Skip to content

Commit 2459eb1

Browse files
committed
Cleanup secret derivation API and make providers use only ByteArray and not ByteString
For now `ByteString` is used mostly as a wrapper. When kotlinx-io will be stable or `ByteString` will migrate to kotlin-stdlib `ByteArray` overloads will be deprecated
1 parent 10c71fc commit 2459eb1

File tree

8 files changed

+52
-42
lines changed

8 files changed

+52
-42
lines changed

cryptography-core/api/cryptography-core.api

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,10 @@ public abstract interface class dev/whyoleg/cryptography/operations/SecretDeriva
760760
public abstract interface class dev/whyoleg/cryptography/operations/SharedSecretGenerator {
761761
public fun generateSharedSecret (Ldev/whyoleg/cryptography/materials/key/Key;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
762762
public static synthetic fun generateSharedSecret$suspendImpl (Ldev/whyoleg/cryptography/operations/SharedSecretGenerator;Ldev/whyoleg/cryptography/materials/key/Key;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
763-
public abstract fun generateSharedSecretBlocking (Ldev/whyoleg/cryptography/materials/key/Key;)Lkotlinx/io/bytestring/ByteString;
763+
public fun generateSharedSecretBlocking (Ldev/whyoleg/cryptography/materials/key/Key;)Lkotlinx/io/bytestring/ByteString;
764+
public fun generateSharedSecretToByteArray (Ldev/whyoleg/cryptography/materials/key/Key;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
765+
public static synthetic fun generateSharedSecretToByteArray$suspendImpl (Ldev/whyoleg/cryptography/operations/SharedSecretGenerator;Ldev/whyoleg/cryptography/materials/key/Key;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
766+
public abstract fun generateSharedSecretToByteArrayBlocking (Ldev/whyoleg/cryptography/materials/key/Key;)[B
764767
}
765768

766769
public abstract interface class dev/whyoleg/cryptography/operations/SignatureGenerator {

cryptography-core/api/cryptography-core.klib.api

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,10 @@ abstract interface <#A: dev.whyoleg.cryptography.materials.key/Key> dev.whyoleg.
420420
}
421421

422422
abstract interface <#A: dev.whyoleg.cryptography.materials.key/Key> dev.whyoleg.cryptography.operations/SharedSecretGenerator { // dev.whyoleg.cryptography.operations/SharedSecretGenerator|null[0]
423-
abstract fun generateSharedSecretBlocking(#A): kotlinx.io.bytestring/ByteString // dev.whyoleg.cryptography.operations/SharedSecretGenerator.generateSharedSecretBlocking|generateSharedSecretBlocking(1:0){}[0]
423+
abstract fun generateSharedSecretToByteArrayBlocking(#A): kotlin/ByteArray // dev.whyoleg.cryptography.operations/SharedSecretGenerator.generateSharedSecretToByteArrayBlocking|generateSharedSecretToByteArrayBlocking(1:0){}[0]
424+
open fun generateSharedSecretBlocking(#A): kotlinx.io.bytestring/ByteString // dev.whyoleg.cryptography.operations/SharedSecretGenerator.generateSharedSecretBlocking|generateSharedSecretBlocking(1:0){}[0]
424425
open suspend fun generateSharedSecret(#A): kotlinx.io.bytestring/ByteString // dev.whyoleg.cryptography.operations/SharedSecretGenerator.generateSharedSecret|generateSharedSecret(1:0){}[0]
426+
open suspend fun generateSharedSecretToByteArray(#A): kotlin/ByteArray // dev.whyoleg.cryptography.operations/SharedSecretGenerator.generateSharedSecretToByteArray|generateSharedSecretToByteArray(1:0){}[0]
425427
}
426428

427429
abstract interface <#A: dev.whyoleg.cryptography.materials.key/KeyFormat, #B: dev.whyoleg.cryptography.materials.key/Key> dev.whyoleg.cryptography.materials.key/KeyDecoder { // dev.whyoleg.cryptography.materials.key/KeyDecoder|null[0]

cryptography-core/src/commonMain/kotlin/operations/SecretDerivation.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,17 @@ import kotlinx.io.bytestring.*
99

1010
@SubclassOptInRequired(CryptographyProviderApi::class)
1111
public interface SecretDerivation {
12-
public suspend fun deriveSecret(input: ByteArray): ByteArray = deriveSecretBlocking(input)
12+
public suspend fun deriveSecret(input: ByteArray): ByteArray {
13+
return deriveSecretBlocking(input)
14+
}
15+
16+
public suspend fun deriveSecret(input: ByteString): ByteString {
17+
return deriveSecret(input.asByteArray()).asByteString()
18+
}
19+
1320
public fun deriveSecretBlocking(input: ByteArray): ByteArray
1421

15-
public suspend fun deriveSecret(input: ByteString): ByteString = deriveSecret(input.asByteArray()).asByteString()
16-
public fun deriveSecretBlocking(input: ByteString): ByteString = deriveSecretBlocking(input.asByteArray()).asByteString()
22+
public fun deriveSecretBlocking(input: ByteString): ByteString {
23+
return deriveSecretBlocking(input.asByteArray()).asByteString()
24+
}
1725
}

cryptography-core/src/commonMain/kotlin/operations/SharedSecretGenerator.kt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ import kotlinx.io.bytestring.*
1010

1111
@SubclassOptInRequired(CryptographyProviderApi::class)
1212
public interface SharedSecretGenerator<K : Key> {
13-
public suspend fun generateSharedSecret(other: K): ByteString = generateSharedSecretBlocking(other)
14-
public fun generateSharedSecretBlocking(other: K): ByteString
13+
public suspend fun generateSharedSecretToByteArray(other: K): ByteArray {
14+
return generateSharedSecretToByteArrayBlocking(other)
15+
}
16+
17+
public fun generateSharedSecretToByteArrayBlocking(other: K): ByteArray
18+
19+
public suspend fun generateSharedSecret(other: K): ByteString {
20+
return generateSharedSecretToByteArray(other).asByteString()
21+
}
22+
23+
public fun generateSharedSecretBlocking(other: K): ByteString {
24+
return generateSharedSecretToByteArrayBlocking(other).asByteString()
25+
}
1526
}

cryptography-providers/jdk/src/jvmMain/kotlin/algorithms/JdkEcdh.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import dev.whyoleg.cryptography.algorithms.*
88
import dev.whyoleg.cryptography.operations.*
99
import dev.whyoleg.cryptography.providers.jdk.*
1010
import dev.whyoleg.cryptography.providers.jdk.operations.*
11-
import kotlinx.io.bytestring.*
1211

1312
internal class JdkEcdh(state: JdkCryptographyState) : JdkEc<ECDH.PublicKey, ECDH.PrivateKey, ECDH.KeyPair>(state), ECDH {
1413
override fun JPublicKey.convert(): ECDH.PublicKey = EcdhPublicKey(state, this)
@@ -26,7 +25,7 @@ internal class JdkEcdh(state: JdkCryptographyState) : JdkEc<ECDH.PublicKey, ECDH
2625
) : ECDH.PublicKey, BaseEcPublicKey(key), SharedSecretGenerator<ECDH.PrivateKey> {
2726
private val keyAgreement = state.keyAgreement("ECDH")
2827
override fun sharedSecretGenerator(): SharedSecretGenerator<ECDH.PrivateKey> = this
29-
override fun generateSharedSecretBlocking(other: ECDH.PrivateKey): ByteString {
28+
override fun generateSharedSecretToByteArrayBlocking(other: ECDH.PrivateKey): ByteArray {
3029
check(other is EcdhPrivateKey) { "Only key produced by JDK provider is supported" }
3130

3231
return keyAgreement.doAgreement(state, other.key, key)
@@ -39,7 +38,7 @@ internal class JdkEcdh(state: JdkCryptographyState) : JdkEc<ECDH.PublicKey, ECDH
3938
) : ECDH.PrivateKey, BaseEcPrivateKey(key), SharedSecretGenerator<ECDH.PublicKey> {
4039
private val keyAgreement = state.keyAgreement("ECDH")
4140
override fun sharedSecretGenerator(): SharedSecretGenerator<ECDH.PublicKey> = this
42-
override fun generateSharedSecretBlocking(other: ECDH.PublicKey): ByteString {
41+
override fun generateSharedSecretToByteArrayBlocking(other: ECDH.PublicKey): ByteArray {
4342
check(other is EcdhPublicKey) { "Only key produced by JDK provider is supported" }
4443

4544
return keyAgreement.doAgreement(state, key, other.key)

cryptography-providers/jdk/src/jvmMain/kotlin/operations/JdkKeyAgreement.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,13 @@
55
package dev.whyoleg.cryptography.providers.jdk.operations
66

77
import dev.whyoleg.cryptography.providers.jdk.*
8-
import kotlinx.io.bytestring.*
9-
import kotlinx.io.bytestring.unsafe.*
108

11-
@OptIn(UnsafeByteStringApi::class)
129
internal fun Pooled<JKeyAgreement>.doAgreement(
1310
state: JdkCryptographyState,
1411
privateKey: JPrivateKey,
1512
publicKey: JPublicKey,
16-
): ByteString = use {
13+
): ByteArray = use {
1714
it.init(privateKey, state.secureRandom)
1815
it.doPhase(publicKey, true)
19-
UnsafeByteStringOperations.wrapUnsafe(it.generateSecret())
16+
it.generateSecret()
2017
}

cryptography-providers/openssl3/api/src/commonMain/kotlin/algorithms/Openssl3Ecdh.kt

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import dev.whyoleg.cryptography.providers.openssl3.internal.*
1111
import dev.whyoleg.cryptography.providers.openssl3.internal.cinterop.*
1212
import dev.whyoleg.cryptography.providers.openssl3.materials.*
1313
import kotlinx.cinterop.*
14-
import kotlinx.io.bytestring.*
15-
import kotlinx.io.bytestring.unsafe.*
1614
import platform.posix.*
1715

1816
internal object Openssl3Ecdh : ECDH {
@@ -111,7 +109,7 @@ internal object Openssl3Ecdh : ECDH {
111109

112110
override fun sharedSecretGenerator(): SharedSecretGenerator<ECDH.PublicKey> = this
113111

114-
override fun generateSharedSecretBlocking(other: ECDH.PublicKey): ByteString {
112+
override fun generateSharedSecretToByteArrayBlocking(other: ECDH.PublicKey): ByteArray {
115113
check(other is EcPublicKey)
116114

117115
return deriveSharedSecret(publicKey = other.key, privateKey = key)
@@ -135,19 +133,19 @@ internal object Openssl3Ecdh : ECDH {
135133

136134
override fun sharedSecretGenerator(): SharedSecretGenerator<ECDH.PrivateKey> = this
137135

138-
override fun generateSharedSecretBlocking(other: ECDH.PrivateKey): ByteString {
136+
override fun generateSharedSecretToByteArrayBlocking(other: ECDH.PrivateKey): ByteArray {
139137
check(other is EcPrivateKey)
140138

141139
return deriveSharedSecret(publicKey = key, privateKey = other.key)
142140
}
143141
}
144142
}
145143

146-
@OptIn(UnsafeNumber::class, UnsafeByteStringApi::class)
144+
@OptIn(UnsafeNumber::class)
147145
private fun deriveSharedSecret(
148146
publicKey: CPointer<EVP_PKEY>,
149147
privateKey: CPointer<EVP_PKEY>,
150-
): ByteString = memScoped {
148+
): ByteArray = memScoped {
151149
val context = checkError(EVP_PKEY_CTX_new_from_pkey(null, privateKey, null))
152150
try {
153151
checkError(EVP_PKEY_derive_init(context))
@@ -156,7 +154,7 @@ private fun deriveSharedSecret(
156154
checkError(EVP_PKEY_derive(context, null, secretSize.ptr))
157155
val secret = ByteArray(secretSize.value.toInt())
158156
checkError(EVP_PKEY_derive(context, secret.refToU(0), secretSize.ptr))
159-
UnsafeByteStringOperations.wrapUnsafe(secret)
157+
secret
160158
} finally {
161159
EVP_PKEY_CTX_free(context)
162160
}

cryptography-providers/webcrypto/src/commonMain/kotlin/algorithms/WebCryptoEcdh.kt

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import dev.whyoleg.cryptography.algorithms.*
88
import dev.whyoleg.cryptography.operations.*
99
import dev.whyoleg.cryptography.providers.webcrypto.internal.*
1010
import dev.whyoleg.cryptography.providers.webcrypto.materials.*
11-
import kotlinx.io.bytestring.*
12-
import kotlinx.io.bytestring.unsafe.*
1311

1412
internal object WebCryptoEcdh : WebCryptoEc<ECDH.PublicKey, ECDH.PrivateKey, ECDH.KeyPair>(
1513
algorithmName = "ECDH",
@@ -27,38 +25,32 @@ internal object WebCryptoEcdh : WebCryptoEc<ECDH.PublicKey, ECDH.PrivateKey, ECD
2725
) : EcPublicKey(publicKey), ECDH.PublicKey, SharedSecretGenerator<ECDH.PrivateKey> {
2826
override fun sharedSecretGenerator(): SharedSecretGenerator<ECDH.PrivateKey> = this
2927

30-
@OptIn(UnsafeByteStringApi::class)
31-
override suspend fun generateSharedSecret(other: ECDH.PrivateKey): ByteString {
28+
override suspend fun generateSharedSecretToByteArray(other: ECDH.PrivateKey): ByteArray {
3229
check(other is EcdhPrivateKey)
33-
return UnsafeByteStringOperations.wrapUnsafe(
34-
WebCrypto.deriveBits(
35-
algorithm = EcdhKeyDeriveAlgorithm(publicKey),
36-
baseKey = other.privateKey,
37-
length = curveOrderSize(publicKey.algorithm.ecKeyAlgorithmNamedCurve).inBits
38-
)
30+
return WebCrypto.deriveBits(
31+
algorithm = EcdhKeyDeriveAlgorithm(publicKey),
32+
baseKey = other.privateKey,
33+
length = curveOrderSize(publicKey.algorithm.ecKeyAlgorithmNamedCurve).inBits
3934
)
4035
}
4136

42-
override fun generateSharedSecretBlocking(other: ECDH.PrivateKey): ByteString = nonBlocking()
37+
override fun generateSharedSecretToByteArrayBlocking(other: ECDH.PrivateKey): ByteArray = nonBlocking()
4338
}
4439

4540
private class EcdhPrivateKey(
4641
privateKey: CryptoKey,
4742
) : EcPrivateKey(privateKey), ECDH.PrivateKey, SharedSecretGenerator<ECDH.PublicKey> {
4843
override fun sharedSecretGenerator(): SharedSecretGenerator<ECDH.PublicKey> = this
4944

50-
@OptIn(UnsafeByteStringApi::class)
51-
override suspend fun generateSharedSecret(other: ECDH.PublicKey): ByteString {
45+
override suspend fun generateSharedSecretToByteArray(other: ECDH.PublicKey): ByteArray {
5246
check(other is EcdhPublicKey)
53-
return UnsafeByteStringOperations.wrapUnsafe(
54-
WebCrypto.deriveBits(
55-
algorithm = EcdhKeyDeriveAlgorithm(other.publicKey),
56-
baseKey = privateKey,
57-
length = curveOrderSize(privateKey.algorithm.ecKeyAlgorithmNamedCurve).inBits
58-
)
47+
return WebCrypto.deriveBits(
48+
algorithm = EcdhKeyDeriveAlgorithm(other.publicKey),
49+
baseKey = privateKey,
50+
length = curveOrderSize(privateKey.algorithm.ecKeyAlgorithmNamedCurve).inBits
5951
)
6052
}
6153

62-
override fun generateSharedSecretBlocking(other: ECDH.PublicKey): ByteString = nonBlocking()
54+
override fun generateSharedSecretToByteArrayBlocking(other: ECDH.PublicKey): ByteArray = nonBlocking()
6355
}
6456
}

0 commit comments

Comments
 (0)