CertificateValidationUtil { public static PKIXCertPathBuilderResult buildTrustedCertPath( List<X509Certificate> certificateChain, Collection<X509Certificate> trustedCertificates, Collection<X509Certificate> issuerCertificates ) throws UaException { Preconditions.checkArgument(!certificateChain.isEmpty(), "certificateChain must not be empty"); if (LOGGER.isTraceEnabled()) { LOGGER.trace("certificateChain: {}", certificateChain); LOGGER.trace("trustedCertificates: {}", trustedCertificates); LOGGER.trace("issuerCertificates: {}", issuerCertificates); } Set<TrustAnchor> trustAnchors = new HashSet<>(); for (X509Certificate c : trustedCertificates) { if (certificateIsCa(c) && certificateIsSelfSigned(c)) { trustAnchors.add(new TrustAnchor(c, null)); } } for (X509Certificate c : issuerCertificates) { if (certificateIsCa(c) && certificateIsSelfSigned(c)) { trustAnchors.add(new TrustAnchor(c, null)); } } PKIXCertPathBuilderResult certPathResult = buildCertPath( certificateChain, trustedCertificates, issuerCertificates, trustAnchors ); CertPath certPath = certPathResult.getCertPath(); TrustAnchor trustAnchor = certPathResult.getTrustAnchor(); List<X509Certificate> certificates = new ArrayList<>(); certPath.getCertificates().stream() .map(X509Certificate.class::cast) .forEach(certificates::add); certificates.add(trustAnchor.getTrustedCert()); if (LOGGER.isTraceEnabled()) { List<String> path = certificates.stream() .map(c -> c.getSubjectX500Principal().getName()) .collect(Collectors.toList()); LOGGER.trace("certificate path: {}", path); } if (certificates.stream().noneMatch(trustedCertificates::contains)) { throw new UaException( StatusCodes.Bad_CertificateUntrusted, "certificate chain did not contain a trusted certificate" ); } return certPathResult; }  static PKIXCertPathBuilderResult buildTrustedCertPath(
        List<X509Certificate> certificateChain,
        Collection<X509Certificate> trustedCertificates,
        Collection<X509Certificate> issuerCertificates
    ); static void validateTrustedCertPath(
        CertPath certPath,
        TrustAnchor trustAnchor,
        Collection<X509CRL> crls,
        Set<ValidationCheck> validationChecks,
        boolean endEntityIsClient
    ); static void checkValidity(X509Certificate certificate, boolean endEntity); static void checkHostnameOrIpAddress(
        X509Certificate certificate,
        String... hostNames
    ); static void checkEndEntityKeyUsage(X509Certificate certificate); static void checkEndEntityExtendedKeyUsage(
        X509Certificate certificate,
        boolean endEntityIsClient
    ); static void checkIssuerKeyUsage(X509Certificate certificate); static void checkApplicationUri(X509Certificate certificate, String applicationUri); static String getSubjectAltNameUri(X509Certificate certificate);  }
@Test public void testBuildTrustedCertPath_LeafSelfSigned() throws Exception { List<X509Certificate> certificateChain = newArrayList(leafSelfSigned); buildTrustedCertPath( certificateChain, newHashSet(leafSelfSigned), emptySet() ); }
@Test public void testBuildTrustedCertPath_LeafSelfSigned_NotTrusted() { List<X509Certificate> certificateChain = newArrayList(leafSelfSigned); expectThrows( UaException.class, () -> buildTrustedCertPath( certificateChain, emptySet(), emptySet() ) ); }
@Test public void testBuildTrustedCertPath_LeafIntermediateSigned() throws Exception { { List<X509Certificate> certificateChain = newArrayList(leafIntermediateSigned); buildTrustedCertPath( certificateChain, newHashSet(caIntermediate), newHashSet(caRoot) ); } { List<X509Certificate> certificateChain = newArrayList(leafIntermediateSigned, caIntermediate); buildTrustedCertPath( certificateChain, newHashSet(caIntermediate), newHashSet(caRoot) ); } { List<X509Certificate> certificateChain = newArrayList(leafIntermediateSigned, caIntermediate); buildTrustedCertPath( certificateChain, newHashSet(caRoot), emptySet() ); } { List<X509Certificate> certificateChain = newArrayList(leafIntermediateSigned, caIntermediate, caRoot); buildTrustedCertPath( certificateChain, newHashSet(caIntermediate), newHashSet(caRoot) ); } { List<X509Certificate> certificateChain = newArrayList(leafIntermediateSigned, caIntermediate, caRoot); buildTrustedCertPath( certificateChain, newHashSet(caRoot), emptySet() ); } { List<X509Certificate> certificateChain = newArrayList(leafIntermediateSigned, caIntermediate, caRoot); buildTrustedCertPath( certificateChain, newHashSet(caIntermediate, caRoot), emptySet() ); } }
@Test public void testBuildTrustedCertPath_NoTrusted_NoIssuers() { expectThrows(UaException.class, () -> buildTrustedCertPath( newArrayList(leafSelfSigned), emptySet(), emptySet() ) ); expectThrows(UaException.class, () -> buildTrustedCertPath( newArrayList(leafIntermediateSigned), emptySet(), emptySet() ) ); expectThrows(UaException.class, () -> buildTrustedCertPath( newArrayList(leafIntermediateSigned, caIntermediate), emptySet(), emptySet() ) ); expectThrows(UaException.class, () -> buildTrustedCertPath( newArrayList(leafIntermediateSigned, caIntermediate, caRoot), emptySet(), emptySet() ) ); }
@Test public void testBuildTrustedCertPath_IntermediateIssuer() throws Exception { { List<X509Certificate> certificateChain = newArrayList(leafIntermediateSigned); buildTrustedCertPath( certificateChain, newHashSet(caRoot), newHashSet(caIntermediate) ); } { List<X509Certificate> certificateChain = newArrayList(leafIntermediateSigned, caIntermediate); buildTrustedCertPath( certificateChain, newHashSet(caRoot), newHashSet(caIntermediate) ); } { List<X509Certificate> certificateChain = newArrayList(leafIntermediateSigned, caIntermediate, caRoot); buildTrustedCertPath( certificateChain, newHashSet(caRoot), newHashSet(caIntermediate) ); } }