Search in sources :

Example 6 with StatusCodes

use of org.eclipse.milo.opcua.stack.core.StatusCodes in project milo by eclipse.

the class CertificateValidationUtil method buildTrustedCertPath.

/**
 * Given a possibly partial certificate chain with at least one certificate in it, builds a path to a trust anchor
 * using a collection of trusted and issuer certificates as possible intermediate and root CAs, and then ensures
 * that at least one certificate in the resulting path is in the trusted collection.
 * <p>
 * Each certificate has its signature and subject/issuer chaining checked. Revocation and other more detailed
 * checks are not done at this stage.
 * <p>
 * The {@link CertPath} and {@link TrustAnchor} from the result is meant to be further validated by
 * {@link #validateTrustedCertPath(CertPath, TrustAnchor, Collection, Set, boolean)}, which can return more detailed
 * failure {@link StatusCodes} in its exceptions because it is dealing with a known trusted path.
 *
 * @param certificateChain    a possibly partial certificate chain to build a trusted path from.
 * @param trustedCertificates a collection of known trusted certificates.
 * @param issuerCertificates  a collection of known CAs that can be used in path building but are not considered
 *                            "trusted" when it comes to determining if the resulting path is "trusted".
 * @return a {@link PKIXCertPathBuilderResult} with a {@link TrustAnchor} and {@link CertPath}, which combined
 * make up the full trusted path.
 * @throws UaException if a trusted path cannot be built.
 */
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;
}
Also used : X509Certificate(java.security.cert.X509Certificate) Arrays(java.util.Arrays) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) Extension(org.bouncycastle.asn1.x509.Extension) X509CRL(java.security.cert.X509CRL) LoggerFactory(org.slf4j.LoggerFactory) CertificateNotYetValidException(java.security.cert.CertificateNotYetValidException) CertificateParsingException(java.security.cert.CertificateParsingException) CertificateExpiredException(java.security.cert.CertificateExpiredException) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) GeneralSecurityException(java.security.GeneralSecurityException) CertPathBuilder(java.security.cert.CertPathBuilder) Sets.newHashSet(com.google.common.collect.Sets.newHashSet) CertPathValidatorException(java.security.cert.CertPathValidatorException) PKIXRevocationChecker(java.security.cert.PKIXRevocationChecker) StatusCodes(org.eclipse.milo.opcua.stack.core.StatusCodes) Logger(org.slf4j.Logger) Predicate(java.util.function.Predicate) SignatureException(java.security.SignatureException) X509CertSelector(java.security.cert.X509CertSelector) Collection(java.util.Collection) CertPathValidator(java.security.cert.CertPathValidator) Set(java.util.Set) IOException(java.io.IOException) PublicKey(java.security.PublicKey) CertPath(java.security.cert.CertPath) PKIXParameters(java.security.cert.PKIXParameters) Collectors(java.util.stream.Collectors) CollectionCertStoreParameters(java.security.cert.CollectionCertStoreParameters) Objects(java.util.Objects) PKIXBuilderParameters(java.security.cert.PKIXBuilderParameters) List(java.util.List) GeneralName(org.bouncycastle.asn1.x509.GeneralName) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) CertStore(java.security.cert.CertStore) GeneralNames(org.bouncycastle.asn1.x509.GeneralNames) UaException(org.eclipse.milo.opcua.stack.core.UaException) PKIXCertPathBuilderResult(java.security.cert.PKIXCertPathBuilderResult) InvalidKeyException(java.security.InvalidKeyException) Preconditions(com.google.common.base.Preconditions) BasicReason(java.security.cert.CertPathValidatorException.BasicReason) Collections(java.util.Collections) CertificateEncodingException(java.security.cert.CertificateEncodingException) TrustAnchor(java.security.cert.TrustAnchor) UaException(org.eclipse.milo.opcua.stack.core.UaException) ArrayList(java.util.ArrayList) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) TrustAnchor(java.security.cert.TrustAnchor) X509Certificate(java.security.cert.X509Certificate) PKIXCertPathBuilderResult(java.security.cert.PKIXCertPathBuilderResult) CertPath(java.security.cert.CertPath) HashSet(java.util.HashSet) Sets.newHashSet(com.google.common.collect.Sets.newHashSet)

Aggregations

List (java.util.List)6 StatusCodes (org.eclipse.milo.opcua.stack.core.StatusCodes)6 UaException (org.eclipse.milo.opcua.stack.core.UaException)6 CompletableFuture (java.util.concurrent.CompletableFuture)5 CompletableFuture.completedFuture (java.util.concurrent.CompletableFuture.completedFuture)5 OpcUaClient (org.eclipse.milo.opcua.sdk.client.OpcUaClient)5 StatusCode (org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode)5 ReadValueId (org.eclipse.milo.opcua.stack.core.types.structured.ReadValueId)5 Unit (org.eclipse.milo.opcua.stack.core.util.Unit)5 Collections.singletonList (java.util.Collections.singletonList)4 Optional (java.util.Optional)4 ExecutionException (java.util.concurrent.ExecutionException)4 UaMonitoredItem (org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem)4 ModifyMonitoredItemResult (org.eclipse.milo.opcua.sdk.client.subscriptions.BatchModifyMonitoredItems.ModifyMonitoredItemResult)4 UInteger (org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger)4 TimestampsToReturn (org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn)4 MonitoredItemModifyRequest (org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemModifyRequest)4 MonitoringParameters (org.eclipse.milo.opcua.stack.core.types.structured.MonitoringParameters)4 FutureUtils.failedUaFuture (org.eclipse.milo.opcua.stack.core.util.FutureUtils.failedUaFuture)4 SetMonitoringModeResult (org.eclipse.milo.opcua.sdk.client.subscriptions.BatchSetMonitoringMode.SetMonitoringModeResult)3