4646import java .io .InputStream ;
4747import java .lang .reflect .Method ;
4848import java .security .CodeSigner ;
49+ import java .security .InvalidAlgorithmParameterException ;
4950import java .security .KeyStore ;
51+ import java .security .KeyStoreException ;
52+ import java .security .NoSuchAlgorithmException ;
5053import java .security .Timestamp ;
5154import java .security .cert .CertPath ;
55+ import java .security .cert .CertPathValidator ;
56+ import java .security .cert .CertPathValidatorException ;
5257import java .security .cert .Certificate ;
58+ import java .security .cert .PKIXParameters ;
59+ import java .security .cert .TrustAnchor ;
5360import java .security .cert .X509Certificate ;
5461import java .time .ZoneId ;
5562import java .time .ZonedDateTime ;
5865import java .util .Date ;
5966import java .util .Enumeration ;
6067import java .util .HashMap ;
68+ import java .util .HashSet ;
6169import java .util .List ;
6270import java .util .Map ;
6371import java .util .Optional ;
72+ import java .util .Set ;
6473import java .util .jar .JarEntry ;
6574import java .util .regex .Pattern ;
6675import java .util .zip .ZipException ;
@@ -399,7 +408,7 @@ VerifyResult verifyJarEntryCerts(final String jarPath, final boolean jarHasManif
399408 }
400409 if (now .isAfter (tsaNotAfter ) && now .isAfter (notAfter )) {
401410 certInfo .setHasExpiredCert ();
402- } else if (expiresSoon .isAfter (tsaNotAfter )) {
411+ } else if (expiresSoon .isAfter (tsaNotAfter )) {
403412 certInfo .setHasExpiringCert ();
404413 }
405414
@@ -455,6 +464,14 @@ private boolean isTrustedTsa(CertPath certPath) {
455464 }
456465 }
457466 }
467+ for (final KeyStore caKeyStore : caKeyStores ) {
468+ try {
469+ validateCertpathWhenRootCANotInChain (certPath , caKeyStore );
470+ return true ;
471+ } catch (Exception ignore ) {
472+ }
473+ }
474+ LOG .warn ("Unable to validate root ca cert in TSA certpath." );
458475 return false ;
459476 }
460477
@@ -500,6 +517,15 @@ private void checkTrustedCerts(final CertPath certPath) {
500517 }
501518 }
502519 }
520+
521+ for (final KeyStore caKeyStore : caKeyStores ) {
522+ try {
523+ validateCertpathWhenRootCANotInChain (certPath , caKeyStore );
524+ info .setRootInCacerts ();
525+ return ;
526+ } catch (Exception ignore ) {
527+ }
528+ }
503529 } catch (Exception e ) {
504530 // TODO: Warn user about not being able to
505531 // look through their cacerts/trusted.certs
@@ -509,9 +535,30 @@ private void checkTrustedCerts(final CertPath certPath) {
509535 }
510536
511537 // Otherwise a parent cert was not found to be trusted.
538+ LOG .warn ("Unable to validate root ca cert." );
512539 info .setUntrusted ();
513540 }
514541
542+ private static void validateCertpathWhenRootCANotInChain (CertPath certPath , KeyStore caKeyStore ) throws KeyStoreException , InvalidAlgorithmParameterException , NoSuchAlgorithmException , CertPathValidatorException {
543+ final Set <TrustAnchor > anchors = new HashSet <>();
544+
545+ for (Enumeration <String > e = caKeyStore .aliases (); e .hasMoreElements (); ) {
546+ final String alias = e .nextElement ();
547+ final Certificate c = caKeyStore .getCertificate (alias );
548+ if (c instanceof X509Certificate ) {
549+ X509Certificate xc = (X509Certificate ) c ;
550+ anchors .add (new TrustAnchor (xc , null ));
551+ }
552+ }
553+
554+ final PKIXParameters params = new PKIXParameters (anchors );
555+ params .setRevocationEnabled (false ); // disable CRL/OCSP for this presence/anchoring check
556+
557+
558+ final CertPathValidator validator = CertPathValidator .getInstance ("PKIX" );
559+ validator .validate (certPath , params );
560+ }
561+
515562 public void setCurrentlyUsedCertPath (final CertPath certPath ) {
516563 currentlyUsed = certPath ;
517564 }
@@ -561,11 +608,11 @@ static boolean isMetaInfFile(final String name) {
561608 }
562609 return name .startsWith (META_INF ) && (
563610 name .endsWith (".MF" ) ||
564- name .endsWith (".SF" ) ||
565- name .endsWith (".DSA" ) ||
566- name .endsWith (".RSA" ) ||
567- name .endsWith (".EC" ) ||
568- SIG .matcher (name ).matches ()
611+ name .endsWith (".SF" ) ||
612+ name .endsWith (".DSA" ) ||
613+ name .endsWith (".RSA" ) ||
614+ name .endsWith (".EC" ) ||
615+ SIG .matcher (name ).matches ()
569616 );
570617 }
571618
0 commit comments