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
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 signature = Crypto.doSign(privateKey, serialised.bytes)
return SignedDataWithCert(serialised, DigitalSignatureWithCert(certificate, signature))
return SignedDataWithCert(serialised, signer(serialised))
}
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> {

View File

@ -4,10 +4,7 @@ import net.corda.core.CordaOID
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SignatureScheme
import net.corda.core.crypto.random63BitValue
import net.corda.core.internal.CertRole
import net.corda.core.internal.reader
import net.corda.core.internal.uncheckedCast
import net.corda.core.internal.writer
import net.corda.core.internal.*
import net.corda.core.utilities.days
import net.corda.core.utilities.millis
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.internal.CertRole
import net.corda.core.internal.DigitalSignatureWithCert
import net.corda.core.internal.SignedDataWithCert
import net.corda.core.internal.signWithCert
import net.corda.core.node.NetworkParameters
import net.corda.core.node.NodeInfo
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializedBytes
import net.corda.nodeapi.internal.crypto.X509Utilities
import java.security.cert.X509Certificate
import java.time.Instant
@ -53,3 +56,10 @@ fun <T : Any> SignedDataWithCert<T>.verifiedNetworkMapCert(rootCert: X509Certifi
X509Utilities.validateCertificateChain(rootCert, sig.by, rootCert)
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
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.serialization.serialize
import net.corda.nodeapi.internal.createDevNetworkMapCa
@ -11,16 +13,13 @@ import java.nio.file.StandardCopyOption
class NetworkParametersCopier(
networkParameters: NetworkParameters,
networkMapCa: CertificateAndKeyPair = createDevNetworkMapCa(),
signingCertAndKeyPair: CertificateAndKeyPair = createDevNetworkMapCa(),
overwriteFile: Boolean = false,
@VisibleForTesting
val update: Boolean = false
) {
private val copyOptions = if (overwriteFile) arrayOf(StandardCopyOption.REPLACE_EXISTING) else emptyArray()
private val serialisedSignedNetParams = networkParameters.signWithCert(
networkMapCa.keyPair.private,
networkMapCa.certificate
).serialize()
private val serialisedSignedNetParams = signingCertAndKeyPair.sign(networkParameters).serialize()
fun install(nodeDir: Path) {
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 nodeInfoMap = ConcurrentHashMap<SecureHash, SignedNodeInfo>()
private val networkParamsMap = HashMap<SecureHash, NetworkParameters>()
private val networkMapCa: CertificateAndKeyPair = createDevNetworkMapCa()
private val networkMapCertAndKeyPair: CertificateAndKeyPair = createDevNetworkMapCa()
private val cacheExpiryMs = 100
private val networkMapClient = createMockNetworkMapClient()
private val scheduler = TestScheduler()
@ -254,7 +254,7 @@ class NetworkMapUpdaterTest {
}
on { getNetworkParameters(any()) }.then {
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 {
Unit

View File

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