Skip to content

Commit

Permalink
Make signature verification fail on wrong signature
Browse files Browse the repository at this point in the history
  • Loading branch information
whyoleg committed Sep 21, 2024
1 parent 15fa767 commit fa49703
Show file tree
Hide file tree
Showing 24 changed files with 200 additions and 81 deletions.
27 changes: 20 additions & 7 deletions cryptography-core/api/cryptography-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -672,10 +672,14 @@ public abstract interface class dev/whyoleg/cryptography/functions/UpdateFunctio
}

public abstract interface class dev/whyoleg/cryptography/functions/VerifyFunction : dev/whyoleg/cryptography/functions/UpdateFunction {
public fun verify (Lkotlinx/io/bytestring/ByteString;II)Z
public abstract fun verify ([BII)Z
public static synthetic fun verify$default (Ldev/whyoleg/cryptography/functions/VerifyFunction;Lkotlinx/io/bytestring/ByteString;IIILjava/lang/Object;)Z
public static synthetic fun verify$default (Ldev/whyoleg/cryptography/functions/VerifyFunction;[BIIILjava/lang/Object;)Z
public fun tryVerify (Lkotlinx/io/bytestring/ByteString;II)Z
public abstract fun tryVerify ([BII)Z
public static synthetic fun tryVerify$default (Ldev/whyoleg/cryptography/functions/VerifyFunction;Lkotlinx/io/bytestring/ByteString;IIILjava/lang/Object;)Z
public static synthetic fun tryVerify$default (Ldev/whyoleg/cryptography/functions/VerifyFunction;[BIIILjava/lang/Object;)Z
public fun verify (Lkotlinx/io/bytestring/ByteString;II)V
public abstract fun verify ([BII)V
public static synthetic fun verify$default (Ldev/whyoleg/cryptography/functions/VerifyFunction;Lkotlinx/io/bytestring/ByteString;IIILjava/lang/Object;)V
public static synthetic fun verify$default (Ldev/whyoleg/cryptography/functions/VerifyFunction;[BIIILjava/lang/Object;)V
}

public abstract interface class dev/whyoleg/cryptography/materials/key/EncodableKey : dev/whyoleg/cryptography/materials/key/Key {
Expand Down Expand Up @@ -816,14 +820,23 @@ public abstract interface class dev/whyoleg/cryptography/operations/SignatureGen

public abstract interface class dev/whyoleg/cryptography/operations/SignatureVerifier {
public abstract fun createVerifyFunction ()Ldev/whyoleg/cryptography/functions/VerifyFunction;
public fun tryVerifySignature (Lkotlinx/io/RawSource;Lkotlinx/io/bytestring/ByteString;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun tryVerifySignature (Lkotlinx/io/bytestring/ByteString;Lkotlinx/io/bytestring/ByteString;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun tryVerifySignature ([B[BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun tryVerifySignature$suspendImpl (Ldev/whyoleg/cryptography/operations/SignatureVerifier;Lkotlinx/io/RawSource;Lkotlinx/io/bytestring/ByteString;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun tryVerifySignature$suspendImpl (Ldev/whyoleg/cryptography/operations/SignatureVerifier;Lkotlinx/io/bytestring/ByteString;Lkotlinx/io/bytestring/ByteString;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun tryVerifySignature$suspendImpl (Ldev/whyoleg/cryptography/operations/SignatureVerifier;[B[BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun tryVerifySignatureBlocking (Lkotlinx/io/RawSource;Lkotlinx/io/bytestring/ByteString;)Z
public fun tryVerifySignatureBlocking (Lkotlinx/io/bytestring/ByteString;Lkotlinx/io/bytestring/ByteString;)Z
public fun tryVerifySignatureBlocking ([B[B)Z
public fun verifySignature (Lkotlinx/io/RawSource;Lkotlinx/io/bytestring/ByteString;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun verifySignature (Lkotlinx/io/bytestring/ByteString;Lkotlinx/io/bytestring/ByteString;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun verifySignature ([B[BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun verifySignature$suspendImpl (Ldev/whyoleg/cryptography/operations/SignatureVerifier;Lkotlinx/io/RawSource;Lkotlinx/io/bytestring/ByteString;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun verifySignature$suspendImpl (Ldev/whyoleg/cryptography/operations/SignatureVerifier;Lkotlinx/io/bytestring/ByteString;Lkotlinx/io/bytestring/ByteString;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun verifySignature$suspendImpl (Ldev/whyoleg/cryptography/operations/SignatureVerifier;[B[BLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun verifySignatureBlocking (Lkotlinx/io/RawSource;Lkotlinx/io/bytestring/ByteString;)Z
public fun verifySignatureBlocking (Lkotlinx/io/bytestring/ByteString;Lkotlinx/io/bytestring/ByteString;)Z
public fun verifySignatureBlocking ([B[B)Z
public fun verifySignatureBlocking (Lkotlinx/io/RawSource;Lkotlinx/io/bytestring/ByteString;)V
public fun verifySignatureBlocking (Lkotlinx/io/bytestring/ByteString;Lkotlinx/io/bytestring/ByteString;)V
public fun verifySignatureBlocking ([B[B)V
}

24 changes: 16 additions & 8 deletions cryptography-core/api/cryptography-core.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,10 @@ abstract interface dev.whyoleg.cryptography.functions/UpdateFunction : kotlin/Au
}

abstract interface dev.whyoleg.cryptography.functions/VerifyFunction : dev.whyoleg.cryptography.functions/UpdateFunction { // dev.whyoleg.cryptography.functions/VerifyFunction|null[0]
abstract fun verify(kotlin/ByteArray, kotlin/Int = ..., kotlin/Int = ...): kotlin/Boolean // dev.whyoleg.cryptography.functions/VerifyFunction.verify|verify(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
open fun verify(kotlinx.io.bytestring/ByteString, kotlin/Int = ..., kotlin/Int = ...): kotlin/Boolean // dev.whyoleg.cryptography.functions/VerifyFunction.verify|verify(kotlinx.io.bytestring.ByteString;kotlin.Int;kotlin.Int){}[0]
abstract fun tryVerify(kotlin/ByteArray, kotlin/Int = ..., kotlin/Int = ...): kotlin/Boolean // dev.whyoleg.cryptography.functions/VerifyFunction.tryVerify|tryVerify(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
abstract fun verify(kotlin/ByteArray, kotlin/Int = ..., kotlin/Int = ...) // dev.whyoleg.cryptography.functions/VerifyFunction.verify|verify(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
open fun tryVerify(kotlinx.io.bytestring/ByteString, kotlin/Int = ..., kotlin/Int = ...): kotlin/Boolean // dev.whyoleg.cryptography.functions/VerifyFunction.tryVerify|tryVerify(kotlinx.io.bytestring.ByteString;kotlin.Int;kotlin.Int){}[0]
open fun verify(kotlinx.io.bytestring/ByteString, kotlin/Int = ..., kotlin/Int = ...) // dev.whyoleg.cryptography.functions/VerifyFunction.verify|verify(kotlinx.io.bytestring.ByteString;kotlin.Int;kotlin.Int){}[0]
}

abstract interface dev.whyoleg.cryptography.materials.key/Key // dev.whyoleg.cryptography.materials.key/Key|null[0]
Expand Down Expand Up @@ -635,12 +637,18 @@ abstract interface dev.whyoleg.cryptography.operations/SignatureGenerator { // d

abstract interface dev.whyoleg.cryptography.operations/SignatureVerifier { // dev.whyoleg.cryptography.operations/SignatureVerifier|null[0]
abstract fun createVerifyFunction(): dev.whyoleg.cryptography.functions/VerifyFunction // dev.whyoleg.cryptography.operations/SignatureVerifier.createVerifyFunction|createVerifyFunction(){}[0]
open fun verifySignatureBlocking(kotlin/ByteArray, kotlin/ByteArray): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignatureBlocking|verifySignatureBlocking(kotlin.ByteArray;kotlin.ByteArray){}[0]
open fun verifySignatureBlocking(kotlinx.io.bytestring/ByteString, kotlinx.io.bytestring/ByteString): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignatureBlocking|verifySignatureBlocking(kotlinx.io.bytestring.ByteString;kotlinx.io.bytestring.ByteString){}[0]
open fun verifySignatureBlocking(kotlinx.io/RawSource, kotlinx.io.bytestring/ByteString): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignatureBlocking|verifySignatureBlocking(kotlinx.io.RawSource;kotlinx.io.bytestring.ByteString){}[0]
open suspend fun verifySignature(kotlin/ByteArray, kotlin/ByteArray): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignature|verifySignature(kotlin.ByteArray;kotlin.ByteArray){}[0]
open suspend fun verifySignature(kotlinx.io.bytestring/ByteString, kotlinx.io.bytestring/ByteString): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignature|verifySignature(kotlinx.io.bytestring.ByteString;kotlinx.io.bytestring.ByteString){}[0]
open suspend fun verifySignature(kotlinx.io/RawSource, kotlinx.io.bytestring/ByteString): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignature|verifySignature(kotlinx.io.RawSource;kotlinx.io.bytestring.ByteString){}[0]
open fun tryVerifySignatureBlocking(kotlin/ByteArray, kotlin/ByteArray): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.tryVerifySignatureBlocking|tryVerifySignatureBlocking(kotlin.ByteArray;kotlin.ByteArray){}[0]
open fun tryVerifySignatureBlocking(kotlinx.io.bytestring/ByteString, kotlinx.io.bytestring/ByteString): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.tryVerifySignatureBlocking|tryVerifySignatureBlocking(kotlinx.io.bytestring.ByteString;kotlinx.io.bytestring.ByteString){}[0]
open fun tryVerifySignatureBlocking(kotlinx.io/RawSource, kotlinx.io.bytestring/ByteString): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.tryVerifySignatureBlocking|tryVerifySignatureBlocking(kotlinx.io.RawSource;kotlinx.io.bytestring.ByteString){}[0]
open fun verifySignatureBlocking(kotlin/ByteArray, kotlin/ByteArray) // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignatureBlocking|verifySignatureBlocking(kotlin.ByteArray;kotlin.ByteArray){}[0]
open fun verifySignatureBlocking(kotlinx.io.bytestring/ByteString, kotlinx.io.bytestring/ByteString) // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignatureBlocking|verifySignatureBlocking(kotlinx.io.bytestring.ByteString;kotlinx.io.bytestring.ByteString){}[0]
open fun verifySignatureBlocking(kotlinx.io/RawSource, kotlinx.io.bytestring/ByteString) // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignatureBlocking|verifySignatureBlocking(kotlinx.io.RawSource;kotlinx.io.bytestring.ByteString){}[0]
open suspend fun tryVerifySignature(kotlin/ByteArray, kotlin/ByteArray): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.tryVerifySignature|tryVerifySignature(kotlin.ByteArray;kotlin.ByteArray){}[0]
open suspend fun tryVerifySignature(kotlinx.io.bytestring/ByteString, kotlinx.io.bytestring/ByteString): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.tryVerifySignature|tryVerifySignature(kotlinx.io.bytestring.ByteString;kotlinx.io.bytestring.ByteString){}[0]
open suspend fun tryVerifySignature(kotlinx.io/RawSource, kotlinx.io.bytestring/ByteString): kotlin/Boolean // dev.whyoleg.cryptography.operations/SignatureVerifier.tryVerifySignature|tryVerifySignature(kotlinx.io.RawSource;kotlinx.io.bytestring.ByteString){}[0]
open suspend fun verifySignature(kotlin/ByteArray, kotlin/ByteArray) // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignature|verifySignature(kotlin.ByteArray;kotlin.ByteArray){}[0]
open suspend fun verifySignature(kotlinx.io.bytestring/ByteString, kotlinx.io.bytestring/ByteString) // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignature|verifySignature(kotlinx.io.bytestring.ByteString;kotlinx.io.bytestring.ByteString){}[0]
open suspend fun verifySignature(kotlinx.io/RawSource, kotlinx.io.bytestring/ByteString) // dev.whyoleg.cryptography.operations/SignatureVerifier.verifySignature|verifySignature(kotlinx.io.RawSource;kotlinx.io.bytestring.ByteString){}[0]
}

abstract interface dev.whyoleg.cryptography/CryptographyAlgorithm { // dev.whyoleg.cryptography/CryptographyAlgorithm|null[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ import dev.whyoleg.cryptography.*
import kotlinx.io.bytestring.*

public interface VerifyFunction : UpdateFunction {
public fun verify(signature: ByteArray, startIndex: Int = 0, endIndex: Int = signature.size): Boolean
public fun verify(signature: ByteString, startIndex: Int = 0, endIndex: Int = signature.size): Boolean {
public fun tryVerify(signature: ByteArray, startIndex: Int = 0, endIndex: Int = signature.size): Boolean
public fun tryVerify(signature: ByteString, startIndex: Int = 0, endIndex: Int = signature.size): Boolean {
return tryVerify(signature.asByteArray(), startIndex, endIndex)
}

public fun verify(signature: ByteArray, startIndex: Int = 0, endIndex: Int = signature.size)
public fun verify(signature: ByteString, startIndex: Int = 0, endIndex: Int = signature.size) {
return verify(signature.asByteArray(), startIndex, endIndex)
}
}
16 changes: 12 additions & 4 deletions cryptography-core/src/commonMain/kotlin/operations/Hasher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,26 @@ import kotlinx.io.bytestring.*
public interface Hasher {
public fun createHashFunction(): HashFunction

public suspend fun hash(data: ByteArray): ByteArray = hashBlocking(data)
public suspend fun hash(data: ByteArray): ByteArray {
return hashBlocking(data)
}

public suspend fun hash(data: ByteString): ByteString = hash(data.asByteArray()).asByteString()
public suspend fun hash(data: ByteString): ByteString {
return hash(data.asByteArray()).asByteString()
}

public suspend fun hash(data: RawSource): ByteString = hashBlocking(data)
public suspend fun hash(data: RawSource): ByteString {
return hashBlocking(data)
}

public fun hashBlocking(data: ByteArray): ByteArray = createHashFunction().use {
it.update(data)
it.hashToByteArray()
}

public fun hashBlocking(data: ByteString): ByteString = hashBlocking(data.asByteArray()).asByteString()
public fun hashBlocking(data: ByteString): ByteString {
return hashBlocking(data.asByteArray()).asByteString()
}

public fun hashBlocking(data: RawSource): ByteString = createHashFunction().use {
it.update(data)
Expand Down
68 changes: 56 additions & 12 deletions cryptography-core/src/commonMain/kotlin/operations/Signature.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,27 @@ import kotlinx.io.bytestring.*
public interface SignatureGenerator {
public fun createSignFunction(): SignFunction

public suspend fun generateSignature(data: ByteArray): ByteArray = generateSignatureBlocking(data)
public suspend fun generateSignature(data: ByteString): ByteString = generateSignature(data.asByteArray()).asByteString()
public suspend fun generateSignature(data: RawSource): ByteString = generateSignatureBlocking(data)
public suspend fun generateSignature(data: ByteArray): ByteArray {
return generateSignatureBlocking(data)
}

public suspend fun generateSignature(data: ByteString): ByteString {
return generateSignature(data.asByteArray()).asByteString()
}

public suspend fun generateSignature(data: RawSource): ByteString {
return generateSignatureBlocking(data)
}

public fun generateSignatureBlocking(data: ByteArray): ByteArray = createSignFunction().use {
it.update(data)
it.signToByteArray()
}

public fun generateSignatureBlocking(data: ByteString): ByteString = generateSignatureBlocking(data.asByteArray()).asByteString()
public fun generateSignatureBlocking(data: ByteString): ByteString {
return generateSignatureBlocking(data.asByteArray()).asByteString()
}

public fun generateSignatureBlocking(data: RawSource): ByteString = createSignFunction().use {
it.update(data)
it.sign()
Expand All @@ -33,21 +44,54 @@ public interface SignatureGenerator {
public interface SignatureVerifier {
public fun createVerifyFunction(): VerifyFunction

public suspend fun verifySignature(data: ByteArray, signature: ByteArray): Boolean = verifySignatureBlocking(data, signature)
public suspend fun verifySignature(data: ByteString, signature: ByteString): Boolean =
verifySignature(data.asByteArray(), signature.asByteArray())
public suspend fun tryVerifySignature(data: ByteArray, signature: ByteArray): Boolean {
return tryVerifySignatureBlocking(data, signature)
}

public suspend fun tryVerifySignature(data: ByteString, signature: ByteString): Boolean {
return tryVerifySignature(data.asByteArray(), signature.asByteArray())
}

public suspend fun tryVerifySignature(data: RawSource, signature: ByteString): Boolean {
return tryVerifySignatureBlocking(data, signature)
}

public fun tryVerifySignatureBlocking(data: ByteArray, signature: ByteArray): Boolean = createVerifyFunction().use {
it.update(data)
it.tryVerify(signature)
}

public suspend fun verifySignature(data: RawSource, signature: ByteString): Boolean = verifySignatureBlocking(data, signature)
public fun tryVerifySignatureBlocking(data: ByteString, signature: ByteString): Boolean {
return tryVerifySignatureBlocking(data.asByteArray(), signature.asByteArray())
}

public fun verifySignatureBlocking(data: ByteArray, signature: ByteArray): Boolean = createVerifyFunction().use {
public fun tryVerifySignatureBlocking(data: RawSource, signature: ByteString): Boolean = createVerifyFunction().use {
it.update(data)
it.tryVerify(signature)
}

public suspend fun verifySignature(data: ByteArray, signature: ByteArray) {
return verifySignatureBlocking(data, signature)
}

public suspend fun verifySignature(data: ByteString, signature: ByteString) {
return verifySignature(data.asByteArray(), signature.asByteArray())
}

public suspend fun verifySignature(data: RawSource, signature: ByteString) {
return verifySignatureBlocking(data, signature)
}

public fun verifySignatureBlocking(data: ByteArray, signature: ByteArray): Unit = createVerifyFunction().use {
it.update(data)
it.verify(signature)
}

public fun verifySignatureBlocking(data: ByteString, signature: ByteString): Boolean =
verifySignatureBlocking(data.asByteArray(), signature.asByteArray())
public fun verifySignatureBlocking(data: ByteString, signature: ByteString) {
return verifySignatureBlocking(data.asByteArray(), signature.asByteArray())
}

public fun verifySignatureBlocking(data: RawSource, signature: ByteString): Boolean = createVerifyFunction().use {
public fun verifySignatureBlocking(data: RawSource, signature: ByteString): Unit = createVerifyFunction().use {
it.update(data)
it.verify(signature)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ abstract class EcdsaCompatibilityTest(
val signature = signer.generateSignature(data)
logger.log { "signature.size = ${signature.size}" }

assertTrue(verifier.verifySignature(data, signature), "Initial Verify")
assertTrue(verifier.tryVerifySignature(data, signature), "Initial Verify")

api.signatures.saveData(signatureParametersId, SignatureData(keyReference, data, signature))
}
Expand All @@ -87,10 +87,10 @@ abstract class EcdsaCompatibilityTest(
val generators = privateKeys.map { it.signatureGenerator(signatureParameters.digest, signatureParameters.signatureFormat) }

verifiers.forEach { verifier ->
assertTrue(verifier.verifySignature(data, signature), "Verify")
assertTrue(verifier.tryVerifySignature(data, signature), "Verify")

generators.forEach { generator ->
assertTrue(verifier.verifySignature(data, generator.generateSignature(data)), "Sign-Verify")
assertTrue(verifier.tryVerifySignature(data, generator.generateSignature(data)), "Sign-Verify")
}
}
}
Expand Down
Loading

0 comments on commit fa49703

Please sign in to comment.