mirror of
https://github.com/corda/corda.git
synced 2024-12-21 13:57:54 +00:00
CORDA-1932 Fixing network map certificate path verification (#3843)
* CORDA-1932 Fixing network map certificate path verification to be certificate hierarchy agnostic * Addressing review comments
This commit is contained in:
parent
d7b85b4928
commit
8e6a9818b7
@ -7,16 +7,24 @@ import net.corda.core.serialization.CordaSerializable
|
|||||||
import net.corda.core.serialization.SerializedBytes
|
import net.corda.core.serialization.SerializedBytes
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
|
import java.security.cert.CertPath
|
||||||
import java.security.cert.X509Certificate
|
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
|
// 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
|
// and the correct exceptions will be need to be annotated
|
||||||
/** A digital signature with attached certificate of the public key. */
|
/** 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: ByteArray): Boolean = by.publicKey.verify(content, this)
|
||||||
fun verify(content: OpaqueBytes): Boolean = verify(content.bytes)
|
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<X509Certificate>, 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. */
|
/** Similar to [SignedData] but instead of just attaching the public key, the certificate for the key is attached instead. */
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
class SignedDataWithCert<T : Any>(val raw: SerializedBytes<T>, val sig: DigitalSignatureWithCert) {
|
class SignedDataWithCert<T : Any>(val raw: SerializedBytes<T>, val sig: DigitalSignatureWithCert) {
|
||||||
|
@ -3,12 +3,11 @@ package net.corda.nodeapi.internal.network
|
|||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.internal.CertRole
|
import net.corda.core.internal.CertRole
|
||||||
import net.corda.core.internal.DigitalSignatureWithCert
|
import net.corda.core.internal.DigitalSignatureWithCert
|
||||||
|
import net.corda.core.internal.DigitalSignatureWithCertPath
|
||||||
import net.corda.core.internal.SignedDataWithCert
|
import net.corda.core.internal.SignedDataWithCert
|
||||||
import net.corda.core.internal.signWithCert
|
|
||||||
import net.corda.core.node.NetworkParameters
|
import net.corda.core.node.NetworkParameters
|
||||||
import net.corda.core.node.NodeInfo
|
import net.corda.core.node.NodeInfo
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
import net.corda.core.serialization.SerializedBytes
|
|
||||||
import net.corda.nodeapi.internal.crypto.X509Utilities
|
import net.corda.nodeapi.internal.crypto.X509Utilities
|
||||||
import java.security.cert.X509Certificate
|
import java.security.cert.X509Certificate
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@ -57,20 +56,13 @@ data class ParametersUpdate(
|
|||||||
val updateDeadline: Instant
|
val updateDeadline: Instant
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Verify that a Network Map certificate is issued by Root CA and its [CertRole] is correct. */
|
/** Verify that a Network Map certificate path and its [CertRole] is correct. */
|
||||||
// TODO: Current implementation works under the assumption that there are no intermediate CAs between Root and
|
|
||||||
// Network Map. Consider a more flexible implementation without the above assumption.
|
|
||||||
|
|
||||||
fun <T : Any> SignedDataWithCert<T>.verifiedNetworkMapCert(rootCert: X509Certificate): T {
|
fun <T : Any> SignedDataWithCert<T>.verifiedNetworkMapCert(rootCert: X509Certificate): T {
|
||||||
require(CertRole.extract(sig.by) == CertRole.NETWORK_MAP) { "Incorrect cert role: ${CertRole.extract(sig.by)}" }
|
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()
|
return verified()
|
||||||
}
|
}
|
||||||
|
|
||||||
class NetworkMapAndSigned private constructor(val networkMap: NetworkMap, val signed: SignedNetworkMap) {
|
|
||||||
constructor(networkMap: NetworkMap, signer: (SerializedBytes<NetworkMap>) -> DigitalSignatureWithCert) : this(networkMap, networkMap.signWithCert(signer))
|
|
||||||
constructor(signed: SignedNetworkMap) : this(signed.verified(), signed)
|
|
||||||
|
|
||||||
operator fun component1(): NetworkMap = networkMap
|
|
||||||
operator fun component2(): SignedNetworkMap = signed
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user