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!_
|
||||
*/
|
||||
operator fun plus(key: SigningKey.Secret): SignedBox =
|
||||
if (key.verifying in this) this
|
||||
else SignedBox(message, seals + Seal.create(key, message), false)
|
||||
if (key.publicKey in this) this
|
||||
else SignedBox(message, seals + key.seal(message), false)
|
||||
|
||||
/**
|
||||
* Check that it is signed with a specified key.
|
||||
*/
|
||||
operator fun contains(verifyingKey: SigningKey.Public): Boolean {
|
||||
return seals.any { it.key == verifyingKey }
|
||||
operator fun contains(publicKey: SigningKey.Public): Boolean {
|
||||
return seals.any { it.publicKey == publicKey }
|
||||
}
|
||||
|
||||
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 {
|
||||
/**
|
||||
@ -76,6 +60,6 @@ class SignedBox(
|
||||
* @throws IllegalArgumentException if keys are not specified.
|
||||
*/
|
||||
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")
|
||||
class Secret(override val packed: UByteArray) : SigningKey() {
|
||||
|
||||
val verifying: Public by lazy {
|
||||
val publicKey: Public by lazy {
|
||||
Public(Signature.ed25519SkToPk(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()}"
|
||||
|
||||
companion object {
|
||||
|
@ -59,19 +59,17 @@ class KiloClientConnection<S>(
|
||||
var params = KiloParams(false, transport, sk, session, null, this@KiloClientConnection)
|
||||
|
||||
// Check ID if any
|
||||
serverHe.serverPublicKey?.let { k ->
|
||||
if (serverHe.signature == null)
|
||||
throw RemoteInterface.SecurityException("missing signature")
|
||||
if (!k.verify(serverHe.signature, params.token))
|
||||
serverHe.signature?.let { s ->
|
||||
if (!s.verify(params.token))
|
||||
throw RemoteInterface.SecurityException("wrong signature")
|
||||
params = params.copy(remoteIdentity = k)
|
||||
params = params.copy(remoteIdentity = s.publicKey)
|
||||
}
|
||||
|
||||
transport.call(
|
||||
L0ClientId, params.encrypt(
|
||||
pack(
|
||||
ClientIdentity(
|
||||
secretIdKey?.verifying,
|
||||
secretIdKey?.publicKey,
|
||||
secretIdKey?.sign(params.token)
|
||||
)
|
||||
)
|
||||
|
@ -60,14 +60,9 @@ class KiloServerConnection<S>(
|
||||
this@KiloServerConnection
|
||||
)
|
||||
|
||||
var public: SigningKey.Public? = null
|
||||
var signature: UByteArray? = null
|
||||
if( serverSigningKey != null ) {
|
||||
public = serverSigningKey.verifying
|
||||
signature = serverSigningKey.sign(params!!.token)
|
||||
}
|
||||
Handshake(1u, pair.publicKey, public, signature)
|
||||
Handshake(1u, pair.publicKey, serverSigningKey?.seal(params!!.token))
|
||||
}
|
||||
|
||||
on(L0ClientId) {
|
||||
var p = params ?: throw RemoteInterface.ClosedException("wrong handshake sequence")
|
||||
val ci = unpack<ClientIdentity>(p.decrypt(it))
|
||||
|
@ -1,13 +1,13 @@
|
||||
package net.sergeych.kiloparsec
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.sergeych.crypto2.Seal
|
||||
import net.sergeych.crypto2.SigningKey
|
||||
|
||||
// L0 commands - key exchange and check:
|
||||
@Serializable
|
||||
data class Handshake(val version: UInt, val publicKey: UByteArray,
|
||||
val serverPublicKey: SigningKey.Public? = null,
|
||||
val signature: UByteArray? = null)
|
||||
val signature: Seal? = null)
|
||||
|
||||
@Serializable
|
||||
data class ClientIdentity(val clientIdKey: SigningKey.Public?, val signature: UByteArray?)
|
||||
|
Loading…
x
Reference in New Issue
Block a user