Merged in rnicoll-signed-data (pull request #69)

Add SignedData class
This commit is contained in:
Ross Nicoll 2016-04-27 13:16:42 +01:00
commit 47401a2a28
2 changed files with 66 additions and 0 deletions

View File

@ -3,6 +3,8 @@ package core.crypto
import com.google.common.io.BaseEncoding
import core.Party
import core.serialization.OpaqueBytes
import core.serialization.SerializedBytes
import core.serialization.deserialize
import java.math.BigInteger
import java.security.*
import java.security.interfaces.ECPublicKey
@ -62,6 +64,40 @@ open class DigitalSignature(bits: ByteArray, val covering: Int = 0) : OpaqueByte
class LegallyIdentifiable(val signer: Party, bits: ByteArray, covering: Int) : WithKey(signer.owningKey, bits, covering)
}
/**
* A serialized piece of data and its signature. Enforces signature validity in order to deserialize the data
* contained within.
*
* @param raw the raw serialized data
* @param sig the (unverified) signature for the data
*/
open class SignedData<T : Any>(val raw: SerializedBytes<T>, val sig: DigitalSignature.WithKey) {
/**
* Return the deserialized data if the signature can be verified.
*
* @throws IllegalArgumentException if the data is invalid (only used if verifyData() is overloaded).
* @throws SignatureException if the signature is invalid.
*/
@Throws(SignatureException::class)
fun verified(): T {
sig.by.verifyWithECDSA(raw.bits, sig)
val data = raw.deserialize()
verifyData(data)
return data
}
/**
* Verify the wrapped data after the signature has been verified and the data deserialised. Provided as an extension
* point for subclasses.
*
* @throws IllegalArgumentException if the data is invalid.
*/
@Throws(IllegalArgumentException::class)
open protected fun verifyData(data: T) {
// By default we accept anything
}
}
object NullPublicKey : PublicKey, Comparable<PublicKey> {
override fun getAlgorithm() = "NULL"
override fun getEncoded() = byteArrayOf(0)

View File

@ -0,0 +1,30 @@
package core.crypto
import core.serialization.serialize
import org.junit.Test
import java.security.SignatureException
import kotlin.test.assertEquals
class SignedDataTest {
val data = "Just a simple test string"
val serialized = data.serialize()
@Test
fun `make sure correctly signed data is released`() {
val keyPair = generateKeyPair()
val sig = keyPair.private.signWithECDSA(serialized.bits, keyPair.public)
val wrappedData = SignedData(serialized, sig)
val unwrappedData = wrappedData.verified()
assertEquals(data, unwrappedData)
}
@Test(expected = SignatureException::class)
fun `make sure incorrectly signed data raises an exception`() {
val keyPairA = generateKeyPair()
val keyPairB = generateKeyPair()
val sig = keyPairA.private.signWithECDSA(serialized.bits, keyPairB.public)
val wrappedData = SignedData(serialized, sig)
val unwrappedData = wrappedData.verified()
}
}