SecretStream.kt fixed by using a lot of external objects on JsSodiumInterface.kt.

Problem: function crypto_secretstream_xchacha20poly1305_pull returns JsAny (via an external object) to dataAndTag value. Later dataAndTag is compared to Boolean. Check it out later. It may cause problems.
This commit is contained in:
Maria Chernova 2024-12-09 03:27:29 +03:00 committed by kildishevps
parent 014daefc43
commit 12ebea9550
4 changed files with 42 additions and 20 deletions

View File

@ -48,6 +48,23 @@ external object CryptoKxServerSessionKeysResult: JsAny {
val sharedTx: Uint8Array val sharedTx: Uint8Array
} }
external object CryptoSecretboxDetachedResult: JsAny {
val cipher: Uint8Array
val mac: Uint8Array
}
external object CryptoSecretstreamXchacha20poly1305InitPushResult: JsAny {
val state: Uint8Array
val header: Uint8Array
}
external object CryptoSecretstreamXchacha20poly1305PullResult: JsAny {
val message: Uint8Array
val tag: UByte
}
@JsModule("libsodium-wrappers-sumo") @JsModule("libsodium-wrappers-sumo")
external object JsSodiumInterface { external object JsSodiumInterface {
@ -87,7 +104,8 @@ external object JsSodiumInterface {
@JsName("crypto_generichash_blake2b_update") @JsName("crypto_generichash_blake2b_update")
fun crypto_generichash_blake2b_update(state: JsAny, inputMessage: Uint8Array) fun crypto_generichash_blake2b_update(state: JsAny, inputMessage: Uint8Array)
// TODO: строка ниже просто висела без ничего, я ее закомментила
//crypto_secretstream_xchacha20poly1305_init_push
@JsName("crypto_generichash_blake2b_final") @JsName("crypto_generichash_blake2b_final")
fun crypto_generichash_blake2b_final(state: JsAny, hashLength: Int) : Uint8Array fun crypto_generichash_blake2b_final(state: JsAny, hashLength: Int) : Uint8Array
@ -130,7 +148,7 @@ external object JsSodiumInterface {
//XChaCha20Poly1305 //XChaCha20Poly1305
//encrypt //encrypt
@JsName("crypto_secretstream_xchacha20poly1305_init_push") @JsName("crypto_secretstream_xchacha20poly1305_init_push")
fun crypto_secretstream_xchacha20poly1305_init_push(key: Uint8Array) : JsAny fun crypto_secretstream_xchacha20poly1305_init_push(key: Uint8Array) : CryptoSecretstreamXchacha20poly1305InitPushResult
@JsName("crypto_secretstream_xchacha20poly1305_push") @JsName("crypto_secretstream_xchacha20poly1305_push")
// TODO: два варианта: \/ // TODO: два варианта: \/
// 1. Меняем юбайт на байт и юинт на инт \/ // 1. Меняем юбайт на байт и юинт на инт \/
@ -141,7 +159,7 @@ external object JsSodiumInterface {
@JsName("crypto_secretstream_xchacha20poly1305_init_pull") @JsName("crypto_secretstream_xchacha20poly1305_init_pull")
fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : JsAny fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : JsAny
@JsName("crypto_secretstream_xchacha20poly1305_pull") @JsName("crypto_secretstream_xchacha20poly1305_pull")
fun crypto_secretstream_xchacha20poly1305_pull(state: JsAny, ciphertext: Uint8Array, associatedData: Uint8Array) : JsAny fun crypto_secretstream_xchacha20poly1305_pull(state: JsAny, ciphertext: Uint8Array, associatedData: Uint8Array) : CryptoSecretstreamXchacha20poly1305PullResult
//keygen and rekey //keygen and rekey
@JsName("crypto_secretstream_xchacha20poly1305_keygen") @JsName("crypto_secretstream_xchacha20poly1305_keygen")
@ -151,7 +169,7 @@ external object JsSodiumInterface {
// ---- SecretBox ---- // ---- SecretBox ----
@JsName("crypto_secretbox_detached") @JsName("crypto_secretbox_detached")
fun crypto_secretbox_detached(message: Uint8Array, nonce: Uint8Array, key: Uint8Array) : JsAny fun crypto_secretbox_detached(message: Uint8Array, nonce: Uint8Array, key: Uint8Array) : CryptoSecretboxDetachedResult
@JsName("crypto_secretbox_easy") @JsName("crypto_secretbox_easy")
fun crypto_secretbox_easy(message: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array fun crypto_secretbox_easy(message: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
@JsName("crypto_secretbox_keygen") @JsName("crypto_secretbox_keygen")

View File

@ -26,12 +26,12 @@ actual object PasswordHash {
throw RuntimeException("Javascript doesnt support more than ${UInt.MAX_VALUE} for opslimit") throw RuntimeException("Javascript doesnt support more than ${UInt.MAX_VALUE} for opslimit")
} }
return getSodium().crypto_pwhash( return getSodium().crypto_pwhash(
outputLength.toUInt(), outputLength.toLong(),
password.encodeToUByteArray().toUInt8Array(), password.encodeToUByteArray().toUInt8Array(),
salt.toUInt8Array(), salt.toUInt8Array(),
opsLimit.toUInt(), opsLimit.toLong(),
memLimit.toUInt(), memLimit.toLong(),
algorithm.toUInt() algorithm.toLong()
).toUByteArray() ).toUByteArray()
} }
@ -51,8 +51,8 @@ actual object PasswordHash {
} }
return getSodium().crypto_pwhash_str( return getSodium().crypto_pwhash_str(
password.encodeToUByteArray().toUInt8Array(), password.encodeToUByteArray().toUInt8Array(),
opslimit.toUInt(), opslimit.toLong(),
memlimit.toUInt() memlimit.toLong()
) )
} }
@ -73,8 +73,8 @@ actual object PasswordHash {
return if ( return if (
getSodium().crypto_pwhash_str_needs_rehash( getSodium().crypto_pwhash_str_needs_rehash(
passwordHash, passwordHash,
opslimit.toUInt(), opslimit.toLong(),
memlimit.toUInt() memlimit.toLong()
) )
) { ) {
1 1

View File

@ -42,8 +42,8 @@ actual object SecretBox {
key.toUInt8Array() key.toUInt8Array()
) )
return SecretBoxEncryptedDataAndTag( return SecretBoxEncryptedDataAndTag(
(result.cipher as Uint8Array).toUByteArray(), result.cipher.toUByteArray(),
(result.mac as Uint8Array).toUByteArray() result.mac.toUByteArray()
) )
} }

View File

@ -5,12 +5,14 @@ import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import org.khronos.webgl.Uint8Array import org.khronos.webgl.Uint8Array
actual typealias SecretStreamState = Any external object SecretStreamStateType: JsAny
actual typealias SecretStreamState = SecretStreamStateType
actual object SecretStream { actual object SecretStream {
actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader { actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader {
val state = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) val state = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array())
return SecretStreamStateAndHeader(state.state, (state.header as Uint8Array).toUByteArray()) return SecretStreamStateAndHeader(state.state as SecretStreamState, state.header.toUByteArray())
} }
actual fun xChaCha20Poly1305Push( actual fun xChaCha20Poly1305Push(
@ -20,7 +22,7 @@ actual object SecretStream {
tag: UByte tag: UByte
): UByteArray { ): UByteArray {
return getSodium().crypto_secretstream_xchacha20poly1305_push( return getSodium().crypto_secretstream_xchacha20poly1305_push(
state, message.toUInt8Array(), associatedData.toUInt8Array(), tag state, message.toUInt8Array(), associatedData.toUInt8Array(), tag.toInt()
).toUByteArray() ).toUByteArray()
} }
@ -29,7 +31,7 @@ actual object SecretStream {
header: UByteArray header: UByteArray
): SecretStreamStateAndHeader { ): SecretStreamStateAndHeader {
val state = getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), key.toUInt8Array()) val state = getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), key.toUInt8Array())
return SecretStreamStateAndHeader(state, header) return SecretStreamStateAndHeader(state as SecretStreamState, header)
} }
actual fun xChaCha20Poly1305Pull( actual fun xChaCha20Poly1305Pull(
@ -40,10 +42,12 @@ actual object SecretStream {
val dataAndTag = getSodium().crypto_secretstream_xchacha20poly1305_pull( val dataAndTag = getSodium().crypto_secretstream_xchacha20poly1305_pull(
state, ciphertext.toUInt8Array(), associatedData.toUInt8Array() state, ciphertext.toUInt8Array(), associatedData.toUInt8Array()
) )
if (dataAndTag == false) { // TODO: cast definitely will succeed (i hope),
// but it needs to be checked \/ i'm not sure about this move
if (dataAndTag as Boolean == false) {
throw SecretStreamCorruptedOrTamperedDataException() throw SecretStreamCorruptedOrTamperedDataException()
} }
return DecryptedDataAndTag((dataAndTag.message as Uint8Array).toUByteArray(), dataAndTag.tag) return DecryptedDataAndTag(dataAndTag.message.toUByteArray(), dataAndTag.tag.toUByte())
} }