mirror of
https://github.com/corda/corda.git
synced 2024-12-19 04:57:58 +00:00
CORDA-540: Introduce mandatory reason for "kryoSpecific" (#1386)
* CORDA-540: Introduce mandatory reason for "kryoSpecific"
... before we forget why they are ignored in such a way
* CORDA-540: Write a test that exposes list serialization problem in AMQP mode
* Revert "Remove CompositeSignaturesWithKeys"
This reverts commit 9b3cad3
This commit is contained in:
parent
6bc44b96f1
commit
954ed69102
@ -1,5 +1,6 @@
|
|||||||
package net.corda.core.crypto
|
package net.corda.core.crypto
|
||||||
|
|
||||||
|
import net.corda.core.crypto.composite.CompositeSignaturesWithKeys
|
||||||
import net.corda.core.serialization.deserialize
|
import net.corda.core.serialization.deserialize
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.security.*
|
import java.security.*
|
||||||
@ -75,10 +76,10 @@ class CompositeSignature : Signature(SIGNATURE_ALGORITHM) {
|
|||||||
|
|
||||||
data class State(val buffer: ByteArrayOutputStream, val verifyKey: CompositeKey) {
|
data class State(val buffer: ByteArrayOutputStream, val verifyKey: CompositeKey) {
|
||||||
fun engineVerify(sigBytes: ByteArray): Boolean {
|
fun engineVerify(sigBytes: ByteArray): Boolean {
|
||||||
val sigs = sigBytes.deserialize<List<TransactionSignature>>()
|
val sig = sigBytes.deserialize<CompositeSignaturesWithKeys>()
|
||||||
return if (verifyKey.isFulfilledBy(sigs.map { it.by })) {
|
return if (verifyKey.isFulfilledBy(sig.sigs.map { it.by })) {
|
||||||
val clearData = SecureHash.SHA256(buffer.toByteArray())
|
val clearData = SecureHash.SHA256(buffer.toByteArray())
|
||||||
sigs.all { it.isValid(clearData) }
|
sig.sigs.all { it.isValid(clearData) }
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package net.corda.core.crypto.composite
|
||||||
|
|
||||||
|
import net.corda.core.crypto.TransactionSignature
|
||||||
|
import net.corda.core.serialization.CordaSerializable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom class for holding signature data. This exists for later extension work to provide a standardised cross-platform
|
||||||
|
* serialization format.
|
||||||
|
*/
|
||||||
|
@CordaSerializable
|
||||||
|
data class CompositeSignaturesWithKeys(val sigs: List<TransactionSignature>) {
|
||||||
|
companion object {
|
||||||
|
val EMPTY = CompositeSignaturesWithKeys(emptyList())
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package net.corda.core.crypto
|
package net.corda.core.crypto
|
||||||
|
|
||||||
import net.corda.core.crypto.CompositeKey.NodeAndWeight
|
import net.corda.core.crypto.CompositeKey.NodeAndWeight
|
||||||
|
import net.corda.core.crypto.composite.CompositeSignaturesWithKeys
|
||||||
import net.corda.core.internal.declaredField
|
import net.corda.core.internal.declaredField
|
||||||
import net.corda.core.internal.div
|
import net.corda.core.internal.div
|
||||||
import net.corda.core.serialization.serialize
|
import net.corda.core.serialization.serialize
|
||||||
@ -160,17 +161,17 @@ class CompositeKeyTests : TestDependencyInjectionBase() {
|
|||||||
engine.initVerify(twoOfThree)
|
engine.initVerify(twoOfThree)
|
||||||
engine.update(secureHash.bytes)
|
engine.update(secureHash.bytes)
|
||||||
|
|
||||||
assertFalse { engine.verify(listOf(aliceSignature).serialize().bytes) }
|
assertFalse { engine.verify(CompositeSignaturesWithKeys(listOf(aliceSignature)).serialize().bytes) }
|
||||||
assertFalse { engine.verify(listOf(bobSignature).serialize().bytes) }
|
assertFalse { engine.verify(CompositeSignaturesWithKeys(listOf(bobSignature)).serialize().bytes) }
|
||||||
assertFalse { engine.verify(listOf(charlieSignature).serialize().bytes) }
|
assertFalse { engine.verify(CompositeSignaturesWithKeys(listOf(charlieSignature)).serialize().bytes) }
|
||||||
assertTrue { engine.verify(listOf(aliceSignature, bobSignature).serialize().bytes) }
|
assertTrue { engine.verify(CompositeSignaturesWithKeys(listOf(aliceSignature, bobSignature)).serialize().bytes) }
|
||||||
assertTrue { engine.verify(listOf(aliceSignature, charlieSignature).serialize().bytes) }
|
assertTrue { engine.verify(CompositeSignaturesWithKeys(listOf(aliceSignature, charlieSignature)).serialize().bytes) }
|
||||||
assertTrue { engine.verify(listOf(bobSignature, charlieSignature).serialize().bytes) }
|
assertTrue { engine.verify(CompositeSignaturesWithKeys(listOf(bobSignature, charlieSignature)).serialize().bytes) }
|
||||||
assertTrue { engine.verify(listOf(aliceSignature, bobSignature, charlieSignature).serialize().bytes) }
|
assertTrue { engine.verify(CompositeSignaturesWithKeys(listOf(aliceSignature, bobSignature, charlieSignature)).serialize().bytes) }
|
||||||
|
|
||||||
// Check the underlying signature is validated
|
// Check the underlying signature is validated
|
||||||
val brokenBobSignature = TransactionSignature(aliceSignature.bytes, bobSignature.by, SignatureMetadata(1, Crypto.findSignatureScheme(bobSignature.by).schemeNumberID))
|
val brokenBobSignature = TransactionSignature(aliceSignature.bytes, bobSignature.by, SignatureMetadata(1, Crypto.findSignatureScheme(bobSignature.by).schemeNumberID))
|
||||||
assertFalse { engine.verify(listOf(aliceSignature, brokenBobSignature).serialize().bytes) }
|
assertFalse { engine.verify(CompositeSignaturesWithKeys(listOf(aliceSignature, brokenBobSignature)).serialize().bytes) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
@ -216,7 +217,7 @@ class CompositeKeyTests : TestDependencyInjectionBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
fun `composite key validation with graph cycle detection`() = kryoSpecific<CompositeKeyTests> {
|
fun `composite key validation with graph cycle detection`() = kryoSpecific<CompositeKeyTests>("Cycle exists in the object graph which is not currently supported in AMQP mode") {
|
||||||
val key1 = CompositeKey.Builder().addKeys(alicePublicKey, bobPublicKey).build() as CompositeKey
|
val key1 = CompositeKey.Builder().addKeys(alicePublicKey, bobPublicKey).build() as CompositeKey
|
||||||
val key2 = CompositeKey.Builder().addKeys(alicePublicKey, key1).build() as CompositeKey
|
val key2 = CompositeKey.Builder().addKeys(alicePublicKey, key1).build() as CompositeKey
|
||||||
val key3 = CompositeKey.Builder().addKeys(alicePublicKey, key2).build() as CompositeKey
|
val key3 = CompositeKey.Builder().addKeys(alicePublicKey, key2).build() as CompositeKey
|
||||||
|
@ -331,8 +331,7 @@ class AttachmentClassLoaderTests : TestDependencyInjectionBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
// Kryo verifies/loads attachments on deserialization, whereas AMQP currently does not
|
fun `test deserialize of WireTransaction where contract cannot be found`() = kryoSpecific<AttachmentClassLoaderTests>("Kryo verifies/loads attachments on deserialization, whereas AMQP currently does not") {
|
||||||
fun `test deserialize of WireTransaction where contract cannot be found`() = kryoSpecific<AttachmentClassLoaderTests> {
|
|
||||||
val child = ClassLoaderForTests()
|
val child = ClassLoaderForTests()
|
||||||
val contractClass = Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, child)
|
val contractClass = Class.forName("net.corda.contracts.isolated.AnotherDummyContract", true, child)
|
||||||
val contract = contractClass.newInstance() as DummyContractBackdoor
|
val contract = contractClass.newInstance() as DummyContractBackdoor
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package net.corda.nodeapi.internal.serialization
|
||||||
|
|
||||||
|
import net.corda.core.serialization.SerializedBytes
|
||||||
|
import net.corda.core.serialization.deserialize
|
||||||
|
import net.corda.core.serialization.serialize
|
||||||
|
import net.corda.testing.TestDependencyInjectionBase
|
||||||
|
import net.corda.testing.kryoSpecific
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class ListsSerializationTest : TestDependencyInjectionBase() {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `check list can be serialized as root of serialization graph`() = kryoSpecific<ListsSerializationTest>("AMQP doesn't support lists as the root of serialization graph"){
|
||||||
|
assertEqualAfterRoundTripSerialization(listOf(1))
|
||||||
|
assertEqualAfterRoundTripSerialization(listOf(1, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline fun<reified T : Any> assertEqualAfterRoundTripSerialization(obj: T) {
|
||||||
|
|
||||||
|
val serializedForm: SerializedBytes<T> = obj.serialize()
|
||||||
|
val deserializedInstance = serializedForm.deserialize()
|
||||||
|
|
||||||
|
assertEquals(obj, deserializedInstance)
|
||||||
|
}
|
||||||
|
}
|
@ -222,8 +222,8 @@ fun getTestPartyAndCertificate(name: X500Name, publicKey: PublicKey, trustRoot:
|
|||||||
return getTestPartyAndCertificate(Party(name, publicKey), trustRoot)
|
return getTestPartyAndCertificate(Party(name, publicKey), trustRoot)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T : Any> kryoSpecific(function: () -> Unit) = if(!AMQP_ENABLED) {
|
inline fun <reified T : Any> kryoSpecific(reason: String, function: () -> Unit) = if(!AMQP_ENABLED) {
|
||||||
function()
|
function()
|
||||||
} else {
|
} else {
|
||||||
loggerFor<T>().info("Ignoring Kryo specific test")
|
loggerFor<T>().info("Ignoring Kryo specific test, reason: $reason" )
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user