From 15fa7673411f40743c47b32c1be4a7ff34f34bbe Mon Sep 17 00:00:00 2001 From: Oleg Yukhnevich Date: Sat, 21 Sep 2024 09:38:02 +0300 Subject: [PATCH] Remove `reset` for hash/signature functions - they should be single-use for now --- cryptography-core/api/cryptography-core.api | 3 -- .../api/cryptography-core.klib.api | 3 -- .../kotlin/functions/HashFunction.kt | 1 - .../kotlin/functions/SignFunction.kt | 1 - .../kotlin/functions/VerifyFunction.kt | 7 ++- .../commonMain/kotlin/default/DigestTest.kt | 27 ---------- .../commonMain/kotlin/algorithms/CCDigest.kt | 24 ++++----- .../commonMain/kotlin/algorithms/CCHmac.kt | 31 ++++------- .../commonMain/kotlin/algorithms/SecEcdsa.kt | 8 --- .../kotlin/internal/SecSignature.kt | 16 +++--- .../jvmMain/kotlin/algorithms/JdkDigest.kt | 13 ++--- .../src/jvmMain/kotlin/algorithms/JdkEcdsa.kt | 8 --- .../kotlin/operations/JdkMacSignature.kt | 12 ++--- .../operations/JdkSignatureGenerator.kt | 25 +++------ .../kotlin/operations/JdkSignatureVerifier.kt | 24 +++------ .../kotlin/algorithms/Openssl3Digest.kt | 17 +++--- .../kotlin/algorithms/Openssl3Ecdsa.kt | 8 --- .../kotlin/algorithms/Openssl3Hmac.kt | 54 ++++++++----------- .../src/commonMain/kotlin/internal/clozy.kt | 2 +- .../Openssl3DigestSignatureGenerator.kt | 37 ++++++------- .../Openssl3DigestSignatureVerifier.kt | 36 ++++++------- 21 files changed, 112 insertions(+), 245 deletions(-) diff --git a/cryptography-core/api/cryptography-core.api b/cryptography-core/api/cryptography-core.api index 4d3ee141..7c5b2624 100644 --- a/cryptography-core/api/cryptography-core.api +++ b/cryptography-core/api/cryptography-core.api @@ -652,11 +652,9 @@ public abstract interface class dev/whyoleg/cryptography/functions/HashFunction public abstract fun hashIntoByteArray ([BI)I public static synthetic fun hashIntoByteArray$default (Ldev/whyoleg/cryptography/functions/HashFunction;[BIILjava/lang/Object;)I public abstract fun hashToByteArray ()[B - public abstract fun reset ()V } public abstract interface class dev/whyoleg/cryptography/functions/SignFunction : dev/whyoleg/cryptography/functions/UpdateFunction { - public abstract fun reset ()V public fun sign ()Lkotlinx/io/bytestring/ByteString; public abstract fun signIntoByteArray ([BI)I public static synthetic fun signIntoByteArray$default (Ldev/whyoleg/cryptography/functions/SignFunction;[BIILjava/lang/Object;)I @@ -674,7 +672,6 @@ public abstract interface class dev/whyoleg/cryptography/functions/UpdateFunctio } public abstract interface class dev/whyoleg/cryptography/functions/VerifyFunction : dev/whyoleg/cryptography/functions/UpdateFunction { - public abstract fun reset ()V 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 diff --git a/cryptography-core/api/cryptography-core.klib.api b/cryptography-core/api/cryptography-core.klib.api index d8d7dd4b..1e6fff32 100644 --- a/cryptography-core/api/cryptography-core.klib.api +++ b/cryptography-core/api/cryptography-core.klib.api @@ -535,12 +535,10 @@ abstract interface dev.whyoleg.cryptography.algorithms/PBKDF2 : dev.whyoleg.cryp abstract interface dev.whyoleg.cryptography.functions/HashFunction : dev.whyoleg.cryptography.functions/UpdateFunction { // dev.whyoleg.cryptography.functions/HashFunction|null[0] abstract fun hashIntoByteArray(kotlin/ByteArray, kotlin/Int = ...): kotlin/Int // dev.whyoleg.cryptography.functions/HashFunction.hashIntoByteArray|hashIntoByteArray(kotlin.ByteArray;kotlin.Int){}[0] abstract fun hashToByteArray(): kotlin/ByteArray // dev.whyoleg.cryptography.functions/HashFunction.hashToByteArray|hashToByteArray(){}[0] - abstract fun reset() // dev.whyoleg.cryptography.functions/HashFunction.reset|reset(){}[0] open fun hash(): kotlinx.io.bytestring/ByteString // dev.whyoleg.cryptography.functions/HashFunction.hash|hash(){}[0] } abstract interface dev.whyoleg.cryptography.functions/SignFunction : dev.whyoleg.cryptography.functions/UpdateFunction { // dev.whyoleg.cryptography.functions/SignFunction|null[0] - abstract fun reset() // dev.whyoleg.cryptography.functions/SignFunction.reset|reset(){}[0] abstract fun signIntoByteArray(kotlin/ByteArray, kotlin/Int = ...): kotlin/Int // dev.whyoleg.cryptography.functions/SignFunction.signIntoByteArray|signIntoByteArray(kotlin.ByteArray;kotlin.Int){}[0] abstract fun signToByteArray(): kotlin/ByteArray // dev.whyoleg.cryptography.functions/SignFunction.signToByteArray|signToByteArray(){}[0] open fun sign(): kotlinx.io.bytestring/ByteString // dev.whyoleg.cryptography.functions/SignFunction.sign|sign(){}[0] @@ -555,7 +553,6 @@ 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 reset() // dev.whyoleg.cryptography.functions/VerifyFunction.reset|reset(){}[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] } diff --git a/cryptography-core/src/commonMain/kotlin/functions/HashFunction.kt b/cryptography-core/src/commonMain/kotlin/functions/HashFunction.kt index 02a454bd..63aed5dc 100644 --- a/cryptography-core/src/commonMain/kotlin/functions/HashFunction.kt +++ b/cryptography-core/src/commonMain/kotlin/functions/HashFunction.kt @@ -11,5 +11,4 @@ public interface HashFunction : UpdateFunction { public fun hashIntoByteArray(destination: ByteArray, destinationOffset: Int = 0): Int public fun hashToByteArray(): ByteArray public fun hash(): ByteString = hashToByteArray().asByteString() - public fun reset() } diff --git a/cryptography-core/src/commonMain/kotlin/functions/SignFunction.kt b/cryptography-core/src/commonMain/kotlin/functions/SignFunction.kt index 459a3d88..1471a919 100644 --- a/cryptography-core/src/commonMain/kotlin/functions/SignFunction.kt +++ b/cryptography-core/src/commonMain/kotlin/functions/SignFunction.kt @@ -11,5 +11,4 @@ public interface SignFunction : UpdateFunction { public fun signIntoByteArray(destination: ByteArray, destinationOffset: Int = 0): Int public fun signToByteArray(): ByteArray public fun sign(): ByteString = signToByteArray().asByteString() - public fun reset() } diff --git a/cryptography-core/src/commonMain/kotlin/functions/VerifyFunction.kt b/cryptography-core/src/commonMain/kotlin/functions/VerifyFunction.kt index ded45417..ba296d2e 100644 --- a/cryptography-core/src/commonMain/kotlin/functions/VerifyFunction.kt +++ b/cryptography-core/src/commonMain/kotlin/functions/VerifyFunction.kt @@ -9,8 +9,7 @@ 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 = - verify(signature.asByteArray(), startIndex, endIndex) - - public fun reset() + public fun verify(signature: ByteString, startIndex: Int = 0, endIndex: Int = signature.size): Boolean { + return verify(signature.asByteArray(), startIndex, endIndex) + } } diff --git a/cryptography-providers-tests/src/commonMain/kotlin/default/DigestTest.kt b/cryptography-providers-tests/src/commonMain/kotlin/default/DigestTest.kt index 6aa747ce..04dd908c 100644 --- a/cryptography-providers-tests/src/commonMain/kotlin/default/DigestTest.kt +++ b/cryptography-providers-tests/src/commonMain/kotlin/default/DigestTest.kt @@ -91,33 +91,6 @@ abstract class DigestTest(provider: CryptographyProvider) : ProviderTest(provide } } - @Test - fun testFunctionReuse() = testAlgorithm(SHA256) { - if (!supportsFunctions()) return@testAlgorithm - - val hasher = algorithm.hasher() - val bytes1 = ByteString(CryptographyRandom.nextBytes(10000)) - val bytes2 = ByteString(CryptographyRandom.nextBytes(10000)) - - val digest1 = hasher.hash(bytes1) - val digest2 = hasher.hash(bytes2) - hasher.createHashFunction().use { function -> - function.update(bytes1) - assertContentEquals(digest1, function.hash()) - - function.update(bytes2) - assertContentEquals(digest2, function.hash()) - - // update and then discard - function.update(bytes1) - function.update(bytes1) - function.reset() - // update after reset - function.update(bytes1) - assertContentEquals(digest1, function.hash()) - } - } - @Test fun testFunctionSource() = testAlgorithm(SHA256) { val hasher = algorithm.hasher() diff --git a/cryptography-providers/apple/src/commonMain/kotlin/algorithms/CCDigest.kt b/cryptography-providers/apple/src/commonMain/kotlin/algorithms/CCDigest.kt index 3c748e19..039673c6 100644 --- a/cryptography-providers/apple/src/commonMain/kotlin/algorithms/CCDigest.kt +++ b/cryptography-providers/apple/src/commonMain/kotlin/algorithms/CCDigest.kt @@ -16,20 +16,21 @@ internal class CCDigest( override val id: CryptographyAlgorithmId, ) : Hasher, Digest { override fun hasher(): Hasher = this - override fun createHashFunction(): HashFunction = CCHashFunction( - algorithm = hashAlgorithm, - context = Resource(hashAlgorithm.alloc(), nativeHeap::free) - ) + override fun createHashFunction(): HashFunction { + val context = hashAlgorithm.alloc() + // TODO: error handle + hashAlgorithm.ccInit(context) + return CCHashFunction( + algorithm = hashAlgorithm, + context = Resource(context, nativeHeap::free) + ) + } } private class CCHashFunction( private val algorithm: CCHashAlgorithm, private val context: Resource>, ) : HashFunction, SafeCloseable(SafeCloseAction(context, AutoCloseable::close)) { - init { - reset() - } - override fun update(source: ByteArray, startIndex: Int, endIndex: Int) { checkBounds(source.size, startIndex, endIndex) @@ -46,7 +47,7 @@ private class CCHashFunction( destination.usePinned { check(algorithm.ccFinal(context, it.safeAddressOf(destinationOffset).reinterpret()) > 0) } - reset() + close() return algorithm.digestSize } @@ -55,9 +56,4 @@ private class CCHashFunction( hashIntoByteArray(output) return output } - - override fun reset() { - val context = context.access() - check(algorithm.ccInit(context) > 0) - } } diff --git a/cryptography-providers/apple/src/commonMain/kotlin/algorithms/CCHmac.kt b/cryptography-providers/apple/src/commonMain/kotlin/algorithms/CCHmac.kt index e3a10eb6..f8237523 100644 --- a/cryptography-providers/apple/src/commonMain/kotlin/algorithms/CCHmac.kt +++ b/cryptography-providers/apple/src/commonMain/kotlin/algorithms/CCHmac.kt @@ -83,26 +83,25 @@ private class HmacSignature( private val key: ByteArray, private val digestSize: Int, ) : SignatureGenerator, SignatureVerifier { - private fun createFunction() = HmacFunction( - hmacAlgorithm = hmacAlgorithm, - key = key, - digestSize = digestSize, - context = Resource(nativeHeap.alloc().ptr, nativeHeap::free) - ) + + @OptIn(UnsafeNumber::class) + private fun createFunction(): HmacFunction { + val context = nativeHeap.alloc().ptr + // TODO: error handle? + key.usePinned { + CCHmacInit(context, hmacAlgorithm, it.safeAddressOf(0), key.size.convert()) + } + return HmacFunction(digestSize, Resource(context, nativeHeap::free)) + } override fun createSignFunction(): SignFunction = createFunction() override fun createVerifyFunction(): VerifyFunction = createFunction() } private class HmacFunction( - private val hmacAlgorithm: CCHmacAlgorithm, - private val key: ByteArray, private val digestSize: Int, private val context: Resource>, ) : SignFunction, VerifyFunction, SafeCloseable(SafeCloseAction(context, AutoCloseable::close)) { - init { - reset() - } @OptIn(UnsafeNumber::class) override fun update(source: ByteArray, startIndex: Int, endIndex: Int) { @@ -121,7 +120,7 @@ private class HmacFunction( destination.usePinned { CCHmacFinal(context, it.safeAddressOf(destinationOffset)) } - reset() + close() return digestSize } @@ -135,12 +134,4 @@ private class HmacFunction( checkBounds(signature.size, startIndex, endIndex) return signToByteArray().contentEquals(signature.copyOfRange(startIndex, endIndex)) } - - @OptIn(UnsafeNumber::class) - override fun reset() { - val context = context.access() - key.usePinned { - CCHmacInit(context, hmacAlgorithm, it.safeAddressOf(0), key.size.convert()) - } - } } diff --git a/cryptography-providers/apple/src/commonMain/kotlin/algorithms/SecEcdsa.kt b/cryptography-providers/apple/src/commonMain/kotlin/algorithms/SecEcdsa.kt index f075823e..b2a9f9fd 100644 --- a/cryptography-providers/apple/src/commonMain/kotlin/algorithms/SecEcdsa.kt +++ b/cryptography-providers/apple/src/commonMain/kotlin/algorithms/SecEcdsa.kt @@ -278,10 +278,6 @@ private class EcdsaRawSignatureGenerator( return rawSignature } - override fun reset() { - derSignFunction.reset() - } - override fun close() { derSignFunction.close() } @@ -322,10 +318,6 @@ private class EcdsaRawSignatureVerifier( return derVerifyFunction.verify(derSignature) } - override fun reset() { - derVerifyFunction.reset() - } - override fun close() { derVerifyFunction.close() } diff --git a/cryptography-providers/apple/src/commonMain/kotlin/internal/SecSignature.kt b/cryptography-providers/apple/src/commonMain/kotlin/internal/SecSignature.kt index 301c4503..cc81cba6 100644 --- a/cryptography-providers/apple/src/commonMain/kotlin/internal/SecSignature.kt +++ b/cryptography-providers/apple/src/commonMain/kotlin/internal/SecSignature.kt @@ -63,15 +63,13 @@ private class SecVerifyFunction( result } } - } - - override fun reset() { - ensureNotClosed() - accumulator = EmptyByteArray + }.also { + close() } override fun close() { isClosed = true + accumulator = EmptyByteArray } } @@ -118,14 +116,12 @@ private class SecSignFunction( signature.toByteArray() } - } - - override fun reset() { - ensureNotClosed() - accumulator = EmptyByteArray + }.also { + close() } override fun close() { isClosed = true + accumulator = EmptyByteArray } } diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkDigest.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkDigest.kt index b168544f..e42af4a4 100644 --- a/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkDigest.kt +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkDigest.kt @@ -18,7 +18,9 @@ internal class JdkDigest( ) : Hasher, Digest { private val messageDigest = state.messageDigest(algorithm) override fun hasher(): Hasher = this - override fun createHashFunction(): HashFunction = JdkHashFunction(messageDigest.borrowResource()) + override fun createHashFunction(): HashFunction = JdkHashFunction(messageDigest.borrowResource().also { + it.access().reset() + }) } private class JdkHashFunction(private val messageDigest: Pooled.Resource) : HashFunction { @@ -34,17 +36,12 @@ private class JdkHashFunction(private val messageDigest: Pooled.Resource, -) : SignFunction, VerifyFunction { +private class JdkMacFunction(private val mac: Pooled.Resource) : SignFunction, VerifyFunction { override fun update(source: ByteArray, startIndex: Int, endIndex: Int) { checkBounds(source.size, startIndex, endIndex) val mac = mac.access() @@ -39,13 +37,13 @@ private class JdkMacFunction( checkBounds(destination.size, destinationOffset, destinationOffset + mac.macLength) - mac.doFinal(destination, destinationOffset) + mac.doFinal(destination, destinationOffset).also { close() } return mac.macLength } override fun signToByteArray(): ByteArray { val mac = mac.access() - return mac.doFinal() + return mac.doFinal().also { close() } } override fun verify(signature: ByteArray, startIndex: Int, endIndex: Int): Boolean { @@ -53,10 +51,6 @@ private class JdkMacFunction( return signToByteArray().contentEquals(signature.copyOfRange(startIndex, endIndex)) } - override fun reset() { - mac.access().reset() - } - override fun close() { mac.close() } diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureGenerator.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureGenerator.kt index 26213e10..e6489129 100644 --- a/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureGenerator.kt +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureGenerator.kt @@ -18,19 +18,14 @@ internal class JdkSignatureGenerator( private val parameters: AlgorithmParameterSpec?, ) : SignatureGenerator { private val signature = state.signature(algorithm) - override fun createSignFunction(): SignFunction = JdkSignFunction(state, key, parameters, signature.borrowResource()) + override fun createSignFunction(): SignFunction = JdkSignFunction(signature.borrowResource().also { + val jsignature = it.access() + jsignature.initSign(key, state.secureRandom) + parameters?.let(jsignature::setParameter) + }) } -private class JdkSignFunction( - private val state: JdkCryptographyState, - private val key: JPrivateKey, - private val parameters: AlgorithmParameterSpec?, - private val jsignature: Pooled.Resource, -) : SignFunction { - init { - reset() - } - +private class JdkSignFunction(private val jsignature: Pooled.Resource) : SignFunction { override fun update(source: ByteArray, startIndex: Int, endIndex: Int) { checkBounds(source.size, startIndex, endIndex) val jsignature = jsignature.access() @@ -46,13 +41,7 @@ private class JdkSignFunction( override fun signToByteArray(): ByteArray { val jsignature = jsignature.access() - return jsignature.sign() - } - - override fun reset() { - val jsignature = jsignature.access() - jsignature.initSign(key, state.secureRandom) - parameters?.let(jsignature::setParameter) + return jsignature.sign().also { close() } } override fun close() { diff --git a/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureVerifier.kt b/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureVerifier.kt index 736510bf..57849393 100644 --- a/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureVerifier.kt +++ b/cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkSignatureVerifier.kt @@ -18,18 +18,14 @@ internal class JdkSignatureVerifier( private val parameters: AlgorithmParameterSpec?, ) : SignatureVerifier { private val signature = state.signature(algorithm) - override fun createVerifyFunction(): VerifyFunction = JdkVerifyFunction(key, parameters, signature.borrowResource()) + override fun createVerifyFunction(): VerifyFunction = JdkVerifyFunction(signature.borrowResource().also { + val jsignature = it.access() + jsignature.initVerify(key) + parameters?.let(jsignature::setParameter) + }) } -private class JdkVerifyFunction( - private val key: JPublicKey, - private val parameters: AlgorithmParameterSpec?, - private val jsignature: Pooled.Resource, -) : VerifyFunction { - init { - reset() - } - +private class JdkVerifyFunction(private val jsignature: Pooled.Resource) : VerifyFunction { override fun update(source: ByteArray, startIndex: Int, endIndex: Int) { checkBounds(source.size, startIndex, endIndex) val jsignature = jsignature.access() @@ -40,13 +36,7 @@ private class JdkVerifyFunction( checkBounds(signature.size, startIndex, endIndex) val jsignature = jsignature.access() - return jsignature.verify(signature, startIndex, endIndex - startIndex) - } - - override fun reset() { - val jsignature = jsignature.access() - jsignature.initVerify(key) - parameters?.let(jsignature::setParameter) + return jsignature.verify(signature, startIndex, endIndex - startIndex).also { close() } } override fun close() { diff --git a/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Digest.kt b/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Digest.kt index 4be4f640..4c49d2c8 100644 --- a/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Digest.kt +++ b/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Digest.kt @@ -16,7 +16,7 @@ internal class Openssl3Digest( private val md: CPointer, override val id: CryptographyAlgorithmId, ) : Hasher, Digest, SafeCloseable(SafeCloseAction(md, ::EVP_MD_free)) { - private val digestSize get() = EVP_MD_get_size(md) + private val digestSize = EVP_MD_get_size(md) constructor( algorithm: String, @@ -25,17 +25,16 @@ internal class Openssl3Digest( override fun hasher(): Hasher = this override fun createHashFunction(): HashFunction { - return Openssl3HashFunction(Resource(checkError(EVP_MD_CTX_new()), ::EVP_MD_CTX_free)) + val context = checkError(EVP_MD_CTX_new()) + // TODO: error handle + checkError(EVP_DigestInit(context, md)) + return Openssl3HashFunction(Resource(context, ::EVP_MD_CTX_free)) } // inner class to have a reference to class and so `md` cleaner - so that `md` can be freed at the right time private inner class Openssl3HashFunction( private val context: Resource>, ) : HashFunction, SafeCloseable(SafeCloseAction(context, AutoCloseable::close)) { - init { - reset() - } - @OptIn(UnsafeNumber::class) override fun update(source: ByteArray, startIndex: Int, endIndex: Int) { checkBounds(source.size, startIndex, endIndex) @@ -53,7 +52,7 @@ internal class Openssl3Digest( destination.usePinned { checkError(EVP_DigestFinal(context, it.safeAddressOf(destinationOffset).reinterpret(), null)) } - reset() + close() return digestSize } @@ -62,9 +61,5 @@ internal class Openssl3Digest( hashIntoByteArray(output) return output } - - override fun reset() { - checkError(EVP_DigestInit(context.access(), md)) - } } } diff --git a/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Ecdsa.kt b/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Ecdsa.kt index e184fb15..06ce8bc2 100644 --- a/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Ecdsa.kt +++ b/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Ecdsa.kt @@ -190,10 +190,6 @@ private class EcdsaRawSignatureGenerator( } } - override fun reset() { - derSignFunction.reset() - } - override fun close() { derSignFunction.close() } @@ -245,10 +241,6 @@ private class EcdsaRawSignatureVerifier( return derVerifyFunction.verify(derSignature) } - override fun reset() { - derVerifyFunction.reset() - } - override fun close() { derVerifyFunction.close() } diff --git a/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Hmac.kt b/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Hmac.kt index 1b9873e2..4979e6ab 100644 --- a/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Hmac.kt +++ b/cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Hmac.kt @@ -78,26 +78,34 @@ private class HmacSignature( private val hashAlgorithm: String, private val key: ByteArray, ) : SignatureGenerator, SignatureVerifier { - private fun createFunction() = HmacFunction( - hashAlgorithm = hashAlgorithm, - key = key, - context = Resource(checkError(EVP_MAC_CTX_new(Openssl3Hmac.mac)), ::EVP_MAC_CTX_free) - ) + @OptIn(UnsafeNumber::class) + private fun createFunction(): HmacFunction { + val context = checkError(EVP_MAC_CTX_new(Openssl3Hmac.mac)) + memScoped { + key.usePinned { + checkError( + EVP_MAC_init( + ctx = context, + key = it.safeAddressOf(0).reinterpret(), + keylen = key.size.convert(), + params = OSSL_PARAM_array( + OSSL_PARAM_construct_utf8_string("digest".cstr.ptr, hashAlgorithm.cstr.ptr, 0.convert()) + ) + ) + ) + } + } + return HmacFunction(Resource(context, ::EVP_MAC_CTX_free)) + } override fun createSignFunction(): SignFunction = createFunction() override fun createVerifyFunction(): VerifyFunction = createFunction() private class HmacFunction( - private val hashAlgorithm: String, - private val key: ByteArray, private val context: Resource>, ) : SignFunction, VerifyFunction, SafeCloseable(SafeCloseAction(context, AutoCloseable::close)) { @OptIn(UnsafeNumber::class) - private val macSize get() = EVP_MAC_CTX_get_mac_size(context.access()).convert() - - init { - reset() - } + private val macSize = EVP_MAC_CTX_get_mac_size(context.access()).convert() @OptIn(UnsafeNumber::class) override fun update(source: ByteArray, startIndex: Int, endIndex: Int) { @@ -117,6 +125,7 @@ private class HmacSignature( destination.usePinned { checkError(EVP_MAC_final(context, it.safeAddressOf(destinationOffset).reinterpret(), null, macSize.convert())) } + close() return macSize } @@ -130,26 +139,5 @@ private class HmacSignature( checkBounds(signature.size, startIndex, endIndex) return signToByteArray().contentEquals(signature.copyOfRange(startIndex, endIndex)) } - - @OptIn(UnsafeNumber::class) - override fun reset(): Unit = memScoped { - val context = context.access() - key.usePinned { - checkError( - EVP_MAC_init( - ctx = context, - key = it.safeAddressOf(0).reinterpret(), - keylen = key.size.convert(), - params = OSSL_PARAM_array( - OSSL_PARAM_construct_utf8_string("digest".cstr.ptr, hashAlgorithm.cstr.ptr, 0.convert()) - ) - ) - ) - } - } - - override fun close() { - context.close() - } } } diff --git a/cryptography-providers/openssl3/api/src/commonMain/kotlin/internal/clozy.kt b/cryptography-providers/openssl3/api/src/commonMain/kotlin/internal/clozy.kt index dc191ded..7a271c5b 100644 --- a/cryptography-providers/openssl3/api/src/commonMain/kotlin/internal/clozy.kt +++ b/cryptography-providers/openssl3/api/src/commonMain/kotlin/internal/clozy.kt @@ -14,7 +14,7 @@ import kotlin.native.ref.* internal abstract class SafeCloseable(closeAction: SafeCloseAction) : AutoCloseable { private val handler = CloseHandler(closeAction) private val cleaner = createCleaner(handler, CloseHandler::onClose) - override fun close(): Unit = handler.onClose() + final override fun close(): Unit = handler.onClose() } internal interface SafeCloseAction { diff --git a/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureGenerator.kt b/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureGenerator.kt index 9dea313d..1bb1c2bd 100644 --- a/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureGenerator.kt +++ b/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureGenerator.kt @@ -22,17 +22,27 @@ internal abstract class Openssl3DigestSignatureGenerator( protected abstract fun MemScope.createParams(): CValuesRef? override fun createSignFunction(): SignFunction { - return Openssl3DigestSignFunction(Resource(checkError(EVP_MD_CTX_new()), ::EVP_MD_CTX_free)) + val context = checkError(EVP_MD_CTX_new()) + memScoped { + checkError( + EVP_DigestSignInit_ex( + ctx = context, + pctx = null, + mdname = hashAlgorithm, + libctx = null, + props = null, + pkey = privateKey, + params = createParams() + ) + ) + } + return Openssl3DigestSignFunction(Resource(context, ::EVP_MD_CTX_free)) } // inner class to have a reference to class with cleaner private inner class Openssl3DigestSignFunction( private val context: Resource>, ) : SignFunction, SafeCloseable(SafeCloseAction(context, AutoCloseable::close)) { - init { - reset() - } - @OptIn(UnsafeNumber::class) override fun update(source: ByteArray, startIndex: Int, endIndex: Int) { checkBounds(source.size, startIndex, endIndex) @@ -58,21 +68,6 @@ internal abstract class Openssl3DigestSignatureGenerator( val signature = ByteArray(siglen.value.convert()) checkError(EVP_DigestSignFinal(context, signature.refToU(0), siglen.ptr)) signature.ensureSizeExactly(siglen.value.convert()) - } - - override fun reset(): Unit = memScoped { - val context = context.access() - checkError( - EVP_DigestSignInit_ex( - ctx = context, - pctx = null, - mdname = hashAlgorithm, - libctx = null, - props = null, - pkey = privateKey, - params = createParams() - ) - ) - } + }.also { close() } } } diff --git a/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureVerifier.kt b/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureVerifier.kt index 2a3876ef..6477c29b 100644 --- a/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureVerifier.kt +++ b/cryptography-providers/openssl3/api/src/commonMain/kotlin/operations/Openssl3DigestSignatureVerifier.kt @@ -21,17 +21,27 @@ internal abstract class Openssl3DigestSignatureVerifier( protected abstract fun MemScope.createParams(): CValuesRef? override fun createVerifyFunction(): VerifyFunction { - return Openssl3DigestVerifyFunction(Resource(checkError(EVP_MD_CTX_new()), ::EVP_MD_CTX_free)) + val context = checkError(EVP_MD_CTX_new()) + memScoped { + checkError( + EVP_DigestVerifyInit_ex( + ctx = context, + pctx = null, + mdname = hashAlgorithm, + libctx = null, + props = null, + pkey = publicKey, + params = createParams() + ) + ) + } + return Openssl3DigestVerifyFunction(Resource(context, ::EVP_MD_CTX_free)) } // inner class to have a reference to class with cleaner private inner class Openssl3DigestVerifyFunction( private val context: Resource>, ) : VerifyFunction, SafeCloseable(SafeCloseAction(context, AutoCloseable::close)) { - init { - reset() - } - @OptIn(UnsafeNumber::class) override fun update(source: ByteArray, startIndex: Int, endIndex: Int) { checkBounds(source.size, startIndex, endIndex) @@ -50,26 +60,12 @@ internal abstract class Openssl3DigestSignatureVerifier( val result = signature.usePinned { EVP_DigestVerifyFinal(context, it.safeAddressOf(startIndex).reinterpret(), (endIndex - startIndex).convert()) } + close() // 0 - means verification failed // 1 - means verification succeeded // other - means error if (result != 0) checkError(result) return result == 1 } - - override fun reset(): Unit = memScoped { - val context = context.access() - checkError( - EVP_DigestVerifyInit_ex( - ctx = context, - pctx = null, - mdname = hashAlgorithm, - libctx = null, - props = null, - pkey = publicKey, - params = createParams() - ) - ) - } } }