Added sign helper method to CertificateAndKeyPair for producing SignedDataWithCert objects (#2841)

This commit is contained in:
Shams Asari 2018-03-19 12:47:23 +00:00 committed by GitHub
parent dc595792e7
commit 327d7d8acf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 23 deletions

View File

@ -378,10 +378,16 @@ val CordaX500Name.x500Name: X500Name
val CordaX500Name.Companion.unspecifiedCountry val CordaX500Name.Companion.unspecifiedCountry
get() = "ZZ" get() = "ZZ"
fun <T : Any> T.signWithCert(privateKey: PrivateKey, certificate: X509Certificate): SignedDataWithCert<T> { inline fun <T : Any> T.signWithCert(signer: (SerializedBytes<T>) -> DigitalSignatureWithCert): SignedDataWithCert<T> {
val serialised = serialize() val serialised = serialize()
val signature = Crypto.doSign(privateKey, serialised.bytes) return SignedDataWithCert(serialised, signer(serialised))
return SignedDataWithCert(serialised, DigitalSignatureWithCert(certificate, signature)) }
fun <T : Any> T.signWithCert(privateKey: PrivateKey, certificate: X509Certificate): SignedDataWithCert<T> {
return signWithCert {
val signature = Crypto.doSign(privateKey, it.bytes)
DigitalSignatureWithCert(certificate, signature)
}
} }
inline fun <T : Any> SerializedBytes<T>.sign(signer: (SerializedBytes<T>) -> DigitalSignature.WithKey): SignedData<T> { inline fun <T : Any> SerializedBytes<T>.sign(signer: (SerializedBytes<T>) -> DigitalSignature.WithKey): SignedData<T> {

View File

@ -4,10 +4,7 @@ import net.corda.core.CordaOID
import net.corda.core.crypto.Crypto import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SignatureScheme import net.corda.core.crypto.SignatureScheme
import net.corda.core.crypto.random63BitValue import net.corda.core.crypto.random63BitValue
import net.corda.core.internal.CertRole import net.corda.core.internal.*
import net.corda.core.internal.reader
import net.corda.core.internal.uncheckedCast
import net.corda.core.internal.writer
import net.corda.core.utilities.days import net.corda.core.utilities.days
import net.corda.core.utilities.millis import net.corda.core.utilities.millis
import org.bouncycastle.asn1.* import org.bouncycastle.asn1.*
@ -415,4 +412,6 @@ enum class CertificateType(val keyUsage: KeyUsage, vararg val purposes: KeyPurpo
) )
} }
data class CertificateAndKeyPair(val certificate: X509Certificate, val keyPair: KeyPair) data class CertificateAndKeyPair(val certificate: X509Certificate, val keyPair: KeyPair) {
fun <T : Any> sign(obj: T): SignedDataWithCert<T> = obj.signWithCert(keyPair.private, certificate)
}

View File

@ -2,10 +2,13 @@ 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.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
@ -53,3 +56,10 @@ fun <T : Any> SignedDataWithCert<T>.verifiedNetworkMapCert(rootCert: X509Certifi
X509Utilities.validateCertificateChain(rootCert, sig.by, rootCert) X509Utilities.validateCertificateChain(rootCert, sig.by, rootCert)
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
}

View File

@ -1,6 +1,8 @@
package net.corda.nodeapi.internal.network package net.corda.nodeapi.internal.network
import net.corda.core.internal.* import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.copyTo
import net.corda.core.internal.div
import net.corda.core.node.NetworkParameters import net.corda.core.node.NetworkParameters
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.nodeapi.internal.createDevNetworkMapCa import net.corda.nodeapi.internal.createDevNetworkMapCa
@ -11,16 +13,13 @@ import java.nio.file.StandardCopyOption
class NetworkParametersCopier( class NetworkParametersCopier(
networkParameters: NetworkParameters, networkParameters: NetworkParameters,
networkMapCa: CertificateAndKeyPair = createDevNetworkMapCa(), signingCertAndKeyPair: CertificateAndKeyPair = createDevNetworkMapCa(),
overwriteFile: Boolean = false, overwriteFile: Boolean = false,
@VisibleForTesting @VisibleForTesting
val update: Boolean = false val update: Boolean = false
) { ) {
private val copyOptions = if (overwriteFile) arrayOf(StandardCopyOption.REPLACE_EXISTING) else emptyArray() private val copyOptions = if (overwriteFile) arrayOf(StandardCopyOption.REPLACE_EXISTING) else emptyArray()
private val serialisedSignedNetParams = networkParameters.signWithCert( private val serialisedSignedNetParams = signingCertAndKeyPair.sign(networkParameters).serialize()
networkMapCa.keyPair.private,
networkMapCa.certificate
).serialize()
fun install(nodeDir: Path) { fun install(nodeDir: Path) {
val fileName = if (update) NETWORK_PARAMS_UPDATE_FILE_NAME else NETWORK_PARAMS_FILE_NAME val fileName = if (update) NETWORK_PARAMS_UPDATE_FILE_NAME else NETWORK_PARAMS_FILE_NAME

View File

@ -49,7 +49,7 @@ class NetworkMapUpdaterTest {
private val networkMapCache = createMockNetworkMapCache() private val networkMapCache = createMockNetworkMapCache()
private val nodeInfoMap = ConcurrentHashMap<SecureHash, SignedNodeInfo>() private val nodeInfoMap = ConcurrentHashMap<SecureHash, SignedNodeInfo>()
private val networkParamsMap = HashMap<SecureHash, NetworkParameters>() private val networkParamsMap = HashMap<SecureHash, NetworkParameters>()
private val networkMapCa: CertificateAndKeyPair = createDevNetworkMapCa() private val networkMapCertAndKeyPair: CertificateAndKeyPair = createDevNetworkMapCa()
private val cacheExpiryMs = 100 private val cacheExpiryMs = 100
private val networkMapClient = createMockNetworkMapClient() private val networkMapClient = createMockNetworkMapClient()
private val scheduler = TestScheduler() private val scheduler = TestScheduler()
@ -254,7 +254,7 @@ class NetworkMapUpdaterTest {
} }
on { getNetworkParameters(any()) }.then { on { getNetworkParameters(any()) }.then {
val paramsHash: SecureHash = uncheckedCast(it.arguments[0]) val paramsHash: SecureHash = uncheckedCast(it.arguments[0])
networkParamsMap[paramsHash]?.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate) networkParamsMap[paramsHash]?.let { networkMapCertAndKeyPair.sign(it) }
} }
on { ackNetworkParametersUpdate(any()) }.then { on { ackNetworkParametersUpdate(any()) }.then {
Unit Unit

View File

@ -35,7 +35,7 @@ import javax.ws.rs.core.Response.status
class NetworkMapServer(private val cacheTimeout: Duration, class NetworkMapServer(private val cacheTimeout: Duration,
hostAndPort: NetworkHostAndPort, hostAndPort: NetworkHostAndPort,
private val networkMapCa: CertificateAndKeyPair = createDevNetworkMapCa(), private val networkMapCertAndKeyPair: CertificateAndKeyPair = createDevNetworkMapCa(),
private val myHostNameValue: String = "test.host.name", private val myHostNameValue: String = "test.host.name",
vararg additionalServices: Any) : Closeable { vararg additionalServices: Any) : Closeable {
companion object { companion object {
@ -108,9 +108,7 @@ class NetworkMapServer(private val cacheTimeout: Duration,
inner class InMemoryNetworkMapService { inner class InMemoryNetworkMapService {
private val nodeInfoMap = mutableMapOf<SecureHash, SignedNodeInfo>() private val nodeInfoMap = mutableMapOf<SecureHash, SignedNodeInfo>()
val latestAcceptedParametersMap = mutableMapOf<PublicKey, SecureHash>() val latestAcceptedParametersMap = mutableMapOf<PublicKey, SecureHash>()
private val signedNetParams by lazy { private val signedNetParams by lazy { networkMapCertAndKeyPair.sign(networkParameters) }
networkParameters.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate)
}
@POST @POST
@Path("publish") @Path("publish")
@ -143,7 +141,7 @@ class NetworkMapServer(private val cacheTimeout: Duration,
@Produces(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.APPLICATION_OCTET_STREAM)
fun getNetworkMap(): Response { fun getNetworkMap(): Response {
val networkMap = NetworkMap(nodeInfoMap.keys.toList(), signedNetParams.raw.hash, parametersUpdate) val networkMap = NetworkMap(nodeInfoMap.keys.toList(), signedNetParams.raw.hash, parametersUpdate)
val signedNetworkMap = networkMap.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate) val signedNetworkMap = networkMapCertAndKeyPair.sign(networkMap)
return Response.ok(signedNetworkMap.serialize().bytes).header("Cache-Control", "max-age=${cacheTimeout.seconds}").build() return Response.ok(signedNetworkMap.serialize().bytes).header("Cache-Control", "max-age=${cacheTimeout.seconds}").build()
} }
@ -172,8 +170,10 @@ class NetworkMapServer(private val cacheTimeout: Duration,
val requestedParameters = if (requestedHash == signedNetParams.raw.hash) { val requestedParameters = if (requestedHash == signedNetParams.raw.hash) {
signedNetParams signedNetParams
} else if (requestedHash == nextNetworkParameters?.serialize()?.hash) { } else if (requestedHash == nextNetworkParameters?.serialize()?.hash) {
nextNetworkParameters?.signWithCert(networkMapCa.keyPair.private, networkMapCa.certificate) nextNetworkParameters?.let { networkMapCertAndKeyPair.sign(it) }
} else null } else {
null
}
requireNotNull(requestedParameters) requireNotNull(requestedParameters)
return Response.ok(requestedParameters!!.serialize().bytes).build() return Response.ok(requestedParameters!!.serialize().bytes).build()
} }