|
1 | 1 | /* |
2 | | - * Copyright (c) 2024 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license. |
| 2 | + * Copyright (c) 2024-2025 Oleg Yukhnevich. Use of this source code is governed by the Apache 2.0 license. |
3 | 3 | */ |
4 | 4 |
|
5 | 5 | @file:Suppress("FunctionName") |
6 | 6 |
|
7 | 7 | package dev.whyoleg.cryptography.providers.webcrypto.internal |
8 | 8 |
|
9 | | -// marker interface |
10 | | -internal expect interface Algorithm |
| 9 | +import kotlin.js.* |
11 | 10 |
|
12 | | -internal expect fun Algorithm(name: String): Algorithm |
| 11 | +internal external interface Algorithm |
13 | 12 |
|
14 | | -internal expect fun AesKeyGenerationAlgorithm(name: String, length: Int): Algorithm |
| 13 | +internal fun Algorithm(name: String): Algorithm = |
| 14 | + js("({ name: name })") |
15 | 15 |
|
16 | | -internal expect fun AesCbcCipherAlgorithm(iv: ByteArray): Algorithm |
| 16 | +internal fun AesKeyGenerationAlgorithm(name: String, length: Int): Algorithm = |
| 17 | + js("({ name: name, length: length })") |
17 | 18 |
|
18 | | -internal expect fun AesCtrCipherAlgorithm(counter: ByteArray, length: Int): Algorithm |
| 19 | +internal fun AesCbcCipherAlgorithm(iv: ByteArray): Algorithm = |
| 20 | + jsAesCbcCipherAlgorithm(iv.toInt8Array()) |
19 | 21 |
|
20 | | -internal expect fun AesGcmCipherAlgorithm(additionalData: ByteArray?, iv: ByteArray, tagLength: Int): Algorithm |
| 22 | +private fun jsAesCbcCipherAlgorithm(iv: Int8Array): Algorithm = |
| 23 | + js("({ name: 'AES-CBC', iv: iv })") |
21 | 24 |
|
22 | | -internal expect fun HmacKeyAlgorithm(hash: String, length: Int?): Algorithm |
| 25 | +internal fun AesCtrCipherAlgorithm(counter: ByteArray, length: Int): Algorithm = |
| 26 | + jsAesCtrCipherAlgorithm(counter.toInt8Array(), length) |
23 | 27 |
|
24 | | -internal expect fun EcKeyAlgorithm( |
25 | | - name: String, //ECDSA | ECDH |
26 | | - namedCurve: String, //P-256, P-384, P-521 |
27 | | -): Algorithm |
| 28 | +private fun jsAesCtrCipherAlgorithm(counter: Int8Array, length: Int): Algorithm = |
| 29 | + js("({ name: 'AES-CTR', counter: counter, length: length })") |
28 | 30 |
|
29 | | -internal expect val Algorithm.ecKeyAlgorithmNamedCurve: String |
| 31 | +internal fun AesGcmCipherAlgorithm(additionalData: ByteArray?, iv: ByteArray, tagLength: Int): Algorithm = when (additionalData) { |
| 32 | + null -> jsAesGcmCipherAlgorithm(iv.toInt8Array(), tagLength) |
| 33 | + else -> jsAesGcmCipherAlgorithm(iv.toInt8Array(), tagLength, additionalData.toInt8Array()) |
| 34 | +} |
30 | 35 |
|
31 | | -internal expect fun EcdsaSignatureAlgorithm(hash: String): Algorithm |
| 36 | +private fun jsAesGcmCipherAlgorithm(iv: Int8Array, tagLength: Int): Algorithm = |
| 37 | + js("({ name: 'AES-GCM', iv: iv, tagLength: tagLength })") |
32 | 38 |
|
33 | | -internal expect fun EcdhKeyDeriveAlgorithm(publicKey: CryptoKey): Algorithm |
| 39 | +private fun jsAesGcmCipherAlgorithm(iv: Int8Array, tagLength: Int, additionalData: Int8Array): Algorithm = |
| 40 | + js("({ name: 'AES-GCM', iv: iv, tagLength: tagLength, additionalData: additionalData })") |
34 | 41 |
|
35 | | -internal expect fun Pbkdf2DeriveAlgorithm(hash: String, iterations: Int, salt: ByteArray): Algorithm |
| 42 | +internal fun HmacKeyAlgorithm(hash: String, length: Int?): Algorithm = when (length) { |
| 43 | + null -> jsHmacKeyAlgorithm(hash) |
| 44 | + else -> jsHmacKeyAlgorithm(hash, length) |
| 45 | +} |
36 | 46 |
|
37 | | -internal expect fun HkdfDeriveAlgorithm(hash: String, salt: ByteArray, info: ByteArray): Algorithm |
| 47 | +private fun jsHmacKeyAlgorithm(hash: String): Algorithm = |
| 48 | + js("({ name: 'HMAC', hash: hash })") |
38 | 49 |
|
39 | | -internal expect fun RsaKeyGenerationAlgorithm( |
40 | | - name: String, //RSA-PSS | RSA-OAEP |
41 | | - modulusLength: Int, |
42 | | - publicExponent: ByteArray, |
43 | | - hash: String, |
44 | | -): Algorithm |
| 50 | +private fun jsHmacKeyAlgorithm(hash: String, length: Int): Algorithm = |
| 51 | + js("({ name: 'HMAC', hash: hash, length: length })") |
45 | 52 |
|
46 | | -internal expect fun RsaKeyImportAlgorithm( |
47 | | - name: String, //RSA-PSS | RSA-OAEP |
48 | | - hash: String, |
49 | | -): Algorithm |
| 53 | +internal fun EcKeyAlgorithm(name: String, namedCurve: String): Algorithm = |
| 54 | + js("({ name: name, namedCurve: namedCurve })") |
50 | 55 |
|
51 | | -internal expect fun RsaOaepCipherAlgorithm(label: ByteArray?): Algorithm |
| 56 | +internal val Algorithm.ecKeyAlgorithmNamedCurve: String get() = ecKeyAlgorithmNamedCurve(this) |
52 | 57 |
|
53 | | -internal expect fun RsaPssSignatureAlgorithm(saltLength: Int): Algorithm |
| 58 | +@Suppress("UNUSED_PARAMETER") |
| 59 | +private fun ecKeyAlgorithmNamedCurve(algorithm: Algorithm): String = js("algorithm.namedCurve") |
54 | 60 |
|
55 | | -internal expect val Algorithm.rsaKeyAlgorithmHashName: String |
| 61 | +internal fun EcdsaSignatureAlgorithm(hash: String): Algorithm = |
| 62 | + js("({ name: 'ECDSA', hash: hash })") |
| 63 | + |
| 64 | +internal fun EcdhKeyDeriveAlgorithm(publicKey: CryptoKey): Algorithm = |
| 65 | + js("({ name: 'ECDH', public: publicKey })") |
| 66 | + |
| 67 | +internal fun Pbkdf2DeriveAlgorithm(hash: String, iterations: Int, salt: ByteArray): Algorithm = |
| 68 | + jsPbkdf2DeriveAlgorithm(hash, iterations, salt.toInt8Array()) |
| 69 | + |
| 70 | +private fun jsPbkdf2DeriveAlgorithm(hash: String, iterations: Int, salt: Int8Array): Algorithm = |
| 71 | + js("({ name: 'PBKDF2', hash: hash, iterations: iterations, salt: salt })") |
| 72 | + |
| 73 | +internal fun HkdfDeriveAlgorithm(hash: String, salt: ByteArray, info: ByteArray): Algorithm = |
| 74 | + jsHkdfDeriveAlgorithm(hash, salt.toInt8Array(), info.toInt8Array()) |
| 75 | + |
| 76 | +private fun jsHkdfDeriveAlgorithm(hash: String, salt: Int8Array, info: Int8Array): Algorithm = |
| 77 | + js("({ name: 'HKDF', hash: hash, salt: salt, info: info })") |
| 78 | + |
| 79 | +internal fun RsaKeyGenerationAlgorithm(name: String, modulusLength: Int, publicExponent: ByteArray, hash: String): Algorithm { |
| 80 | + val publicExponent2 = publicExponent.toInt8Array().let { Uint8Array(it.buffer, it.byteOffset, it.length) } |
| 81 | + return jsRsaKeyGenerationAlgorithm(name, modulusLength, publicExponent2, hash) |
| 82 | +} |
| 83 | + |
| 84 | +private fun jsRsaKeyGenerationAlgorithm(name: String, modulusLength: Int, publicExponent: Uint8Array, hash: String): Algorithm = |
| 85 | + js("({ name: name, modulusLength: modulusLength, publicExponent: publicExponent, hash: hash })") |
| 86 | + |
| 87 | +internal fun RsaKeyImportAlgorithm(name: String, hash: String): Algorithm = |
| 88 | + js("({ name: name, hash: hash })") |
| 89 | + |
| 90 | +internal fun RsaOaepCipherAlgorithm(label: ByteArray?): Algorithm = when (label) { |
| 91 | + null -> jsRsaOaepCipherAlgorithm() |
| 92 | + else -> jsRsaOaepCipherAlgorithm(label.toInt8Array()) |
| 93 | +} |
| 94 | + |
| 95 | +private fun jsRsaOaepCipherAlgorithm(): Algorithm = |
| 96 | + js("({ name: 'RSA-OAEP' })") |
| 97 | + |
| 98 | +private fun jsRsaOaepCipherAlgorithm(label: Int8Array): Algorithm = |
| 99 | + js("({ name: 'RSA-OAEP', label: label })") |
| 100 | + |
| 101 | +internal fun RsaPssSignatureAlgorithm(saltLength: Int): Algorithm = |
| 102 | + js("({ name: 'RSA-PSS', saltLength: saltLength })") |
| 103 | + |
| 104 | +internal val Algorithm.rsaKeyAlgorithmHashName: String get() = rsaKeyAlgorithmHashName(this) |
| 105 | + |
| 106 | +@Suppress("UNUSED_PARAMETER") |
| 107 | +private fun rsaKeyAlgorithmHashName(algorithm: Algorithm): String = js("algorithm.hash.name") |
0 commit comments