mirror of
https://github.com/corda/corda.git
synced 2025-06-13 04:38:19 +00:00
Adding the X509CRL custom serializer. (#2844)
CORDA-1233 * Adding the X509CRL custom serializer. * Addressing review comments
This commit is contained in:
@ -19,6 +19,8 @@ from the previous milestone release.
|
|||||||
|
|
||||||
* java.security.cert.CRLReason added to the default Whitelist.
|
* java.security.cert.CRLReason added to the default Whitelist.
|
||||||
|
|
||||||
|
* java.security.cert.X509CRL serialization support added.
|
||||||
|
|
||||||
.. _changelog_v3:
|
.. _changelog_v3:
|
||||||
|
|
||||||
Version 3.0
|
Version 3.0
|
||||||
|
@ -71,6 +71,7 @@ abstract class AbstractAMQPSerializationScheme(val cordappLoader: List<Cordapp>)
|
|||||||
register(net.corda.nodeapi.internal.serialization.amqp.custom.PeriodSerializer(this))
|
register(net.corda.nodeapi.internal.serialization.amqp.custom.PeriodSerializer(this))
|
||||||
register(net.corda.nodeapi.internal.serialization.amqp.custom.ClassSerializer(this))
|
register(net.corda.nodeapi.internal.serialization.amqp.custom.ClassSerializer(this))
|
||||||
register(net.corda.nodeapi.internal.serialization.amqp.custom.X509CertificateSerializer)
|
register(net.corda.nodeapi.internal.serialization.amqp.custom.X509CertificateSerializer)
|
||||||
|
register(net.corda.nodeapi.internal.serialization.amqp.custom.X509CRLSerializer)
|
||||||
register(net.corda.nodeapi.internal.serialization.amqp.custom.CertPathSerializer(this))
|
register(net.corda.nodeapi.internal.serialization.amqp.custom.CertPathSerializer(this))
|
||||||
register(net.corda.nodeapi.internal.serialization.amqp.custom.StringBufferSerializer)
|
register(net.corda.nodeapi.internal.serialization.amqp.custom.StringBufferSerializer)
|
||||||
register(net.corda.nodeapi.internal.serialization.amqp.custom.SimpleStringSerializer)
|
register(net.corda.nodeapi.internal.serialization.amqp.custom.SimpleStringSerializer)
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package net.corda.nodeapi.internal.serialization.amqp.custom
|
||||||
|
|
||||||
|
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
|
||||||
|
import net.corda.nodeapi.internal.serialization.amqp.*
|
||||||
|
import org.apache.qpid.proton.codec.Data
|
||||||
|
import java.lang.reflect.Type
|
||||||
|
import java.security.cert.X509CRL
|
||||||
|
|
||||||
|
object X509CRLSerializer : CustomSerializer.Implements<X509CRL>(X509CRL::class.java) {
|
||||||
|
override val schemaForDocumentation = Schema(listOf(RestrictedType(
|
||||||
|
type.toString(),
|
||||||
|
"",
|
||||||
|
listOf(type.toString()),
|
||||||
|
SerializerFactory.primitiveTypeName(ByteArray::class.java)!!,
|
||||||
|
descriptor,
|
||||||
|
emptyList()
|
||||||
|
)))
|
||||||
|
|
||||||
|
override fun writeDescribedObject(obj: X509CRL, data: Data, type: Type, output: SerializationOutput) {
|
||||||
|
output.writeObject(obj.encoded, data, clazz)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readObject(obj: Any, schemas: SerializationSchemas, input: DeserializationInput): X509CRL {
|
||||||
|
val bytes = input.readObject(obj, schemas, ByteArray::class.java) as ByteArray
|
||||||
|
return X509CertificateFactory().delegate.generateCRL(bytes.inputStream()) as X509CRL
|
||||||
|
}
|
||||||
|
}
|
@ -8,15 +8,19 @@ import net.corda.client.rpc.RPCException
|
|||||||
import net.corda.core.CordaException
|
import net.corda.core.CordaException
|
||||||
import net.corda.core.CordaRuntimeException
|
import net.corda.core.CordaRuntimeException
|
||||||
import net.corda.core.contracts.*
|
import net.corda.core.contracts.*
|
||||||
|
import net.corda.core.crypto.Crypto
|
||||||
import net.corda.core.crypto.SecureHash
|
import net.corda.core.crypto.SecureHash
|
||||||
import net.corda.core.crypto.secureRandomBytes
|
import net.corda.core.crypto.secureRandomBytes
|
||||||
import net.corda.core.flows.FlowException
|
import net.corda.core.flows.FlowException
|
||||||
import net.corda.core.identity.AbstractParty
|
import net.corda.core.identity.AbstractParty
|
||||||
import net.corda.core.identity.CordaX500Name
|
import net.corda.core.identity.CordaX500Name
|
||||||
import net.corda.core.internal.AbstractAttachment
|
import net.corda.core.internal.AbstractAttachment
|
||||||
|
import net.corda.core.internal.x500Name
|
||||||
import net.corda.core.serialization.*
|
import net.corda.core.serialization.*
|
||||||
import net.corda.core.transactions.LedgerTransaction
|
import net.corda.core.transactions.LedgerTransaction
|
||||||
import net.corda.core.utilities.OpaqueBytes
|
import net.corda.core.utilities.OpaqueBytes
|
||||||
|
import net.corda.nodeapi.internal.DEV_INTERMEDIATE_CA
|
||||||
|
import net.corda.nodeapi.internal.crypto.ContentSignerBuilder
|
||||||
import net.corda.nodeapi.internal.serialization.*
|
import net.corda.nodeapi.internal.serialization.*
|
||||||
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.isPrimitive
|
import net.corda.nodeapi.internal.serialization.amqp.SerializerFactory.Companion.isPrimitive
|
||||||
import net.corda.testing.contracts.DummyContract
|
import net.corda.testing.contracts.DummyContract
|
||||||
@ -29,6 +33,9 @@ import org.apache.qpid.proton.amqp.*
|
|||||||
import org.apache.qpid.proton.codec.DecoderImpl
|
import org.apache.qpid.proton.codec.DecoderImpl
|
||||||
import org.apache.qpid.proton.codec.EncoderImpl
|
import org.apache.qpid.proton.codec.EncoderImpl
|
||||||
import org.assertj.core.api.Assertions.*
|
import org.assertj.core.api.Assertions.*
|
||||||
|
import org.bouncycastle.cert.X509v2CRLBuilder
|
||||||
|
import org.bouncycastle.cert.jcajce.JcaX509CRLConverter
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.*
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
@ -41,6 +48,7 @@ import java.io.IOException
|
|||||||
import java.io.NotSerializableException
|
import java.io.NotSerializableException
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
|
import java.security.cert.X509CRL
|
||||||
import java.time.*
|
import java.time.*
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -51,6 +59,7 @@ import kotlin.test.assertTrue
|
|||||||
|
|
||||||
object AckWrapper {
|
object AckWrapper {
|
||||||
object Ack
|
object Ack
|
||||||
|
|
||||||
fun serialize() {
|
fun serialize() {
|
||||||
val factory = testDefaultFactoryNoEvolution()
|
val factory = testDefaultFactoryNoEvolution()
|
||||||
SerializationOutput(factory).serialize(Ack)
|
SerializationOutput(factory).serialize(Ack)
|
||||||
@ -59,6 +68,7 @@ object AckWrapper {
|
|||||||
|
|
||||||
object PrivateAckWrapper {
|
object PrivateAckWrapper {
|
||||||
private object Ack
|
private object Ack
|
||||||
|
|
||||||
fun serialize() {
|
fun serialize() {
|
||||||
val factory = testDefaultFactoryNoEvolution()
|
val factory = testDefaultFactoryNoEvolution()
|
||||||
SerializationOutput(factory).serialize(Ack)
|
SerializationOutput(factory).serialize(Ack)
|
||||||
@ -630,6 +640,7 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val FOO_PROGRAM_ID = "net.corda.nodeapi.internal.serialization.amqp.SerializationOutputTests.FooContract"
|
private val FOO_PROGRAM_ID = "net.corda.nodeapi.internal.serialization.amqp.SerializationOutputTests.FooContract"
|
||||||
|
|
||||||
class FooState : ContractState {
|
class FooState : ContractState {
|
||||||
override val participants: List<AbstractParty> = emptyList()
|
override val participants: List<AbstractParty> = emptyList()
|
||||||
}
|
}
|
||||||
@ -992,6 +1003,25 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
|
|||||||
assertEquals(objCopy.a, objCopy.b)
|
assertEquals(objCopy.a, objCopy.b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun emptyCrl(): X509CRL {
|
||||||
|
val builder = X509v2CRLBuilder(CordaX500Name.build(DEV_INTERMEDIATE_CA.certificate.issuerX500Principal).x500Name, Date())
|
||||||
|
val provider = BouncyCastleProvider()
|
||||||
|
val crlHolder = builder.build(ContentSignerBuilder.build(Crypto.RSA_SHA256, Crypto.generateKeyPair(Crypto.RSA_SHA256).private, provider))
|
||||||
|
return JcaX509CRLConverter().setProvider(provider).getCRL(crlHolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test X509CRL custom serializer`() {
|
||||||
|
val factory = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||||
|
factory.register(net.corda.nodeapi.internal.serialization.amqp.custom.X509CRLSerializer)
|
||||||
|
|
||||||
|
val factory2 = SerializerFactory(AllWhitelist, ClassLoader.getSystemClassLoader())
|
||||||
|
factory2.register(net.corda.nodeapi.internal.serialization.amqp.custom.X509CRLSerializer)
|
||||||
|
|
||||||
|
val obj = emptyCrl()
|
||||||
|
serdes(obj, factory, factory2)
|
||||||
|
}
|
||||||
|
|
||||||
data class ByteArrays(val a: ByteArray, val b: ByteArray)
|
data class ByteArrays(val a: ByteArray, val b: ByteArray)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -1197,7 +1227,8 @@ class SerializationOutputTests(private val compression: CordaSerializationEncodi
|
|||||||
@Test
|
@Test
|
||||||
fun throwable() {
|
fun throwable() {
|
||||||
class TestException(message: String?, cause: Throwable?) : CordaException(message, cause)
|
class TestException(message: String?, cause: Throwable?) : CordaException(message, cause)
|
||||||
val testExcp = TestException("hello", Throwable().apply { stackTrace = Thread.currentThread().stackTrace } )
|
|
||||||
|
val testExcp = TestException("hello", Throwable().apply { stackTrace = Thread.currentThread().stackTrace })
|
||||||
val factory = testDefaultFactoryNoEvolution()
|
val factory = testDefaultFactoryNoEvolution()
|
||||||
SerializationOutput(factory).serialize(testExcp)
|
SerializationOutput(factory).serialize(testExcp)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user