Merge pull request #51 from ReneeVandervelde/return-codes

Use single shared method for return code checking.
This commit is contained in:
Ugljesa Jovanovic 2024-07-02 21:07:00 +02:00 committed by GitHub
commit 4ff2dddf14
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 89 additions and 53 deletions

View File

@ -1,11 +1,19 @@
package com.ionspin.kotlin.crypto
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
class GeneralLibsodiumException : RuntimeException("Libsodium reported error! Returned value was -1") {
companion object {
/**
* Throws a [GeneralLibsodiumException] if the return code is not
* successful.
*
* This will throw an [IllegalStateException] if the return code is invalid/unknown.
*/
fun Int.ensureLibsodiumSuccess() {
if (this == -1) {
if (!isLibsodiumSuccessCode()) {
throw GeneralLibsodiumException()
}
}
}
}
}

View File

@ -36,3 +36,16 @@ fun UByteArray.hexColumnsPrint(chunk: Int = 16) {
val printout = this.map { it.toString(16).padStart(2, '0') }.chunked(chunk)
printout.forEach { println(it.joinToString(separator = " ") { it.uppercase() }) }
}
/**
* Functions returning an int return 0 on success and -1 to indicate an error.
*
* This will throw an [IllegalStateException] if the return code is invalid/unknown.
*/
fun Int.isLibsodiumSuccessCode(): Boolean {
return when (this) {
0 -> true
-1 -> false
else -> throw IllegalStateException("Libsodium returned an unexpected return code $this")
}
}

View File

@ -161,7 +161,7 @@ interface JnaLibsodiumInterface : Library {
bin: ByteArray,
binLength: Int,
variant: Int
): Int
)
// int sodium_base642bin(
// unsigned char * const bin, const size_t bin_maxlen,
@ -274,7 +274,7 @@ interface JnaLibsodiumInterface : Library {
fun crypto_shorthash(out: ByteArray, input: ByteArray, inlen: Long, key: ByteArray): Int
// void crypto_shorthash_keygen(unsigned char k[crypto_shorthash_KEYBYTES])
fun crypto_shorthash_keygen(key: ByteArray): Int
fun crypto_shorthash_keygen(key: ByteArray)
//
// ---- Short hash end ----

View File

@ -2,6 +2,7 @@ package com.ionspin.kotlin.crypto.aead
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
actual object AuthenticatedEncryptionWithAssociatedData {
@ -47,7 +48,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
nonce.asByteArray(),
key.asByteArray(),
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}
return message
@ -95,7 +96,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
nonce.asByteArray(),
key.asByteArray(),
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}
return message
@ -140,7 +141,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
nonce.asByteArray(),
key.asByteArray(),
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}
return message
@ -188,7 +189,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
nonce.asByteArray(),
key.asByteArray(),
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}
return message
@ -233,7 +234,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
nonce.asByteArray(),
key.asByteArray(),
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}
return message
@ -281,7 +282,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
nonce.asByteArray(),
key.asByteArray(),
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}
return message

View File

@ -2,6 +2,7 @@ package com.ionspin.kotlin.crypto.auth
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
actual object Auth {
actual fun authKeygen(): UByteArray {
@ -27,7 +28,7 @@ actual object Auth {
message.asByteArray(),
message.size.toLong(),
key.asByteArray()
) == 0
).isLibsodiumSuccessCode()
}
actual fun authHmacSha256Keygen(): UByteArray {
@ -57,7 +58,7 @@ actual object Auth {
message.asByteArray(),
message.size.toLong(),
key.asByteArray()
) == 0
).isLibsodiumSuccessCode()
}
actual fun authHmacSha512Keygen(): UByteArray {
@ -87,7 +88,7 @@ actual object Auth {
message.asByteArray(),
message.size.toLong(),
key.asByteArray()
) == 0
).isLibsodiumSuccessCode()
}
}

View File

@ -2,6 +2,7 @@ package com.ionspin.kotlin.crypto.box
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
actual object Box {
/**
@ -73,7 +74,7 @@ actual object Box {
sendersPublicKey.asByteArray(),
recipientsSecretKey.asByteArray()
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw BoxCorruptedOrTamperedDataException()
}
@ -128,7 +129,7 @@ actual object Box {
precomputedKey.asByteArray()
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw BoxCorruptedOrTamperedDataException()
}
@ -188,7 +189,7 @@ actual object Box {
recipientsSecretKey.asByteArray()
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw BoxCorruptedOrTamperedDataException()
}
@ -216,7 +217,7 @@ actual object Box {
recipientsSecretKey.asByteArray()
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw BoxCorruptedOrTamperedDataException()
}

View File

@ -2,6 +2,7 @@ package com.ionspin.kotlin.crypto.pwhash
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
actual object PasswordHash {
/**
@ -88,7 +89,7 @@ actual object PasswordHash {
password.length.toLong()
)
return result == 0
return result.isLibsodiumSuccessCode()
}
}

View File

@ -2,6 +2,7 @@ package com.ionspin.kotlin.crypto.secretbox
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
actual object SecretBox {
actual fun easy(message: UByteArray, nonce: UByteArray, key: UByteArray): UByteArray {
@ -29,7 +30,7 @@ actual object SecretBox {
nonce.asByteArray(),
key.asByteArray()
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey()
}
return decrypted
@ -68,7 +69,7 @@ actual object SecretBox {
nonce.asByteArray(),
key.asByteArray()
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey()
}
return message

View File

@ -3,6 +3,7 @@ package com.ionspin.kotlin.crypto.secretstream
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import com.ionspin.kotlin.crypto.SecretStreamXChaCha20Poly1305State
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
actual typealias SecretStreamState = SecretStreamXChaCha20Poly1305State
@ -60,7 +61,7 @@ actual object SecretStream {
associatedData.asByteArray(),
associatedData.size.toLong()
)
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw SecretStreamCorruptedOrTamperedDataException()
}
return DecryptedDataAndTag(result, tagArray[0])

View File

@ -20,7 +20,7 @@ actual object ShortHash {
actual fun shortHashKeygen(): UByteArray {
val key = UByteArray(crypto_shorthash_KEYBYTES)
sodiumJna.crypto_shorthash_keygen(key.asByteArray()).ensureLibsodiumSuccess()
sodiumJna.crypto_shorthash_keygen(key.asByteArray())
return key
}

View File

@ -3,6 +3,7 @@ package com.ionspin.kotlin.crypto.signature
import com.ionspin.kotlin.crypto.Ed25519SignatureState
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
actual typealias SignatureState = Ed25519SignatureState
@ -39,7 +40,7 @@ actual object Signature {
signature.asByteArray(),
publicKey.asByteArray()
)
if (verificationResult == -1) {
if (!verificationResult.isLibsodiumSuccessCode()) {
throw InvalidSignatureException()
}
}
@ -108,7 +109,7 @@ actual object Signature {
signedMessage.size.toLong(),
publicKey.asByteArray()
)
if (verificationResult == -1) {
if (!verificationResult.isLibsodiumSuccessCode()) {
throw InvalidSignatureException()
}
return message
@ -150,7 +151,7 @@ actual object Signature {
publicKey.asByteArray()
)
if (verificationResult == -1) {
if (!verificationResult.isLibsodiumSuccessCode()) {
throw InvalidSignatureException()
}
}

View File

@ -9,7 +9,7 @@ actual object LibsodiumUtil {
if (first.size != second.size) {
throw RuntimeException("Sodium memcmp() only supports comparing same length arrays")
}
return sodiumJna.sodium_memcmp(first.asByteArray(), second.asByteArray(), first.size) == 0
return sodiumJna.sodium_memcmp(first.asByteArray(), second.asByteArray(), first.size).isLibsodiumSuccessCode()
}
actual fun memzero(target: UByteArray) {
@ -34,7 +34,7 @@ actual object LibsodiumUtil {
blocksize,
newSize
)
if (resultCode != 0) {
if (!resultCode.isLibsodiumSuccessCode()) {
throw RuntimeException("Padding failed")
}
@ -71,7 +71,7 @@ actual object LibsodiumUtil {
data.asByteArray(),
data.size,
variant.value
).ensureLibsodiumSuccess()
)
//Drop terminating char \0
return String(result.sliceArray(0 until result.size - 1))
}
@ -104,7 +104,7 @@ actual object LibsodiumUtil {
binLenReference.pointer,
null
)
if (resultCode != 0) {
if (!resultCode.isLibsodiumSuccessCode()) {
throw ConversionException()
}
return result.slice(0 until binLenReference.value).toByteArray().asUByteArray()
@ -129,7 +129,7 @@ actual object LibsodiumUtil {
variant.value
)
if (resultCode != 0) {
if (!resultCode.isLibsodiumSuccessCode()) {
throw ConversionException()
}

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.aead
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -94,7 +95,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
noncePinned.unpin()
keyPinned.unpin()
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}
@ -177,7 +178,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
noncePinned.unpin()
keyPinned.unpin()
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}
@ -253,7 +254,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
noncePinned.unpin()
keyPinned.unpin()
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}
@ -336,7 +337,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
noncePinned.unpin()
keyPinned.unpin()
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}
@ -412,7 +413,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
noncePinned.unpin()
keyPinned.unpin()
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}
@ -495,7 +496,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
noncePinned.unpin()
keyPinned.unpin()
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw AeadCorrupedOrTamperedDataException()
}

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.auth
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -58,7 +59,7 @@ actual object Auth {
keyPinned.unpin()
messagePinned.unpin()
macPinned.unpin()
return verify == 0
return verify.isLibsodiumSuccessCode()
}
actual fun authHmacSha256Keygen(): UByteArray {
@ -109,7 +110,7 @@ actual object Auth {
keyPinned.unpin()
messagePinned.unpin()
macPinned.unpin()
return verify == 0
return verify.isLibsodiumSuccessCode()
}
actual fun authHmacSha512Keygen(): UByteArray {
@ -160,7 +161,7 @@ actual object Auth {
keyPinned.unpin()
messagePinned.unpin()
macPinned.unpin()
return verify == 0
return verify.isLibsodiumSuccessCode()
}
}

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.box
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -124,7 +125,7 @@ actual object Box {
sendersPublicKeyPinned.unpin()
recipientsSecretKeyPinned.unpin()
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw BoxCorruptedOrTamperedDataException()
}
@ -212,7 +213,7 @@ actual object Box {
noncePinned.unpin()
precomputedKeyPinned.unpin()
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw BoxCorruptedOrTamperedDataException()
}
@ -301,7 +302,7 @@ actual object Box {
recipientsSecretKeyPinned.unpin()
sendersPublicKeyPinned.unpin()
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw BoxCorruptedOrTamperedDataException()
}
@ -351,7 +352,7 @@ actual object Box {
recipientsPublicKeyPinned.unpin()
recipientsSecretKeyPinned.unpin()
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw BoxCorruptedOrTamperedDataException()
}
@ -359,4 +360,4 @@ actual object Box {
}
}
}

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.pwhash
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.convert
@ -44,7 +45,7 @@ actual object PasswordHash {
)
saltPinned.unpin()
hashedPasswordPinned.unpin()
if (hashingResult != 0) {
if (!hashingResult.isLibsodiumSuccessCode()) {
throw PasswordHashingFailed()
}
@ -108,7 +109,7 @@ actual object PasswordHash {
password,
password.length.convert()
)
return result == 0
return result.isLibsodiumSuccessCode()
}
}

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.secretbox
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -52,7 +53,7 @@ actual object SecretBox {
messagePinned.unpin()
noncePinned.unpin()
keyPinned.unpin()
if (verificationResult != 0) {
if (!verificationResult.isLibsodiumSuccessCode()) {
throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey()
}
return message
@ -110,7 +111,7 @@ actual object SecretBox {
messagePinned.unpin()
noncePinned.unpin()
keyPinned.unpin()
if (verificationResult != 0) {
if (!verificationResult.isLibsodiumSuccessCode()) {
throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey()
}
return message

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.secretstream
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -116,7 +117,7 @@ actual object SecretStream {
messagePinned.unpin()
associatedDataPinned?.unpin()
tagPinned.unpin()
if (validationResult != 0) {
if (!validationResult.isLibsodiumSuccessCode()) {
throw SecretStreamCorruptedOrTamperedDataException()
}
return DecryptedDataAndTag(message, tag[0])

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.signature
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -74,7 +75,7 @@ actual object Signature {
signaturePinned.unpin()
publicKeyPinned.unpin()
if (verificationResult == -1) {
if (!verificationResult.isLibsodiumSuccessCode()) {
throw InvalidSignatureException()
}
}
@ -162,7 +163,7 @@ actual object Signature {
messagePinned.unpin()
signedMessagePinned.unpin()
publicKeyPinned.unpin()
if (verificationResult == -1) {
if (!verificationResult.isLibsodiumSuccessCode()) {
throw InvalidSignatureException()
}
return message
@ -214,7 +215,7 @@ actual object Signature {
messagePinned.unpin()
publicKeyPinned.unpin()
if (verificationResult == -1) {
if (!verificationResult.isLibsodiumSuccessCode()) {
throw InvalidSignatureException()
}
}

View File

@ -1,6 +1,7 @@
package com.ionspin.kotlin.crypto.util
import com.ionspin.kotlin.crypto.GeneralLibsodiumException.Companion.ensureLibsodiumSuccess
import com.ionspin.kotlin.crypto.util.isLibsodiumSuccessCode
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
@ -30,7 +31,7 @@ actual object LibsodiumUtil {
val result = sodium_memcmp(firstPinned.toPtr(), secondPinned.toPtr(), first.size.convert())
firstPinned.unpin()
secondPinned.unpin()
return result == 0
return result.isLibsodiumSuccessCode()
}
actual fun memzero(target: UByteArray) {