Skip to content
Permalink
Browse files
8255348: NPE in PKIXCertPathValidator event logging code
Reviewed-by: mullan
  • Loading branch information
coffeys committed Jan 22, 2021
1 parent a97f3c1 commit 18eb6d9e34afa0df168c1794a9a41b23e5a17915
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 24 deletions.
@@ -241,13 +241,13 @@ private static PKIXCertPathValidatorResult validate(TrustAnchor anchor,
X509ValidationEvent xve = new X509ValidationEvent();
if (xve.shouldCommit() || EventHelper.isLoggingSecurity()) {
int[] certIds = params.certificates().stream()
.mapToInt(x -> x.hashCode())
.mapToInt(Certificate::hashCode)
.toArray();
int anchorCertId =
anchor.getTrustedCert().hashCode();
int anchorCertId = (anchorCert != null) ?
anchorCert.hashCode() : anchor.getCAPublicKey().hashCode();
if (xve.shouldCommit()) {
xve.certificateId = anchorCertId;
int certificatePos = 1; //anchor cert
int certificatePos = 1; // most trusted CA
xve.certificatePosition = certificatePos;
xve.validationCounter = validationCounter.incrementAndGet();
xve.commit();
@@ -48,12 +48,11 @@ public static void main(String[] args) throws Exception {
recording.enable(EventNames.X509Certificate);
recording.start();

CertificateFactory cf = CertificateFactory.getInstance("X.509");
TestCertificate.ONE.generate(cf);
TestCertificate.TWO.generate(cf);
TestCertificate.ONE.certificate();
TestCertificate.TWO.certificate();
// Generate twice to make sure only one event per certificate is generated
TestCertificate.ONE.generate(cf);
TestCertificate.TWO.generate(cf);
TestCertificate.ONE.certificate();
TestCertificate.TWO.certificate();

recording.stop();

@@ -47,8 +47,8 @@ public static void main(String[] args) throws Exception {
try (Recording recording = new Recording()) {
recording.enable(EventNames.X509Validation);
recording.start();
// intermeditate certificate test
TestCertificate.generateChain(false);
// intermediate certificate test
TestCertificate.generateChain(false, true);
recording.stop();
List<RecordedEvent> events = Events.fromRecording(recording);
Asserts.assertEquals(events.size(), 3, "Incorrect number of events");
@@ -59,12 +59,23 @@ public static void main(String[] args) throws Exception {
recording.enable(EventNames.X509Validation);
recording.start();
// self signed certificate test
TestCertificate.generateChain(true);
TestCertificate.generateChain(true, true);
recording.stop();
List<RecordedEvent> events = Events.fromRecording(recording);
Asserts.assertEquals(events.size(), 2, "Incorrect number of events");
assertEvent2(events);
}

try (Recording recording = new Recording()) {
recording.enable(EventNames.X509Validation);
recording.start();
// intermediate certificate test, with no Cert for trust anchor
TestCertificate.generateChain(true, false);
recording.stop();
List<RecordedEvent> events = Events.fromRecording(recording);
Asserts.assertEquals(events.size(), 2, "Incorrect number of events");
assertEvent3(events);
}
}

private static void assertEvent1(List<RecordedEvent> events) throws Exception {
@@ -108,4 +119,26 @@ private static void assertEvent2(List<RecordedEvent> events) throws Exception {
}
}
}
/*
* Self signed certificate test
*/
private static void assertEvent3(List<RecordedEvent> events) throws Exception {
for (RecordedEvent e : events) {
int pos = e.getInt("certificatePosition");
switch (pos) {
// use public key of cert provided in TrustAnchor
case 1:
Asserts.assertEquals(e.getLong("certificateId"),
Long.valueOf(TestCertificate.ROOT_CA.certificate().getPublicKey().hashCode()));
break;
case 2:
Events.assertField(e, "certificateId")
.equal(TestCertificate.ROOT_CA.certId);
break;
default:
System.out.println(events);
throw new Exception("Unexpected position:" + pos);
}
}
}
}
@@ -58,9 +58,8 @@ public static void main(String[] args) throws Exception {

public static class GenerateX509Certicate {
public static void main(String[] args) throws Exception {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
TestCertificate.ONE.generate(cf);
TestCertificate.TWO.generate(cf);
TestCertificate.ONE.certificate();
TestCertificate.TWO.certificate();
}
}
}
@@ -43,14 +43,19 @@ public static void main(String[] args) throws Exception {
l.addExpected("FINE: ValidationChain: " +
TestCertificate.ROOT_CA.certId + ", " +
TestCertificate.ROOT_CA.certId);
l.addExpected("FINE: ValidationChain: " +
TestCertificate.ROOT_CA.certificate().getPublicKey().hashCode() +
", " + TestCertificate.ROOT_CA.certId);
l.testExpected();
}

public static class GenerateCertificateChain {
public static void main(String[] args) throws Exception {
TestCertificate.generateChain(false);
TestCertificate.generateChain(false, true);
// self signed test
TestCertificate.generateChain(true);
TestCertificate.generateChain(true, true);
// no cert for trust anchor
TestCertificate.generateChain(true, false);
}
}
}
@@ -122,6 +122,8 @@ public enum TestCertificate {
"J2GyCaJINsyaI/I2\n" +
"-----END CERTIFICATE-----");

private static final CertificateFactory CERTIFICATE_FACTORY = getCertificateFactory();

public String serialNumber;
public String algorithm;
public String subject;
@@ -143,22 +145,35 @@ public enum TestCertificate {
this.keyLength = 2048;
}

public X509Certificate generate(CertificateFactory cf) throws CertificateException {
private static CertificateFactory getCertificateFactory() {
try {
return CertificateFactory.getInstance("X.509");
} catch (CertificateException e) {
throw new RuntimeException(e);
}
}

public X509Certificate certificate() throws CertificateException {
ByteArrayInputStream is = new ByteArrayInputStream(encoded.getBytes());
return (X509Certificate) cf.generateCertificate(is);
return (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(is);
}

public static void generateChain(boolean selfSignedTest) throws Exception {
public static void generateChain(boolean selfSignedTest, boolean trustAnchorCert) throws Exception {
// Do path validation as if it is always Tue, 06 Sep 2016 22:12:21 GMT
// This value is within the lifetimes of all certificates.
Date testDate = new Date(1473199941000L);

CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate c1 = TestCertificate.ONE.generate(cf);
X509Certificate c2 = TestCertificate.TWO.generate(cf);
X509Certificate ca = TestCertificate.ROOT_CA.generate(cf);
X509Certificate c1 = TestCertificate.ONE.certificate();
X509Certificate c2 = TestCertificate.TWO.certificate();
X509Certificate ca = TestCertificate.ROOT_CA.certificate();

TrustAnchor ta = new TrustAnchor(ca, null);
TrustAnchor ta;
if (trustAnchorCert) {
ta = new TrustAnchor(ca, null);
} else {
ta = new TrustAnchor(ca.getIssuerX500Principal(), ca.getPublicKey(), null);
}
CertPathValidator validator = CertPathValidator.getInstance("PKIX");

PKIXParameters params = new PKIXParameters(Collections.singleton(ta));

1 comment on commit 18eb6d9

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 18eb6d9 Jan 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.