From 5df6143c75eb8dbba4ece115de29819d5d04de74 Mon Sep 17 00:00:00 2001 From: sergeych Date: Tue, 25 Jun 2024 10:39:00 +0700 Subject: [PATCH] adopted crypto2 0.4.* --- build.gradle.kts | 3 ++- .../net/sergeych/kiloparsec/KiloClient.kt | 9 +++++---- .../kiloparsec/KiloClientConnection.kt | 9 +++++---- .../net/sergeych/kiloparsec/KiloParams.kt | 6 +++--- .../net/sergeych/kiloparsec/KiloScope.kt | 7 ++++--- .../net/sergeych/kiloparsec/KiloServer.kt | 2 +- .../kiloparsec/KiloServerConnection.kt | 4 ++-- .../kiloparsec/adapter/websocketClient.kt | 2 +- .../net/sergeych/kiloparsec/commands.kt | 4 ++-- src/commonTest/kotlin/KeysTest.kt | 13 ++++++++----- src/commonTest/kotlin/ToolsTest.kt | 19 ------------------- src/commonTest/kotlin/TransportTest.kt | 9 +++++---- .../kiloparsec/adapter/WebsocketServer.kt | 2 +- .../kiloparsec/adapter/asyncSocketToDevice.kt | 14 +++++++------- 14 files changed, 46 insertions(+), 57 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 12d3b9b..f25c40e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -44,6 +44,7 @@ kotlin { // iosArm64() // iosSimulatorArm64() linuxX64() + linuxArm64() // macosX64() @@ -66,7 +67,7 @@ kotlin { // api("net.sergeych:mp_bintools:0.1.1") // api("net.sergeych:mp_stools:1.4.7") - api("net.sergeych:crypto2:0.2.2-SNAPSHOT") + api("net.sergeych:crypto2:0.4.1-SNAPSHOT") } } val commonTest by getting { diff --git a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloClient.kt b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloClient.kt index 5ce02c9..e99e936 100644 --- a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloClient.kt +++ b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloClient.kt @@ -9,6 +9,7 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import net.sergeych.crypto2.SigningKey +import net.sergeych.crypto2.VerifyingPublicKey import net.sergeych.mp_logger.LogTag import net.sergeych.mp_logger.Loggable import net.sergeych.mp_logger.debug @@ -23,7 +24,7 @@ import net.sergeych.mp_tools.globalLaunch */ class KiloClient( localInterface: KiloInterface, - secretKey: SigningKey.Secret? = null, + secretKey: SigningKey? = null, connectionDataFactory: ConnectionDataFactory, ) : RemoteInterface, Loggable by LogTag("CLIF") { @@ -101,14 +102,14 @@ class KiloClient( suspend fun token() = deferredClient.await().token() /** - * Remote party shared key ([SigningKey.Public]]), could be used ti ensure server is what we expected and + * Remote party shared key ([VerifyingPublicKey]), could be used ti ensure server is what we expected and * there is no active MITM attack. * * Non-null value means the key was successfully authenticated, null means remote party did not provide * a key. Connection is established either with a properly authenticated key or no key at all. */ @Suppress("unused") - suspend fun remoteId() = deferredClient.await().remoteId() + suspend fun remoteId(): VerifyingPublicKey? = deferredClient.await().remoteId() companion object { class Builder() { @@ -120,7 +121,7 @@ class KiloClient( } private var connectionBuilder: (suspend () -> Transport.Device)? = null - var secretIdKey: SigningKey.Secret? = null + var secretIdKey: SigningKey? = null /** * Build local command implementations (remotely callable ones), exception diff --git a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloClientConnection.kt b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloClientConnection.kt index 9acccce..02396c9 100644 --- a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloClientConnection.kt +++ b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloClientConnection.kt @@ -3,6 +3,7 @@ package net.sergeych.kiloparsec import kotlinx.coroutines.* import net.sergeych.crypto2.SafeKeyExchange import net.sergeych.crypto2.SigningKey +import net.sergeych.crypto2.VerifyingPublicKey import net.sergeych.mp_logger.LogTag import net.sergeych.mp_logger.Loggable import net.sergeych.mp_logger.debug @@ -15,17 +16,17 @@ class KiloClientConnection( private val clientInterface: KiloInterface, private val device: Transport.Device, private val session: S, - private val secretIdKey: SigningKey.Secret? = null, + private val secretIdKey: SigningKey? = null, ) : RemoteInterface, Loggable by LogTag("KPC:${++clientIds}") { - constructor(localInterface: KiloInterface, connection: KiloConnectionData, secretIdKey: SigningKey.Secret? = null) + constructor(localInterface: KiloInterface, connection: KiloConnectionData, secretIdKey: SigningKey? = null) : this(localInterface, connection.device, connection.session, secretIdKey) private val kiloRemoteInterface = CompletableDeferred>() private val deferredParams = CompletableDeferred>() - suspend fun remoteId(): SigningKey.Public? = deferredParams.await().remoteIdentity + suspend fun remoteId(): VerifyingPublicKey? = deferredParams.await().remoteIdentity /** * Run the client, blocking until the device is closed, or some critical exception @@ -69,7 +70,7 @@ class KiloClientConnection( L0ClientId, params.encrypt( pack( ClientIdentity( - secretIdKey?.publicKey, + secretIdKey?.verifyingKey, secretIdKey?.sign(params.token) ) ) diff --git a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloParams.kt b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloParams.kt index 9b3ff33..8777885 100644 --- a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloParams.kt +++ b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloParams.kt @@ -24,7 +24,7 @@ data class KiloParams( val transport: RemoteInterface, val sessionKey: SafeKeyExchange.SessionKey, val scopeSession: S, - val remoteIdentity: SigningKey.Public?, + val remoteIdentity: VerifyingPublicKey?, val remoteTransport: RemoteInterface, ) { @Serializable @@ -41,12 +41,12 @@ data class KiloParams( override val session = scopeSession override val remote: RemoteInterface = remoteTransport override val sessionToken: UByteArray = token - override val remoteIdentity: SigningKey.Public? = this@KiloParams.remoteIdentity + override val remoteIdentity: VerifyingPublicKey? = this@KiloParams.remoteIdentity } } val token: UByteArray by lazy { - blake2b("token_".encodeToUByteArray() + sessionKey.sessionTag).sliceArray(0.. { val sessionToken: UByteArray /** - * If the remote part has provided a secret key, e.g., gave non-null [SigningKey.Secret] on construction, - * the kiloparsec checks it in the MITM-safe way and provides its [SigningKey.Public] shared key here. + * If the remote part has provided a secret key, e.g., gave non-null [SigningKey] on construction, + * the kiloparsec checks it in the MITM-safe way and provides its [VerifyingPublicKey] shared key here. * Knowing a remote party shared key, it is possible to be sure that the connection is made directly * to this party with no middle point intruders. * @@ -37,6 +38,6 @@ interface KiloScope { * In spite of the above said, which means, non-null value in this field means the key is authorized, but * It is up to the caller to ensure it is expected key of the remote party. */ - val remoteIdentity: SigningKey.Public? + val remoteIdentity: VerifyingPublicKey? } diff --git a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloServer.kt b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloServer.kt index 4fa4e95..f889bb4 100644 --- a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloServer.kt +++ b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloServer.kt @@ -17,7 +17,7 @@ private val instances = AtomicCounter() class KiloServer( private val clientInterface: KiloInterface, private val connections: Flow, - private val serverSecretKey: SigningKey.Secret? = null, + private val serverSecretKey: SigningKey? = null, private val sessionBuilder: ()->S, ): LogTag("KS:${instances.incrementAndGet()}") { diff --git a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloServerConnection.kt b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloServerConnection.kt index 3c71eb7..654eae0 100644 --- a/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloServerConnection.kt +++ b/src/commonMain/kotlin/net/sergeych/kiloparsec/KiloServerConnection.kt @@ -23,14 +23,14 @@ class KiloServerConnection( private val clientInterface: KiloInterface, private val device: Transport.Device, private val session: S, - private val serverSigningKey: SigningKey.Secret? = null + private val serverSigningKey: SigningKey? = null ) : RemoteInterface, Loggable by LogTag("SRV${++serverIds}") { /** * Shortcut to construct with [KiloConnectionData] intance */ @Suppress("unused") - constructor(localInterface: KiloInterface, connection: KiloConnectionData, serverSecretKey: SigningKey.Secret? = null) + constructor(localInterface: KiloInterface, connection: KiloConnectionData, serverSecretKey: SigningKey? = null) : this(localInterface, connection.device, connection.session, serverSecretKey) private val kiloRemoteInterface = CompletableDeferred>() diff --git a/src/commonMain/kotlin/net/sergeych/kiloparsec/adapter/websocketClient.kt b/src/commonMain/kotlin/net/sergeych/kiloparsec/adapter/websocketClient.kt index 145e0c5..5f93f0b 100644 --- a/src/commonMain/kotlin/net/sergeych/kiloparsec/adapter/websocketClient.kt +++ b/src/commonMain/kotlin/net/sergeych/kiloparsec/adapter/websocketClient.kt @@ -28,7 +28,7 @@ fun websocketClient( path: String, clientInterface: KiloInterface = KiloInterface(), client: HttpClient = HttpClient { install(WebSockets) }, - secretKey: SigningKey.Secret? = null, + secretKey: SigningKey? = null, sessionMaker: () -> S = { @Suppress("UNCHECKED_CAST") Unit as S diff --git a/src/commonMain/kotlin/net/sergeych/kiloparsec/commands.kt b/src/commonMain/kotlin/net/sergeych/kiloparsec/commands.kt index d4d2535..50ab94b 100644 --- a/src/commonMain/kotlin/net/sergeych/kiloparsec/commands.kt +++ b/src/commonMain/kotlin/net/sergeych/kiloparsec/commands.kt @@ -3,7 +3,7 @@ package net.sergeych.kiloparsec import kotlinx.serialization.Serializable import net.sergeych.crypto2.SafeKeyExchange import net.sergeych.crypto2.Seal -import net.sergeych.crypto2.SigningKey +import net.sergeych.crypto2.VerifyingPublicKey // L0 commands - key exchange and check: @Serializable @@ -11,7 +11,7 @@ data class Handshake(val version: UInt, val publicKey: SafeKeyExchange.PublicKey val signature: Seal? = null) @Serializable -data class ClientIdentity(val clientIdKey: SigningKey.Public?, val signature: UByteArray?) +data class ClientIdentity(val clientIdKey: VerifyingPublicKey?, val signature: UByteArray?) // Level 0 command: request key exchange internal val L0Request by command() diff --git a/src/commonTest/kotlin/KeysTest.kt b/src/commonTest/kotlin/KeysTest.kt index bd1d807..60aef56 100644 --- a/src/commonTest/kotlin/KeysTest.kt +++ b/src/commonTest/kotlin/KeysTest.kt @@ -1,5 +1,8 @@ import kotlinx.coroutines.test.runTest -import net.sergeych.crypto2.* +import net.sergeych.crypto2.IllegalSignatureException +import net.sergeych.crypto2.SealedBox +import net.sergeych.crypto2.SigningSecretKey +import net.sergeych.crypto2.initCrypto import net.sergeych.kiloparsec.encodeToUByteArray import net.sergeych.utools.pack import net.sergeych.utools.unpack @@ -9,11 +12,11 @@ class KeysTest { @Test fun testCreationAndMap() = runTest { initCrypto() - val (stk,pbk) = SigningKey.pair() + val (stk,pbk) = SigningSecretKey.generatePair() val x = mapOf( stk to "STK!", pbk to "PBK!") assertEquals("STK!", x[stk]) - val s1 = SigningKey.Secret(stk.packed) + val s1 = SigningSecretKey(stk.keyBytes) assertEquals(stk, s1) assertEquals("STK!", x[s1]) assertEquals("PBK!", x[pbk]) @@ -25,8 +28,8 @@ class KeysTest { data1[0] = 0x01u assertFalse(s.isValid(data1)) - val p2 = SigningKey.pair() - val p3 = SigningKey.pair() + val p2 = SigningSecretKey.generatePair() + val p3 = SigningSecretKey.generatePair() val ms = SealedBox(data, s1) + p2.secretKey diff --git a/src/commonTest/kotlin/ToolsTest.kt b/src/commonTest/kotlin/ToolsTest.kt index f2a9ba5..506a868 100644 --- a/src/commonTest/kotlin/ToolsTest.kt +++ b/src/commonTest/kotlin/ToolsTest.kt @@ -1,23 +1,4 @@ -import kotlinx.coroutines.test.runTest -import net.sergeych.crypto2.createContrail -import net.sergeych.crypto2.initCrypto -import net.sergeych.crypto2.isValidContrail -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertTrue - class ToolsTest { - @Test - fun testContrails() = runTest { - initCrypto() - val c = createContrail(ubyteArrayOf(1u, 2u, 3u, 4u, 5u)) - assertEquals(134u, c[0]) - assertTrue { isValidContrail(c) } - c[2] = 11u - assertFalse { isValidContrail(c) } - } - // @Test // fun testRemoceCmd() { // assertEquals("lalala", removeCmd("lalala")) diff --git a/src/commonTest/kotlin/TransportTest.kt b/src/commonTest/kotlin/TransportTest.kt index 3892b29..818264d 100644 --- a/src/commonTest/kotlin/TransportTest.kt +++ b/src/commonTest/kotlin/TransportTest.kt @@ -3,7 +3,8 @@ import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.test.runTest -import net.sergeych.crypto2.SigningKey +import net.sergeych.crypto2.SigningSecretKey +import net.sergeych.crypto2.VerifyingPublicKey import net.sergeych.crypto2.initCrypto import net.sergeych.kiloparsec.* import net.sergeych.mp_logger.Log @@ -167,7 +168,7 @@ class TransportTest { val cmdPing by command() val cmdPush by command() val cmdGetToken by command() - val cmdGetClientId by command() + val cmdGetClientId by command() val cmdChainCallServer1 by command() val cmdChainCallClient1 by command() val cmdChainCallServer2 by command() @@ -176,8 +177,8 @@ class TransportTest { // Log.defaultLevel = Log.Level.DEBUG val (d1, d2) = createTestDevice() - val serverId = SigningKey.pair() - val clientId = SigningKey.pair() + val serverId = SigningSecretKey.generatePair() + val clientId = SigningSecretKey.generatePair() val cmdException by command() val cmdRemoteExceptionTest by command() diff --git a/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/WebsocketServer.kt b/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/WebsocketServer.kt index 8a8ed5f..a5d89d6 100644 --- a/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/WebsocketServer.kt +++ b/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/WebsocketServer.kt @@ -21,7 +21,7 @@ import java.time.Duration fun Application.setupWebsocketServer( localInterface: KiloInterface, path: String = "/kp", - serverKey: SigningKey.Secret? = null, + serverKey: SigningKey? = null, createSession: () -> S, ) { diff --git a/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/asyncSocketToDevice.kt b/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/asyncSocketToDevice.kt index c3839c4..cfc2101 100644 --- a/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/asyncSocketToDevice.kt +++ b/src/jvmMain/kotlin/net/sergeych/kiloparsec/adapter/asyncSocketToDevice.kt @@ -4,12 +4,12 @@ import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.ClosedReceiveChannelException import kotlinx.coroutines.flow.MutableStateFlow +import net.sergeych.crypto2.Contrail import net.sergeych.crypto2.encodeVarUnsigned import net.sergeych.crypto2.readVarUnsigned import net.sergeych.kiloparsec.RemoteInterface import net.sergeych.kiloparsec.Transport import net.sergeych.mp_logger.LogTag -import net.sergeych.mp_logger.info import net.sergeych.mp_logger.warning import net.sergeych.mp_tools.globalLaunch import net.sergeych.tools.waitFor @@ -25,7 +25,10 @@ private val log = LogTag("ASTD") /** * Prepend block with its size, varint-encoded */ -private fun encode(block: UByteArray): ByteArray = (encodeVarUnsigned(block.size.toUInt()) + block).toByteArray() +private fun encode(block: UByteArray): ByteArray { + val c = Contrail.create(block) + return (encodeVarUnsigned(c.size.toUInt()) + c).toByteArray() +} /** * Convert asynchronous socket to a [Transport.Device] using non-blocking nio, @@ -122,7 +125,8 @@ suspend fun asyncSocketToDevice(socket: AsynchronousSocketChannel): InetTranspor for (i in 0..