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:
Viktor Kolomeyko
2017-09-01 14:45:14 +01:00
committed by GitHub
parent 6bc44b96f1
commit 954ed69102
6 changed files with 58 additions and 16 deletions

View File

@ -1,5 +1,6 @@
package net.corda.core.crypto
import net.corda.core.crypto.composite.CompositeSignaturesWithKeys
import net.corda.core.serialization.deserialize
import java.io.ByteArrayOutputStream
import java.security.*
@ -75,10 +76,10 @@ class CompositeSignature : Signature(SIGNATURE_ALGORITHM) {
data class State(val buffer: ByteArrayOutputStream, val verifyKey: CompositeKey) {
fun engineVerify(sigBytes: ByteArray): Boolean {
val sigs = sigBytes.deserialize<List<TransactionSignature>>()
return if (verifyKey.isFulfilledBy(sigs.map { it.by })) {
val sig = sigBytes.deserialize<CompositeSignaturesWithKeys>()
return if (verifyKey.isFulfilledBy(sig.sigs.map { it.by })) {
val clearData = SecureHash.SHA256(buffer.toByteArray())
sigs.all { it.isValid(clearData) }
sig.sigs.all { it.isValid(clearData) }
} else {
false
}

View File

@ -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())
}
}

View File

@ -1,6 +1,7 @@
package net.corda.core.crypto
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.div
import net.corda.core.serialization.serialize
@ -160,17 +161,17 @@ class CompositeKeyTests : TestDependencyInjectionBase() {
engine.initVerify(twoOfThree)
engine.update(secureHash.bytes)
assertFalse { engine.verify(listOf(aliceSignature).serialize().bytes) }
assertFalse { engine.verify(listOf(bobSignature).serialize().bytes) }
assertFalse { engine.verify(listOf(charlieSignature).serialize().bytes) }
assertTrue { engine.verify(listOf(aliceSignature, bobSignature).serialize().bytes) }
assertTrue { engine.verify(listOf(aliceSignature, charlieSignature).serialize().bytes) }
assertTrue { engine.verify(listOf(bobSignature, charlieSignature).serialize().bytes) }
assertTrue { engine.verify(listOf(aliceSignature, bobSignature, charlieSignature).serialize().bytes) }
assertFalse { engine.verify(CompositeSignaturesWithKeys(listOf(aliceSignature)).serialize().bytes) }
assertFalse { engine.verify(CompositeSignaturesWithKeys(listOf(bobSignature)).serialize().bytes) }
assertFalse { engine.verify(CompositeSignaturesWithKeys(listOf(charlieSignature)).serialize().bytes) }
assertTrue { engine.verify(CompositeSignaturesWithKeys(listOf(aliceSignature, bobSignature)).serialize().bytes) }
assertTrue { engine.verify(CompositeSignaturesWithKeys(listOf(aliceSignature, charlieSignature)).serialize().bytes) }
assertTrue { engine.verify(CompositeSignaturesWithKeys(listOf(bobSignature, charlieSignature)).serialize().bytes) }
assertTrue { engine.verify(CompositeSignaturesWithKeys(listOf(aliceSignature, bobSignature, charlieSignature)).serialize().bytes) }
// Check the underlying signature is validated
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()
@ -216,7 +217,7 @@ class CompositeKeyTests : TestDependencyInjectionBase() {
}
@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 key2 = CompositeKey.Builder().addKeys(alicePublicKey, key1).build() as CompositeKey
val key3 = CompositeKey.Builder().addKeys(alicePublicKey, key2).build() as CompositeKey