Skip loading known-bad certs (#1806)

This commit is contained in:
Jen Basch
2026-07-30 22:54:08 +00:00
committed by GitHub
parent 043f0e129b
commit 5333d55269
2 changed files with 33 additions and 10 deletions
@@ -219,7 +219,7 @@ abstract class CliCommand(protected val cliOptions: CliBaseOptions) {
var certsAdded = false var certsAdded = false
if (Files.isDirectory(caCertsDir)) { if (Files.isDirectory(caCertsDir)) {
Files.list(caCertsDir) Files.list(caCertsDir)
.filter { it.isRegularFile() } .filter { it.isRegularFile() && !it.fileName.toString().startsWith(".") }
.forEach { cert -> .forEach { cert ->
certsAdded = true certsAdded = true
addCertificates(cert) addCertificates(cert)
@@ -19,6 +19,7 @@ import com.google.errorprone.annotations.ThreadSafe;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.PushbackInputStream;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
@@ -37,11 +38,10 @@ import java.security.SecureRandom;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Objects;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException; import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLHandshakeException;
@@ -177,17 +177,40 @@ final class JdkHttpClient implements HttpClient {
CertificateFactory factory, CertificateFactory factory,
InputStream stream, InputStream stream,
Object source) { Object source) {
Collection<X509Certificate> certificates; var input = new PushbackInputStream(stream);
try { try {
//noinspection unchecked var peekByte = input.read();
certificates = (Collection<X509Certificate>) factory.generateCertificates(stream); if (peekByte == -1) {
} catch (CertificateException e) { throw new HttpClientException(ErrorMessages.create("emptyCertFile", source));
} else {
input.unread(peekByte);
}
} catch (IOException e) {
throw new HttpClientException( throw new HttpClientException(
ErrorMessages.create("cannotParseCertFile", source, Exceptions.getRootReason(e))); ErrorMessages.create("cannotParseCertFile", source, Exceptions.getRootReason(e)));
} }
if (certificates.isEmpty()) {
throw new HttpClientException(ErrorMessages.create("emptyCertFile", source)); var first = true;
while (true) {
try {
anchors.add(factory.generateCertificate(input));
} catch (CertificateException e) {
if (e.getCause() instanceof IOException ioExc) {
if (Objects.equals(ioExc.getMessage(), "Empty input")) {
if (first) {
throw new HttpClientException(
ErrorMessages.create("cannotParseCertFile", source, "No certificate data found"));
}
break;
}
if (Objects.equals(ioExc.getMessage(), "Duplicate extensions not allowed")) continue;
}
throw new HttpClientException(
ErrorMessages.create("cannotParseCertFile", source, Exceptions.getRootReason(e)));
} finally {
first = false;
}
} }
anchors.addAll(certificates);
} }
} }