diff --git a/core/src/main/kotlin/net/corda/core/identity/PartyAndCertificate.kt b/core/src/main/kotlin/net/corda/core/identity/PartyAndCertificate.kt index 7f01393eaf..60d11c613f 100644 --- a/core/src/main/kotlin/net/corda/core/identity/PartyAndCertificate.kt +++ b/core/src/main/kotlin/net/corda/core/identity/PartyAndCertificate.kt @@ -2,6 +2,7 @@ package net.corda.core.identity import net.corda.core.internal.CertRole import net.corda.core.internal.uncheckedCast +import net.corda.core.internal.validate import net.corda.core.serialization.CordaSerializable import java.security.PublicKey import java.security.cert.* @@ -40,9 +41,7 @@ class PartyAndCertificate(val certPath: CertPath) { /** Verify the certificate path is valid. */ fun verify(trustAnchor: TrustAnchor): PKIXCertPathValidatorResult { - val parameters = PKIXParameters(setOf(trustAnchor)).apply { isRevocationEnabled = false } - val validator = CertPathValidator.getInstance("PKIX") - val result = validator.validate(certPath, parameters) as PKIXCertPathValidatorResult + val result = certPath.validate(trustAnchor) // Apply Corda-specific validity rules to the chain. This only applies to chains with any roles present, so // an all-null chain is in theory valid. var parentRole: CertRole? = CertRole.extract(result.trustAnchor.trustedCert) diff --git a/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt b/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt index 3632d5a9c0..2f3899293f 100644 --- a/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt +++ b/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt @@ -44,7 +44,7 @@ import java.nio.file.attribute.FileTime import java.security.KeyPair import java.security.PrivateKey import java.security.PublicKey -import java.security.cert.X509Certificate +import java.security.cert.* import java.time.Duration import java.time.temporal.Temporal import java.util.* @@ -386,6 +386,22 @@ fun ExecutorService.join() { } } +fun CertPath.validate(trustAnchor: TrustAnchor): PKIXCertPathValidatorResult { + val parameters = PKIXParameters(setOf(trustAnchor)).apply { isRevocationEnabled = false } + try { + return CertPathValidator.getInstance("PKIX").validate(this, parameters) as PKIXCertPathValidatorResult + } catch (e: CertPathValidatorException) { + throw CertPathValidatorException( + """Cert path failed to validate against trust anchor. +Reason: ${e.reason} +Offending cert index: ${e.index} +Cert path: $this + +Trust anchor: +$trustAnchor""", e, this, e.index) + } +} + /** * Return the underlying X.500 name from this Corda-safe X.500 name. These are guaranteed to have a consistent * ordering, such that their `toString()` function returns the same value every time for the same [CordaX500Name]. diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/crypto/X509Utilities.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/crypto/X509Utilities.kt index 245263768f..85e00d7807 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/crypto/X509Utilities.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/crypto/X509Utilities.kt @@ -104,20 +104,7 @@ object X509Utilities { } fun validateCertPath(trustedRoot: X509Certificate, certPath: CertPath) { - val params = PKIXParameters(setOf(TrustAnchor(trustedRoot, null))) - params.isRevocationEnabled = false - try { - CertPathValidator.getInstance("PKIX").validate(certPath, params) - } catch (e: CertPathValidatorException) { - throw CertPathValidatorException( - """Cert path failed to validate against root certificate. -Reason: ${e.reason} -Offending cert index: ${e.index} -Cert path: $certPath - -Root certificate: -$trustedRoot""", e, certPath, e.index) - } + certPath.validate(TrustAnchor(trustedRoot, null)) } /**