Use NetworkMap and SignedNetworkMap in NetworkMapClient, and enable signature verification. (#2054)

* new network map object for network map, and verify signature and root in Signed network map and node info

* fixup after rebase

* * added certificate and key to network map server
* move DigitalSignature.WithCert back to NetworkMap.kt, as its breaking API test, will raise another PR to move it back.
* Make DigitalSignature.WithCert not extend WithKey, as per PR discussion.
* various fixes after rebase.

* move Network map back to core/node, as its breaking API test

* revert unintended changes

* move network map objects to node-api
This commit is contained in:
Patrick Kuo
2017-11-29 15:55:13 +00:00
committed by GitHub
parent cc1fba641e
commit 572c4af40c
20 changed files with 245 additions and 147 deletions

View File

@ -0,0 +1,75 @@
package net.corda.nodeapi.internal
import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.verify
import net.corda.core.identity.Party
import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.SerializedBytes
import net.corda.core.serialization.deserialize
import java.security.SignatureException
import java.security.cert.CertPathValidatorException
import java.security.cert.X509Certificate
import java.time.Duration
import java.time.Instant
// TODO: Need more discussion on rather we should move this class out of internal.
/**
* Data class containing hash of [NetworkParameters] and network participant's [NodeInfo] hashes.
*/
@CordaSerializable
data class NetworkMap(val nodeInfoHashes: List<SecureHash>, val networkParameterHash: SecureHash)
/**
* @property minimumPlatformVersion
* @property notaries
* @property eventHorizon
* @property maxMessageSize Maximum P2P message sent over the wire in bytes.
* @property maxTransactionSize Maximum permitted transaction size in bytes.
* @property modifiedTime
* @property epoch Version number of the network parameters. Starting from 1, this will always increment on each new set
* of parameters.
*/
// TODO Wire up the parameters
@CordaSerializable
data class NetworkParameters(
val minimumPlatformVersion: Int,
val notaries: List<NotaryInfo>,
val eventHorizon: Duration,
val maxMessageSize: Int,
val maxTransactionSize: Int,
val modifiedTime: Instant,
val epoch: Int
) {
init {
require(minimumPlatformVersion > 0) { "minimumPlatformVersion must be at least 1" }
require(notaries.distinctBy { it.identity } == notaries) { "Duplicate notary identities" }
require(epoch > 0) { "epoch must be at least 1" }
}
}
@CordaSerializable
data class NotaryInfo(val identity: Party, val validating: Boolean)
/**
* A serialized [NetworkMap] and its signature and certificate. Enforces signature validity in order to deserialize the data
* contained within.
*/
@CordaSerializable
class SignedNetworkMap(val raw: SerializedBytes<NetworkMap>, val sig: DigitalSignatureWithCert) {
/**
* Return the deserialized NetworkMap if the signature and certificate can be verified.
*
* @throws CertPathValidatorException if the certificate path is invalid.
* @throws SignatureException if the signature is invalid.
*/
@Throws(SignatureException::class)
fun verified(): NetworkMap {
sig.by.publicKey.verify(raw.bytes, sig)
return raw.deserialize()
}
}
// TODO: This class should reside in the [DigitalSignature] class.
/** A digital signature that identifies who the public key is owned by, and the certificate which provides prove of the identity */
class DigitalSignatureWithCert(val by: X509Certificate, val signatureBytes: ByteArray) : DigitalSignature(signatureBytes)

View File

@ -6,6 +6,7 @@ import net.corda.core.utilities.NetworkHostAndPort
import org.apache.activemq.artemis.api.core.SimpleString
import rx.Notification
import rx.exceptions.OnErrorNotImplementedException
import sun.security.x509.X509CertImpl
import java.util.*
/**
@ -58,6 +59,9 @@ object DefaultWhitelist : SerializationWhitelist {
java.util.LinkedHashMap::class.java,
BitSet::class.java,
OnErrorNotImplementedException::class.java,
StackTraceElement::class.java
)
StackTraceElement::class.java,
// Implementation of X509Certificate.
X509CertImpl::class.java
)
}

View File

@ -44,6 +44,7 @@ import org.objenesis.strategy.StdInstantiatorStrategy
import org.slf4j.Logger
import sun.security.ec.ECPublicKeyImpl
import sun.security.provider.certpath.X509CertPath
import sun.security.x509.X509CertImpl
import java.io.BufferedInputStream
import java.io.ByteArrayOutputStream
import java.io.FileInputStream
@ -75,6 +76,7 @@ object DefaultKryoCustomizer {
addDefaultSerializer(InputStream::class.java, InputStreamSerializer)
addDefaultSerializer(SerializeAsToken::class.java, SerializeAsTokenSerializer<SerializeAsToken>())
addDefaultSerializer(Logger::class.java, LoggerSerializer)
addDefaultSerializer(X509Certificate::class.java, X509CertificateSerializer)
// WARNING: reordering the registrations here will cause a change in the serialized form, since classes
// with custom serializers get written as registration ids. This will break backwards-compatibility.
@ -108,7 +110,6 @@ object DefaultKryoCustomizer {
register(FileInputStream::class.java, InputStreamSerializer)
register(CertPath::class.java, CertPathSerializer)
register(X509CertPath::class.java, CertPathSerializer)
register(X509Certificate::class.java, X509CertificateSerializer)
register(BCECPrivateKey::class.java, PrivateKeySerializer)
register(BCECPublicKey::class.java, publicKeySerializer)
register(BCRSAPrivateCrtKey::class.java, PrivateKeySerializer)