use top-level Seal class
This commit is contained in:
parent
7042e41d70
commit
67c0009b5b
11
src/commonMain/kotlin/net/sergeych/crypto2/Seal.kt
Normal file
11
src/commonMain/kotlin/net/sergeych/crypto2/Seal.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package net.sergeych.crypto2
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class Seal(
|
||||||
|
val publicKey: SigningKey.Public,
|
||||||
|
val signature: UByteArray
|
||||||
|
) {
|
||||||
|
inline fun verify(message: UByteArray) = publicKey.verify(signature, message)
|
||||||
|
}
|
@ -30,14 +30,14 @@ class SignedBox(
|
|||||||
* _can't assume it always returns a copied object!_
|
* _can't assume it always returns a copied object!_
|
||||||
*/
|
*/
|
||||||
operator fun plus(key: SigningKey.Secret): SignedBox =
|
operator fun plus(key: SigningKey.Secret): SignedBox =
|
||||||
if (key.verifying in this) this
|
if (key.publicKey in this) this
|
||||||
else SignedBox(message, seals + Seal.create(key, message), false)
|
else SignedBox(message, seals + key.seal(message), false)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that it is signed with a specified key.
|
* Check that it is signed with a specified key.
|
||||||
*/
|
*/
|
||||||
operator fun contains(verifyingKey: SigningKey.Public): Boolean {
|
operator fun contains(publicKey: SigningKey.Public): Boolean {
|
||||||
return seals.any { it.key == verifyingKey }
|
return seals.any { it.publicKey == publicKey }
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -47,22 +47,6 @@ class SignedBox(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A key + signature pair for [SignedBox] boxes, usually you don't use it
|
|
||||||
* directly bug call [SignedBox] constructor or [SignedBox.plus] to
|
|
||||||
* add seals.
|
|
||||||
*/
|
|
||||||
@Serializable
|
|
||||||
data class Seal(val key: SigningKey.Public, val signature: UByteArray) {
|
|
||||||
|
|
||||||
fun verify(message: UByteArray): Boolean = key.verify(signature, message)
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun create(key: SigningKey.Secret, message: UByteArray): Seal {
|
|
||||||
return Seal(key.verifying, key.sign(message))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
@ -76,6 +60,6 @@ class SignedBox(
|
|||||||
* @throws IllegalArgumentException if keys are not specified.
|
* @throws IllegalArgumentException if keys are not specified.
|
||||||
*/
|
*/
|
||||||
operator fun invoke(data: UByteArray, vararg keys: SigningKey.Secret): SignedBox =
|
operator fun invoke(data: UByteArray, vararg keys: SigningKey.Secret): SignedBox =
|
||||||
SignedBox(data, keys.map { Seal.create(it, data) }, false)
|
SignedBox(data, keys.map { it.seal(data) }, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -54,11 +54,13 @@ sealed class SigningKey {
|
|||||||
@SerialName("s")
|
@SerialName("s")
|
||||||
class Secret(override val packed: UByteArray) : SigningKey() {
|
class Secret(override val packed: UByteArray) : SigningKey() {
|
||||||
|
|
||||||
val verifying: Public by lazy {
|
val publicKey: Public by lazy {
|
||||||
Public(Signature.ed25519SkToPk(packed))
|
Public(Signature.ed25519SkToPk(packed))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sign(message: UByteArray): UByteArray = Signature.detached(message, packed)
|
fun sign(message: UByteArray): UByteArray = Signature.detached(message, packed)
|
||||||
|
|
||||||
|
fun seal(message: UByteArray): Seal = Seal(this.publicKey, sign(message))
|
||||||
override fun toString(): String = "Sct:${super.toString()}"
|
override fun toString(): String = "Sct:${super.toString()}"
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -59,19 +59,17 @@ class KiloClientConnection<S>(
|
|||||||
var params = KiloParams(false, transport, sk, session, null, this@KiloClientConnection)
|
var params = KiloParams(false, transport, sk, session, null, this@KiloClientConnection)
|
||||||
|
|
||||||
// Check ID if any
|
// Check ID if any
|
||||||
serverHe.serverPublicKey?.let { k ->
|
serverHe.signature?.let { s ->
|
||||||
if (serverHe.signature == null)
|
if (!s.verify(params.token))
|
||||||
throw RemoteInterface.SecurityException("missing signature")
|
|
||||||
if (!k.verify(serverHe.signature, params.token))
|
|
||||||
throw RemoteInterface.SecurityException("wrong signature")
|
throw RemoteInterface.SecurityException("wrong signature")
|
||||||
params = params.copy(remoteIdentity = k)
|
params = params.copy(remoteIdentity = s.publicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
transport.call(
|
transport.call(
|
||||||
L0ClientId, params.encrypt(
|
L0ClientId, params.encrypt(
|
||||||
pack(
|
pack(
|
||||||
ClientIdentity(
|
ClientIdentity(
|
||||||
secretIdKey?.verifying,
|
secretIdKey?.publicKey,
|
||||||
secretIdKey?.sign(params.token)
|
secretIdKey?.sign(params.token)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -60,14 +60,9 @@ class KiloServerConnection<S>(
|
|||||||
this@KiloServerConnection
|
this@KiloServerConnection
|
||||||
)
|
)
|
||||||
|
|
||||||
var public: SigningKey.Public? = null
|
Handshake(1u, pair.publicKey, serverSigningKey?.seal(params!!.token))
|
||||||
var signature: UByteArray? = null
|
|
||||||
if( serverSigningKey != null ) {
|
|
||||||
public = serverSigningKey.verifying
|
|
||||||
signature = serverSigningKey.sign(params!!.token)
|
|
||||||
}
|
|
||||||
Handshake(1u, pair.publicKey, public, signature)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
on(L0ClientId) {
|
on(L0ClientId) {
|
||||||
var p = params ?: throw RemoteInterface.ClosedException("wrong handshake sequence")
|
var p = params ?: throw RemoteInterface.ClosedException("wrong handshake sequence")
|
||||||
val ci = unpack<ClientIdentity>(p.decrypt(it))
|
val ci = unpack<ClientIdentity>(p.decrypt(it))
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package net.sergeych.kiloparsec
|
package net.sergeych.kiloparsec
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import net.sergeych.crypto2.Seal
|
||||||
import net.sergeych.crypto2.SigningKey
|
import net.sergeych.crypto2.SigningKey
|
||||||
|
|
||||||
// L0 commands - key exchange and check:
|
// L0 commands - key exchange and check:
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Handshake(val version: UInt, val publicKey: UByteArray,
|
data class Handshake(val version: UInt, val publicKey: UByteArray,
|
||||||
val serverPublicKey: SigningKey.Public? = null,
|
val signature: Seal? = null)
|
||||||
val signature: UByteArray? = null)
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class ClientIdentity(val clientIdKey: SigningKey.Public?, val signature: UByteArray?)
|
data class ClientIdentity(val clientIdKey: SigningKey.Public?, val signature: UByteArray?)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user