diff --git a/core/src/main/kotlin/net/corda/core/internal/DigitalSignatureWithCert.kt b/core/src/main/kotlin/net/corda/core/internal/DigitalSignatureWithCert.kt index 04ca25c6cb..d9414f0c18 100644 --- a/core/src/main/kotlin/net/corda/core/internal/DigitalSignatureWithCert.kt +++ b/core/src/main/kotlin/net/corda/core/internal/DigitalSignatureWithCert.kt @@ -7,16 +7,24 @@ import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.deserialize import net.corda.core.utilities.OpaqueBytes +import java.security.cert.CertPath import java.security.cert.X509Certificate // TODO: Rename this to DigitalSignature.WithCert once we're happy for it to be public API. The methods will need documentation // and the correct exceptions will be need to be annotated /** A digital signature with attached certificate of the public key. */ -class DigitalSignatureWithCert(val by: X509Certificate, bytes: ByteArray) : DigitalSignature(bytes) { +open class DigitalSignatureWithCert(val by: X509Certificate, bytes: ByteArray) : DigitalSignature(bytes) { fun verify(content: ByteArray): Boolean = by.publicKey.verify(content, this) fun verify(content: OpaqueBytes): Boolean = verify(content.bytes) } +/** + * A digital signature with attached certificate path. The first certificate in the path corresponds to the data signer key. + * @param path certificate path associated with this signature + * @param bytes signature bytes + */ +class DigitalSignatureWithCertPath(val path: List, bytes: ByteArray): DigitalSignatureWithCert(path.first(), bytes) + /** Similar to [SignedData] but instead of just attaching the public key, the certificate for the key is attached instead. */ @CordaSerializable class SignedDataWithCert(val raw: SerializedBytes, val sig: DigitalSignatureWithCert) { diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt index 7c3afb499d..b3c9f32edf 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/network/NetworkMap.kt @@ -2,6 +2,7 @@ package net.corda.nodeapi.internal.network import net.corda.core.crypto.SecureHash import net.corda.core.internal.CertRole +import net.corda.core.internal.DigitalSignatureWithCertPath import net.corda.core.internal.SignedDataWithCert import net.corda.core.node.NetworkParameters import net.corda.core.node.NodeInfo @@ -10,7 +11,6 @@ import net.corda.nodeapi.internal.crypto.X509Utilities import java.security.cert.X509Certificate import java.time.Instant - const val NETWORK_PARAMS_FILE_NAME = "network-parameters" const val NETWORK_PARAMS_UPDATE_FILE_NAME = "network-parameters-update" @@ -54,8 +54,13 @@ data class ParametersUpdate( val updateDeadline: Instant ) +/** Verify that a Network Map certificate path and its [CertRole] is correct. */ fun SignedDataWithCert.verifiedNetworkMapCert(rootCert: X509Certificate): T { require(CertRole.extract(sig.by) == CertRole.NETWORK_MAP) { "Incorrect cert role: ${CertRole.extract(sig.by)}" } - X509Utilities.validateCertificateChain(rootCert, sig.by, rootCert) + val path = when (this.sig) { + is DigitalSignatureWithCertPath -> (sig as DigitalSignatureWithCertPath).path + else -> listOf(sig.by, rootCert) + } + X509Utilities.validateCertificateChain(rootCert, path) return verified() }