Skip to content

Commit

Permalink
Merge pull request #8 from ionspin/jna-android-and-java
Browse files Browse the repository at this point in the history
Jna android and java
  • Loading branch information
ionspin committed Feb 24, 2021
2 parents 5228614 + e18f7d3 commit 6db7a82
Show file tree
Hide file tree
Showing 46 changed files with 1,901 additions and 344 deletions.
46 changes: 24 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,34 @@

# Libsodium bindings for Kotiln Multiplatform

Libsodium bindings project uses libsodium c sources, libsodium.js as well as LazySodium Java and Android to provide a kotlin multiplatform wrapper library for libsodium.
Libsodium bindings project uses libsodium c sources and libsodium.js to provide a kotlin multiplatform wrapper library for libsodium.

## Installation

The libsodium binding library is not published yet, once the sample showing the basic usage is ready, the library will be published. You can track the implementation
[progress here](https://github.com/ionspin/kotlin-multiplatform-crypto/blob/master/supported_bindings_list.md)
#### Gradle
```kotlin
implementation("com.ionspin.kotlin:multiplatform-crypto-lisodium-bindings:0.8.0")
```

#### Snapshot builds
```kotlin
repositories {
maven {
url = uri("https://oss.sonatype.org/content/repositories/snapshots")
}
}
implementation("com.ionspin.kotlin:multiplatform-crypto-lisodium-bindings:0.8.1-SNAPSHOT ")

```



## Usage

Before using the wrapper you need to initialize the underlying libsodium library. You can use either a callback or coroutines approach

```
= runTest {
LibsodiumInitializer.initializeWithCallback {
LibsodiumInitializer.initializeWithCallback {
// Libsodium initialized
}
```
Expand Down Expand Up @@ -125,31 +138,20 @@ Currently supported native platforms:
|minGW X86 64| :heavy_check_mark: |
|minGW X86 32| :x: |

[List of supported bindings](https://github.com/ionspin/kotlin-multiplatform-crypto/blob/master/supported_bindings_list.md)
### Where do the compiled libraries used by JVM and Android come from
Android .so files come from running dist-build scripts in libsodium which you can find in the libsodium submodule
Java Linux Arm/X86_64 and Mac so and dylib are the same as produced by multiplatform builds, also based on the same submodule commit
Java Windows dll is from https://download.libsodium.org/libsodium/releases/libsodium-1.0.18-stable-msvc.zip


### TODO:
- Copy/adapt code documentation, currently only some functions have documentation that is a copy-paste from libsodium website
- Replace LazySodium with direct JNA calls, and add build scripts for required libraries if missing
- Android testing
- Fix browser testing, both locally and in CI/CD
- LobsodiumUtil `unpad` and `fromBase64` native implementations use a nasty hack to support shared native sourceset. The hack either needs to be removed and replaced with another solution or additional safeguards need to be added.
- Complete exposing libsodium constants

### Known issues:
- Using LazySodium self built variant to fix some of the bugs present in LazySodium, but **Android** is using directly
LazySodium release which has not been updated (latest version is 4.2.0), this means that randombytes_random, basetobin and
base64tohex functions are not working on Android, as well as problems with sodium_pad:

https://github.com/terl/lazysodium-java/issues/83

https://github.com/terl/lazysodium-java/issues/85

https://github.com/terl/lazysodium-java/issues/86

Also it is not clear where are the precompiled libraries in LazySodium coming from

This will be handled by providing a new JNA libsodium wrapper library



#### Notes for Gitlab runners:
- At the moment all runners need to have android sdk
Expand Down
15 changes: 8 additions & 7 deletions buildSrc/src/main/kotlin/Deps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,24 @@ object Versions {
val dokkaPlugin = "1.4.20"
val taskTreePlugin = "1.5"
val kotlinBigNumVersion = "0.2.8-SNAPSHOT"
val lazySodium = "4.3.1-SNAPSHOT"
val jna = "5.5.0"
val jna = "5.7.0"
val kotlinPoet = "1.6.0"
val libsodiumBindings = "0.1.1-SNAPSHOT"
val ktor = "1.3.2"
val timber = "4.7.1"
val kodeinVersion = "7.1.0"

val resourceLoader = "1.3.10"




}

object ReleaseInfo {
val group = "com.ionspin.kotlin"
val version = "0.1.0-SNAPSHOT"
val bindingsVersion = "0.1.1-SNAPSHOT"
val bindingsVersion = "0.8.0-SNAPSHOT"
}

object Deps {
Expand Down Expand Up @@ -112,11 +114,9 @@ object Deps {

val kotlinPoet = "com.squareup:kotlinpoet:${Versions.kotlinPoet}"

val resourceLoader = "co.libly:resource-loader:${Versions.resourceLoader}"

object Delegated {
// Temporary until reported lazysodium issues are fixed. My snapshot build with
// And cause I registered com.ionspin.kotlin as maven central package root now I have to use
// that even though this is pure java library. :)
val lazysodium = "com.ionspin.kotlin:lazysodium-java:${Versions.lazySodium}"
val jna = "net.java.dev.jna:jna:${Versions.jna}"
}
}
Expand All @@ -139,6 +139,7 @@ object Deps {
val ktorClientSerialization = "io.ktor:ktor-client-serialization-jvm:${Versions.ktor}"
val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime:${Versions.kotlinSerialization}"
val timber = "com.jakewharton.timber:timber:${Versions.timber}"
val jna = "net.java.dev.jna:jna:${Versions.jna}@aar"
}

object Desktop {
Expand Down
60 changes: 37 additions & 23 deletions multiplatform-crypto-libsodium-bindings/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ val sonatypeUsernameEnv: String? = System.getenv()["SONATYPE_USERNAME"]
repositories {
mavenCentral()
jcenter()
maven("https://dl.bintray.com/terl/lazysodium-maven")
maven {
url = uri("https://oss.sonatype.org/content/repositories/snapshots")
}
Expand All @@ -73,16 +72,20 @@ android {
isMinifyEnabled = false
}
}
sourceSets.getByName("main") {
// jniLibs.srcDir("src/androidMain/libs")
}
}



kotlin {
val hostOsName = getHostOsName()
android()
jvm()
runningOnLinuxx86_64 {
println("Configuring Linux X86-64 targets")
jvm()

js(IR) {
browser {
testTask {
Expand Down Expand Up @@ -438,14 +441,16 @@ kotlin {

val androidMain by getting {
isNotRunningInIdea {
kotlin.srcDirs("src/androidSpecific", "src/jvmMain/kotlin")
kotlin.srcDirs("src/androidMain", "src/androidSpecific", "src/jvmMain/kotlin")
}
isRunningInIdea {
kotlin.srcDirs("src/androidSpecific")
kotlin.srcDirs("src/androidSpecific", "src/jvmMain/kotlin")
}
dependencies {
implementation("com.goterl.lazycode:lazysodium-android:4.2.0@aar")
implementation("net.java.dev.jna:jna:5.5.0@aar")
implementation(Deps.Jvm.resourceLoader) {
exclude("net.java.dev.jna", "jna")
}
}
}

Expand All @@ -458,28 +463,30 @@ kotlin {
}
}

val jvmMain by getting {
kotlin.srcDirs("src/jvmSpecific", "src/jvmMain/kotlin")
dependencies {
implementation(kotlin(Deps.Jvm.stdLib))
implementation(kotlin(Deps.Jvm.test))
implementation(kotlin(Deps.Jvm.testJUnit))

runningOnLinuxx86_64 {
println("Configuring Linux 64 Bit source sets")
val jvmMain by getting {
kotlin.srcDirs("src/jvmSpecific", "src/jvmMain/kotlin")
dependencies {
implementation(kotlin(Deps.Jvm.stdLib))
implementation(kotlin(Deps.Jvm.test))
implementation(kotlin(Deps.Jvm.testJUnit))
implementation(Deps.Jvm.resourceLoader)

//lazysodium
implementation(Deps.Jvm.Delegated.lazysodium)
implementation(Deps.Jvm.Delegated.jna)
}
implementation(Deps.Jvm.Delegated.jna)

implementation("org.slf4j:slf4j-api:1.7.30")
}
val jvmTest by getting {
dependencies {
implementation(kotlin(Deps.Jvm.test))
implementation(kotlin(Deps.Jvm.testJUnit))
implementation(kotlin(Deps.Jvm.reflection))
}
}
val jvmTest by getting {
dependencies {
implementation(kotlin(Deps.Jvm.test))
implementation(kotlin(Deps.Jvm.testJUnit))
implementation(kotlin(Deps.Jvm.reflection))
}
}
runningOnLinuxx86_64 {
println("Configuring Linux 64 Bit source sets")



val jsMain by getting {
Expand Down Expand Up @@ -678,6 +685,13 @@ tasks {

}

allprojects {
tasks.withType(JavaCompile::class) {
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
}
}



signing {
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,12 +1,2 @@
package com.ionspin.kotlin.crypto

import com.goterl.lazycode.lazysodium.LazySodiumAndroid
import com.goterl.lazycode.lazysodium.SodiumAndroid


/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 22-Aug-2020
*/
typealias SodiumWrapper = SodiumAndroid
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,22 @@ const val crypto_stream_chacha20_KEYBYTES = 32
const val crypto_stream_chacha20_NONCEBYTES = 8
const val crypto_stream_chacha20_ietf_KEYBYTES = 32
const val crypto_stream_chacha20_ietf_NONCEBYTES = 12
const val crypto_stream_xchacha20_NONCEBYTES = 24
const val crypto_stream_xchacha20_KEYBYTES = 32


expect object Stream {
fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray) : UByteArray
fun chacha20IetfXor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray
fun chacha20IetfXorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray
fun chacha20Keygen() : UByteArray

fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray) : UByteArray
fun chacha20Xor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray
fun chacha20XorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray

fun chacha20IetfXor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray
fun chacha20IetfXorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray

// fun xChacha20Keygen() : UByteArray
//
// fun xChacha20Xor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray
// fun xChacha20XorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ enum class Base64Variants(val value: Int) {
ORIGINAL(1), ORIGINAL_NO_PADDING(3), URLSAFE(5), URLSAFE_NO_PADDING(7)
}

class ConversionException() : RuntimeException("Conversion failed")
class PaddingException() : RuntimeException("Padding failed")

expect object LibsodiumUtil {

fun memcmp(first: UByteArray, second: UByteArray) : Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,26 @@ class StreamTest {
}
}
}

// @Test
// fun testXChaCha20IetfStream() = runTest {
// LibsodiumInitializer.initializeWithCallback {
// val message = "This is a cha cha message".encodeToUByteArray()
// val nonce = LibsodiumRandom.bufDeterministic(crypto_stream_xchacha20_NONCEBYTES, seed)
// val key = Stream.xChacha20Keygen()
// val encryptedUsingLibsodium = Stream.xChacha20Xor(message, nonce, key)
// val encryptedUsingLibsodiumWithInitialCounter = Stream.xChacha20XorIc(message, nonce, 0U, key)
// println(encryptedUsingLibsodium.toHexString())
// println(encryptedUsingLibsodiumWithInitialCounter.toHexString())
// assertTrue {
// encryptedUsingLibsodium.contentEquals(encryptedUsingLibsodiumWithInitialCounter)
// }
// val decryptedUsingLibsodium = Stream.xChacha20Xor(encryptedUsingLibsodium, nonce, key)
// println(message.toHexString())
// println(decryptedUsingLibsodium.toHexString())
// assertTrue {
// decryptedUsingLibsodium.contentEquals(message)
// }
// }
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ interface JsSodiumInterface {
fun crypto_stream_chacha20_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
fun crypto_stream_chacha20_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array

fun crypto_stream_xchacha20_keygen() : Uint8Array
fun crypto_stream_xchacha20_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
fun crypto_stream_xchacha20_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array

// ---- Stream end ----

// ---- Scalar multiplication ----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,42 @@ actual object Stream {

return result.toUByteArray()
}

// actual fun xChacha20Keygen(): UByteArray {
// val result = getSodium().crypto_stream_xchacha20_keygen()
//
// return result.toUByteArray()
// }
//
// actual fun xChacha20Xor(
// message: UByteArray,
// nonce: UByteArray,
// key: UByteArray
// ): UByteArray {
// val result = getSodium().crypto_stream_xchacha20_xor(
// message.toUInt8Array(),
// nonce.toUInt8Array(),
// key.toUInt8Array()
// )
//
// return result.toUByteArray()
// }
//
// actual fun xChacha20XorIc(
// message: UByteArray,
// nonce: UByteArray,
// initialCounter: ULong,
// key: UByteArray
// ): UByteArray {
// val result = getSodium().crypto_stream_xchacha20_xor_ic(
// message.toUInt8Array(),
// nonce.toUInt8Array(),
// initialCounter.toUInt(),
// key.toUInt8Array()
// )
//
// return result.toUByteArray()
// }


}
Loading

0 comments on commit 6db7a82

Please sign in to comment.