Skip to content

Commit 81aaede

Browse files
committed
providers/base: add accumulating sign/verify helpers; add unwrapSubjectPublicKeyInfo(Set<ObjectIdentifier>) helper; update ABI
1 parent 1d0f98f commit 81aaede

File tree

4 files changed

+141
-0
lines changed

4 files changed

+141
-0
lines changed

cryptography-providers/base/api/cryptography-provider-base.api

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public final class dev/whyoleg/cryptography/providers/base/algorithms/EcKt {
6666
public final class dev/whyoleg/cryptography/providers/base/materials/KeysKt {
6767
public static final fun unwrapPem-unSj4pc (Ljava/lang/String;[B)[B
6868
public static final fun unwrapPrivateKeyInfo-4RESAxk (Ljava/lang/String;[B)[B
69+
public static final fun unwrapSubjectPublicKeyInfo (Ljava/util/Set;[B)[B
6970
public static final fun unwrapSubjectPublicKeyInfo-4RESAxk (Ljava/lang/String;[B)[B
7071
public static final fun wrapPem-unSj4pc (Ljava/lang/String;[B)[B
7172
public static final fun wrapPrivateKeyInfo (ILdev/whyoleg/cryptography/serialization/asn1/modules/KeyAlgorithmIdentifier;[B)[B
@@ -77,6 +78,24 @@ public final class dev/whyoleg/cryptography/providers/base/operations/Accumulati
7778
public fun close ()V
7879
}
7980

81+
public final class dev/whyoleg/cryptography/providers/base/operations/AccumulatingSignFunction : dev/whyoleg/cryptography/operations/SignFunction {
82+
public fun <init> (Lkotlin/jvm/functions/Function1;)V
83+
public fun close ()V
84+
public fun reset ()V
85+
public fun signIntoByteArray ([BI)I
86+
public fun signToByteArray ()[B
87+
public fun update ([BII)V
88+
}
89+
90+
public final class dev/whyoleg/cryptography/providers/base/operations/AccumulatingVerifyFunction : dev/whyoleg/cryptography/operations/VerifyFunction {
91+
public fun <init> (Lkotlin/jvm/functions/Function4;)V
92+
public fun close ()V
93+
public fun reset ()V
94+
public fun tryVerify ([BII)Z
95+
public fun update ([BII)V
96+
public fun verify ([BII)V
97+
}
98+
8099
public abstract interface class dev/whyoleg/cryptography/providers/base/operations/BaseAuthenticatedCipher : dev/whyoleg/cryptography/operations/AuthenticatedCipher, dev/whyoleg/cryptography/providers/base/operations/BaseAuthenticatedDecryptor, dev/whyoleg/cryptography/providers/base/operations/BaseAuthenticatedEncryptor, dev/whyoleg/cryptography/providers/base/operations/BaseCipher {
81100
}
82101

cryptography-providers/base/api/cryptography-provider-base.klib.api

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,26 @@ final class dev.whyoleg.cryptography.providers.base.operations/AccumulatingCiphe
134134
final fun close() // dev.whyoleg.cryptography.providers.base.operations/AccumulatingCipherFunction.close|close(){}[0]
135135
}
136136

137+
final class dev.whyoleg.cryptography.providers.base.operations/AccumulatingSignFunction : dev.whyoleg.cryptography.operations/SignFunction { // dev.whyoleg.cryptography.providers.base.operations/AccumulatingSignFunction|null[0]
138+
constructor <init>(kotlin/Function1<kotlin/ByteArray, kotlin/ByteArray>) // dev.whyoleg.cryptography.providers.base.operations/AccumulatingSignFunction.<init>|<init>(kotlin.Function1<kotlin.ByteArray,kotlin.ByteArray>){}[0]
139+
140+
final fun close() // dev.whyoleg.cryptography.providers.base.operations/AccumulatingSignFunction.close|close(){}[0]
141+
final fun reset() // dev.whyoleg.cryptography.providers.base.operations/AccumulatingSignFunction.reset|reset(){}[0]
142+
final fun signIntoByteArray(kotlin/ByteArray, kotlin/Int): kotlin/Int // dev.whyoleg.cryptography.providers.base.operations/AccumulatingSignFunction.signIntoByteArray|signIntoByteArray(kotlin.ByteArray;kotlin.Int){}[0]
143+
final fun signToByteArray(): kotlin/ByteArray // dev.whyoleg.cryptography.providers.base.operations/AccumulatingSignFunction.signToByteArray|signToByteArray(){}[0]
144+
final fun update(kotlin/ByteArray, kotlin/Int, kotlin/Int) // dev.whyoleg.cryptography.providers.base.operations/AccumulatingSignFunction.update|update(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
145+
}
146+
147+
final class dev.whyoleg.cryptography.providers.base.operations/AccumulatingVerifyFunction : dev.whyoleg.cryptography.operations/VerifyFunction { // dev.whyoleg.cryptography.providers.base.operations/AccumulatingVerifyFunction|null[0]
148+
constructor <init>(kotlin/Function4<kotlin/ByteArray, kotlin/ByteArray, kotlin/Int, kotlin/Int, kotlin/Boolean>) // dev.whyoleg.cryptography.providers.base.operations/AccumulatingVerifyFunction.<init>|<init>(kotlin.Function4<kotlin.ByteArray,kotlin.ByteArray,kotlin.Int,kotlin.Int,kotlin.Boolean>){}[0]
149+
150+
final fun close() // dev.whyoleg.cryptography.providers.base.operations/AccumulatingVerifyFunction.close|close(){}[0]
151+
final fun reset() // dev.whyoleg.cryptography.providers.base.operations/AccumulatingVerifyFunction.reset|reset(){}[0]
152+
final fun tryVerify(kotlin/ByteArray, kotlin/Int, kotlin/Int): kotlin/Boolean // dev.whyoleg.cryptography.providers.base.operations/AccumulatingVerifyFunction.tryVerify|tryVerify(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
153+
final fun update(kotlin/ByteArray, kotlin/Int, kotlin/Int) // dev.whyoleg.cryptography.providers.base.operations/AccumulatingVerifyFunction.update|update(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
154+
final fun verify(kotlin/ByteArray, kotlin/Int, kotlin/Int) // dev.whyoleg.cryptography.providers.base.operations/AccumulatingVerifyFunction.verify|verify(kotlin.ByteArray;kotlin.Int;kotlin.Int){}[0]
155+
}
156+
137157
final val dev.whyoleg.cryptography.providers.base/EmptyByteArray // dev.whyoleg.cryptography.providers.base/EmptyByteArray|{}EmptyByteArray[0]
138158
final fun <get-EmptyByteArray>(): kotlin/ByteArray // dev.whyoleg.cryptography.providers.base/EmptyByteArray.<get-EmptyByteArray>|<get-EmptyByteArray>(){}[0]
139159

@@ -143,6 +163,7 @@ final fun dev.whyoleg.cryptography.providers.base.algorithms/convertEcPrivateKey
143163
final fun dev.whyoleg.cryptography.providers.base.materials/unwrapPem(dev.whyoleg.cryptography.serialization.pem/PemLabel, kotlin/ByteArray): kotlin/ByteArray // dev.whyoleg.cryptography.providers.base.materials/unwrapPem|unwrapPem(dev.whyoleg.cryptography.serialization.pem.PemLabel;kotlin.ByteArray){}[0]
144164
final fun dev.whyoleg.cryptography.providers.base.materials/unwrapPrivateKeyInfo(dev.whyoleg.cryptography.serialization.asn1/ObjectIdentifier, kotlin/ByteArray): kotlin/ByteArray // dev.whyoleg.cryptography.providers.base.materials/unwrapPrivateKeyInfo|unwrapPrivateKeyInfo(dev.whyoleg.cryptography.serialization.asn1.ObjectIdentifier;kotlin.ByteArray){}[0]
145165
final fun dev.whyoleg.cryptography.providers.base.materials/unwrapSubjectPublicKeyInfo(dev.whyoleg.cryptography.serialization.asn1/ObjectIdentifier, kotlin/ByteArray): kotlin/ByteArray // dev.whyoleg.cryptography.providers.base.materials/unwrapSubjectPublicKeyInfo|unwrapSubjectPublicKeyInfo(dev.whyoleg.cryptography.serialization.asn1.ObjectIdentifier;kotlin.ByteArray){}[0]
166+
final fun dev.whyoleg.cryptography.providers.base.materials/unwrapSubjectPublicKeyInfo(kotlin.collections/Set<dev.whyoleg.cryptography.serialization.asn1/ObjectIdentifier>, kotlin/ByteArray): kotlin/ByteArray // dev.whyoleg.cryptography.providers.base.materials/unwrapSubjectPublicKeyInfo|unwrapSubjectPublicKeyInfo(kotlin.collections.Set<dev.whyoleg.cryptography.serialization.asn1.ObjectIdentifier>;kotlin.ByteArray){}[0]
146167
final fun dev.whyoleg.cryptography.providers.base.materials/wrapPem(dev.whyoleg.cryptography.serialization.pem/PemLabel, kotlin/ByteArray): kotlin/ByteArray // dev.whyoleg.cryptography.providers.base.materials/wrapPem|wrapPem(dev.whyoleg.cryptography.serialization.pem.PemLabel;kotlin.ByteArray){}[0]
147168
final fun dev.whyoleg.cryptography.providers.base.materials/wrapPrivateKeyInfo(kotlin/Int, dev.whyoleg.cryptography.serialization.asn1.modules/KeyAlgorithmIdentifier, kotlin/ByteArray): kotlin/ByteArray // dev.whyoleg.cryptography.providers.base.materials/wrapPrivateKeyInfo|wrapPrivateKeyInfo(kotlin.Int;dev.whyoleg.cryptography.serialization.asn1.modules.KeyAlgorithmIdentifier;kotlin.ByteArray){}[0]
148169
final fun dev.whyoleg.cryptography.providers.base.materials/wrapSubjectPublicKeyInfo(dev.whyoleg.cryptography.serialization.asn1.modules/KeyAlgorithmIdentifier, kotlin/ByteArray): kotlin/ByteArray // dev.whyoleg.cryptography.providers.base.materials/wrapSubjectPublicKeyInfo|wrapSubjectPublicKeyInfo(dev.whyoleg.cryptography.serialization.asn1.modules.KeyAlgorithmIdentifier;kotlin.ByteArray){}[0]

cryptography-providers/base/src/commonMain/kotlin/materials/keys.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ public fun unwrapSubjectPublicKeyInfo(algorithm: ObjectIdentifier, key: ByteArra
3232
}.subjectPublicKey.byteArray
3333
}
3434

35+
@CryptographyProviderApi
36+
public fun unwrapSubjectPublicKeyInfo(algorithms: Set<ObjectIdentifier>, key: ByteArray): ByteArray {
37+
return Der.decodeFromByteArray(SubjectPublicKeyInfo.serializer(), key).also {
38+
check(it.algorithm.algorithm in algorithms) {
39+
"Expected one of algorithms '${algorithms.joinToString { a -> a.value }}', received: '${it.algorithm.algorithm}'"
40+
}
41+
}.subjectPublicKey.byteArray
42+
}
43+
3544
@CryptographyProviderApi
3645
public fun wrapSubjectPublicKeyInfo(identifier: KeyAlgorithmIdentifier, key: ByteArray): ByteArray {
3746
return Der.encodeToByteArray(
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright (c) 2025 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package dev.whyoleg.cryptography.providers.base.operations
6+
7+
import dev.whyoleg.cryptography.*
8+
import dev.whyoleg.cryptography.operations.*
9+
import dev.whyoleg.cryptography.providers.base.*
10+
11+
@CryptographyProviderApi
12+
public class AccumulatingSignFunction(
13+
private val oneShot: (data: ByteArray) -> ByteArray,
14+
) : SignFunction {
15+
private var isClosed = false
16+
private var accumulator = EmptyByteArray
17+
18+
private fun ensureNotClosed() { check(!isClosed) { "Already closed" } }
19+
private fun accumulate(source: ByteArray, startIndex: Int, endIndex: Int) {
20+
ensureNotClosed()
21+
checkBounds(source.size, startIndex, endIndex)
22+
accumulator += source.copyOfRange(startIndex, endIndex)
23+
}
24+
25+
override fun update(source: ByteArray, startIndex: Int, endIndex: Int) {
26+
accumulate(source, startIndex, endIndex)
27+
}
28+
29+
override fun signIntoByteArray(destination: ByteArray, destinationOffset: Int): Int {
30+
val sig = signToByteArray()
31+
sig.copyInto(destination, destinationOffset)
32+
return sig.size
33+
}
34+
35+
override fun signToByteArray(): ByteArray {
36+
ensureNotClosed()
37+
val out = oneShot(accumulator)
38+
reset()
39+
return out
40+
}
41+
42+
override fun reset() {
43+
ensureNotClosed()
44+
accumulator = EmptyByteArray
45+
}
46+
47+
override fun close() {
48+
isClosed = true
49+
accumulator = EmptyByteArray
50+
}
51+
}
52+
53+
@CryptographyProviderApi
54+
public class AccumulatingVerifyFunction(
55+
private val oneShot: (data: ByteArray, signature: ByteArray, startIndex: Int, endIndex: Int) -> Boolean,
56+
) : VerifyFunction {
57+
private var isClosed = false
58+
private var accumulator = EmptyByteArray
59+
60+
private fun ensureNotClosed() { check(!isClosed) { "Already closed" } }
61+
private fun accumulate(source: ByteArray, startIndex: Int, endIndex: Int) {
62+
ensureNotClosed()
63+
checkBounds(source.size, startIndex, endIndex)
64+
accumulator += source.copyOfRange(startIndex, endIndex)
65+
}
66+
67+
override fun update(source: ByteArray, startIndex: Int, endIndex: Int) {
68+
accumulate(source, startIndex, endIndex)
69+
}
70+
71+
override fun tryVerify(signature: ByteArray, startIndex: Int, endIndex: Int): Boolean {
72+
ensureNotClosed()
73+
checkBounds(signature.size, startIndex, endIndex)
74+
val ok = oneShot(accumulator, signature, startIndex, endIndex)
75+
reset()
76+
return ok
77+
}
78+
79+
override fun verify(signature: ByteArray, startIndex: Int, endIndex: Int) {
80+
check(tryVerify(signature, startIndex, endIndex)) { "Invalid signature" }
81+
}
82+
83+
override fun reset() {
84+
ensureNotClosed()
85+
accumulator = EmptyByteArray
86+
}
87+
88+
override fun close() {
89+
isClosed = true
90+
accumulator = EmptyByteArray
91+
}
92+
}

0 commit comments

Comments
 (0)