From aa7bae962b0e2697de0dff0c8fe4d772afea5c6f Mon Sep 17 00:00:00 2001 From: Cristian G Date: Wed, 1 Nov 2023 14:30:46 -0400 Subject: [PATCH 1/4] feat: make public and private keys exportable and importable --- .../apollo/utils/Ed25519PrivateKey.kt | 27 +++++++ .../apollo/utils/Ed25519PublicKey.kt | 27 +++++++ .../apollo/utils/Secp256k1PrivateKey.kt | 30 ++++++++ .../apollo/utils/Secp256k1PublicKey.kt | 31 ++++++++ .../apollo/utils/X25519PrivateKey.kt | 27 +++++++ .../walletsdk/apollo/utils/X25519PublicKey.kt | 27 +++++++ .../keyManagement/ExportableImportableKey.kt | 77 +++++++++++++++++++ .../domain/models/keyManagement/Key.kt | 6 +- .../domain/models/keyManagement/PrivateKey.kt | 2 +- .../domain/models/keyManagement/PublicKey.kt | 2 +- .../prism/walletsdk/apollo/ApolloTests.kt | 8 ++ 11 files changed, 261 insertions(+), 3 deletions(-) create mode 100644 atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKey.kt diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt index 60b6e334c..f39c5c0d9 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt @@ -1,9 +1,12 @@ package io.iohk.atala.prism.walletsdk.apollo.utils +import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.apollo.utils.KMMEdPrivateKey import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.SignableKey @@ -29,4 +32,28 @@ class Ed25519PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey { val private = KMMEdPrivateKey(raw) return private.sign(message) } + + override fun getPem(): String { + return PEMKey( + keyType = "EC PRIVATE KEY", + keyData = raw + ).pemEncoded() + } + + override fun getJwk(): JWK { + return JWK( + kty = "OKP", + crv = getProperty(CurveKey().property), + x = raw.base64UrlEncoded + ) + } + + override fun jwkWithKid(kid: String): JWK { + return JWK( + kty = "OKP", + kid = kid, + crv = getProperty(CurveKey().property), + x = raw.base64UrlEncoded + ) + } } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt index ca581a17a..5729e0373 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt @@ -1,9 +1,12 @@ package io.iohk.atala.prism.walletsdk.apollo.utils +import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.apollo.utils.KMMEdPublicKey import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.VerifiableKey @@ -22,4 +25,28 @@ class Ed25519PublicKey(nativeValue: ByteArray) : PublicKey(), VerifiableKey { val public = KMMEdPublicKey(raw) return public.verify(message, signature) } + + override fun getPem(): String { + return PEMKey( + keyType = "EC PUBLIC KEY", + keyData = raw + ).pemEncoded() + } + + override fun getJwk(): JWK { + return JWK( + kty = "OKP", + crv = getProperty(CurveKey().property), + x = raw.base64UrlEncoded + ) + } + + override fun jwkWithKid(kid: String): JWK { + return JWK( + kty = "OKP", + kid = kid, + crv = getProperty(CurveKey().property), + x = raw.base64UrlEncoded + ) + } } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt index d70f9ea5f..d237a6bdb 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt @@ -1,9 +1,14 @@ package io.iohk.atala.prism.walletsdk.apollo.utils +import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.apollo.utils.KMMECSecp256k1PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurvePointXKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurvePointYKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.SignableKey @@ -27,4 +32,29 @@ class Secp256k1PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey { val kmmPrivateKey = KMMECSecp256k1PrivateKey.secp256k1FromByteArray(raw) return kmmPrivateKey.sign(data = message) } + + override fun getPem(): String { + return PEMKey( + keyType = "EC PRIVATE KEY", + keyData = raw + ).pemEncoded() + } + override fun getJwk(): JWK { + return JWK( + kty = "OKP", + crv = getProperty(CurveKey().property), + x = getProperty(CurvePointXKey().property).base64UrlEncoded, + y = getProperty(CurvePointYKey().property).base64UrlEncoded + ) + } + + override fun jwkWithKid(kid: String): JWK { + return JWK( + kty = "OKP", + kid = kid, + crv = getProperty(CurveKey().property), + x = getProperty(CurvePointXKey().property).base64UrlEncoded, + y = getProperty(CurvePointYKey().property).base64UrlEncoded + ) + } } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt index f1992041b..a3a27f6cd 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt @@ -1,11 +1,16 @@ package io.iohk.atala.prism.walletsdk.apollo.utils +import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.apollo.utils.KMMECSecp256k1PublicKey import io.iohk.atala.prism.walletsdk.apollo.config.ECConfig import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurvePointXKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurvePointYKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CustomKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.VerifiableKey @@ -33,6 +38,32 @@ class Secp256k1PublicKey(nativeValue: ByteArray) : PublicKey(), VerifiableKey { ) } + override fun getPem(): String { + return PEMKey( + keyType = "EC PUBLIC KEY", + keyData = raw + ).pemEncoded() + } + + override fun getJwk(): JWK { + return JWK( + kty = "OKP", + crv = getProperty(CurveKey().property), + x = getProperty(CurvePointXKey().property).base64UrlEncoded, + y = getProperty(CurvePointYKey().property).base64UrlEncoded + ) + } + + override fun jwkWithKid(kid: String): JWK { + return JWK( + kty = "OKP", + kid = kid, + crv = getProperty(CurveKey().property), + x = getProperty(CurvePointXKey().property).base64UrlEncoded, + y = getProperty(CurvePointYKey().property).base64UrlEncoded + ) + } + fun getEncodedCompressed(): ByteArray { return KMMECSecp256k1PublicKey(raw).getCompressed() } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt index f5adce3bc..a20337f78 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt @@ -1,9 +1,12 @@ package io.iohk.atala.prism.walletsdk.apollo.utils +import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.apollo.utils.KMMX25519PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey @@ -22,4 +25,28 @@ class X25519PrivateKey(nativeValue: ByteArray) : PrivateKey() { val private = KMMX25519PrivateKey(raw) return X25519PublicKey(private.publicKey().raw) } + + override fun getPem(): String { + return PEMKey( + keyType = "EC PRIVATE KEY", + keyData = raw + ).pemEncoded() + } + + override fun getJwk(): JWK { + return JWK( + kty = "OKP", + crv = getProperty(CurveKey().property), + x = raw.base64UrlEncoded + ) + } + + override fun jwkWithKid(kid: String): JWK { + return JWK( + kty = "OKP", + kid = kid, + crv = getProperty(CurveKey().property), + x = raw.base64UrlEncoded + ) + } } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt index b321ae849..8c57f0326 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt @@ -1,8 +1,11 @@ package io.iohk.atala.prism.walletsdk.apollo.utils +import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey class X25519PublicKey(nativeValue: ByteArray) : PublicKey() { @@ -15,4 +18,28 @@ class X25519PublicKey(nativeValue: ByteArray) : PublicKey() { size = raw.size keySpecification[CurveKey().property] = Curve.X25519.value } + + override fun getPem(): String { + return PEMKey( + keyType = "EC PUBLIC KEY", + keyData = raw + ).pemEncoded() + } + + override fun getJwk(): JWK { + return JWK( + kty = "OKP", + crv = getProperty(CurveKey().property), + x = raw.base64UrlEncoded + ) + } + + override fun jwkWithKid(kid: String): JWK { + return JWK( + kty = "OKP", + kid = kid, + crv = getProperty(CurveKey().property), + x = raw.base64UrlEncoded + ) + } } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKey.kt new file mode 100644 index 000000000..8a78871c8 --- /dev/null +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKey.kt @@ -0,0 +1,77 @@ +package io.iohk.atala.prism.walletsdk.domain.models.keyManagement + +import io.iohk.atala.prism.apollo.base64.base64UrlDecoded +import io.iohk.atala.prism.apollo.base64.base64UrlDecodedBytes +import io.iohk.atala.prism.apollo.base64.base64UrlEncoded +import kotlinx.serialization.Serializable + +interface ExportableKey { + fun getPem(): String + fun getJwk(): JWK + + fun jwkWithKid(kid: String): JWK +} + +interface ImportableKey { + @Throws(Exception::class) + fun initializeFromPem(pem: String) + + @Throws(Exception::class) + fun initializeFromJwk(jwk: JWK) +} + +@Serializable +data class JWK( + val kty: String, + val alg: String? = null, + val kid: String? = null, + val use: String? = null, + val n: String? = null, + val e: String? = null, + val d: String? = null, + val p: String? = null, + val q: String? = null, + val dp: String? = null, + val dq: String? = null, + val qi: String? = null, + val crv: String? = null, + val x: String? = null, + val y: String? = null, + val k: String? = null +) + +data class PEMKey(val keyType: String, val keyData: ByteArray) { + constructor(keyType: String, keyData: String) : this(keyType, keyData.base64UrlDecodedBytes) + + fun pemEncoded(): String { + val base64Data = keyData.base64UrlEncoded + val beginMarker = "-----BEGIN $keyType-----" + val endMarker = "-----END $keyType-----" + + return "$beginMarker\n$base64Data$endMarker" + } + + companion object { + fun fromPemEncoded(pemString: String): PEMKey? { + val lines = pemString.split("\n") + if (lines.size < 3) { + return null + } + + val beginMarker = lines[0] + val endMarker = lines[lines.size - 1] + + if (!beginMarker.startsWith("-----BEGIN ") || !beginMarker.endsWith("-----") || + !endMarker.startsWith("-----END ") || !endMarker.endsWith("-----") + ) { + return null + } + + val keyType = beginMarker.substring(11, beginMarker.length - 5) + val base64Data = lines.subList(1, lines.size - 1).joinToString("") + val keyData = base64Data.base64UrlDecoded + + return PEMKey(keyType = keyType, keyData = keyData) + } + } +} diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/Key.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/Key.kt index bdf4945a8..0f5efaa6c 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/Key.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/Key.kt @@ -39,7 +39,11 @@ abstract class Key { } fun isExportable(): Boolean { - return this is StorableKey + return this is ExportableKey + } + + fun isImportable(): Boolean { + return this is ImportableKey } fun isSignable(): Boolean { diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PrivateKey.kt index 0714abecf..c268f17c6 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PrivateKey.kt @@ -2,7 +2,7 @@ package io.iohk.atala.prism.walletsdk.domain.models.keyManagement import io.iohk.atala.prism.walletsdk.domain.models.Curve -abstract class PrivateKey : Key() { +abstract class PrivateKey : Key(), ExportableKey { fun getCurve(): String { return this.getProperty(CurveKey().property) diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PublicKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PublicKey.kt index 3aacdc57a..359bb3360 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PublicKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PublicKey.kt @@ -2,7 +2,7 @@ package io.iohk.atala.prism.walletsdk.domain.models.keyManagement import io.iohk.atala.prism.walletsdk.domain.models.Curve -abstract class PublicKey : Key() { +abstract class PublicKey : Key(), ExportableKey { fun getCurve(): String { return this.getProperty(CurveKey().property) diff --git a/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloTests.kt b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloTests.kt index b54b9b493..5fe2c7422 100644 --- a/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloTests.kt +++ b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/apollo/ApolloTests.kt @@ -12,6 +12,8 @@ import io.iohk.atala.prism.walletsdk.apollo.utils.Secp256k1KeyPair import io.iohk.atala.prism.walletsdk.apollo.utils.Secp256k1PrivateKey import io.iohk.atala.prism.walletsdk.apollo.utils.Secp256k1PublicKey import io.iohk.atala.prism.walletsdk.apollo.utils.X25519KeyPair +import io.iohk.atala.prism.walletsdk.apollo.utils.X25519PrivateKey +import io.iohk.atala.prism.walletsdk.apollo.utils.X25519PublicKey import io.iohk.atala.prism.walletsdk.domain.buildingblocks.Apollo import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.KeyCurve @@ -91,6 +93,8 @@ class ApolloTests { assertEquals(signature.size <= ECConfig.SIGNATURE_MAX_BYTE_SIZE, true) assertTrue((keyPair.publicKey as Secp256k1PublicKey).verify(message.encodeToByteArray(), signature)) + assertTrue((keyPair.publicKey as Secp256k1PublicKey).isExportable()) + assertTrue((keyPair.privateKey as Secp256k1PrivateKey).isExportable()) } @Test @@ -100,6 +104,8 @@ class ApolloTests { val publicKey = keyPair.publicKey assertEquals(32, privateKey.raw.size) assertEquals(32, publicKey.raw.size) + assertTrue((keyPair.publicKey as Ed25519PublicKey).isExportable()) + assertTrue((keyPair.privateKey as Ed25519PrivateKey).isExportable()) } @Test @@ -109,6 +115,8 @@ class ApolloTests { val publicKey = keyPair.publicKey assertEquals(32, privateKey.raw.size) assertEquals(32, publicKey.raw.size) + assertTrue((keyPair.publicKey as X25519PublicKey).isExportable()) + assertTrue((keyPair.privateKey as X25519PrivateKey).isExportable()) } @Test From bcbae88204cdf58ce3687613ea8ca7cdf04f10cc Mon Sep 17 00:00:00 2001 From: Cristian G Date: Fri, 3 Nov 2023 08:57:18 -0400 Subject: [PATCH 2/4] feat: exportable, importable and storable keys --- .../apollo/utils/Ed25519PrivateKey.kt | 9 +- .../apollo/utils/Ed25519PublicKey.kt | 9 +- .../apollo/utils/Secp256k1PrivateKey.kt | 9 +- .../apollo/utils/Secp256k1PublicKey.kt | 9 +- .../apollo/utils/X25519PrivateKey.kt | 9 +- .../walletsdk/apollo/utils/X25519PublicKey.kt | 9 +- .../walletsdk/domain/buildingblocks/Pluto.kt | 5 +- .../prism/walletsdk/domain/models/Errors.kt | 8 ++ .../prism/walletsdk/domain/models/PeerDID.kt | 2 +- .../domain/models/keyManagement/PrivateKey.kt | 2 +- .../domain/models/keyManagement/PublicKey.kt | 2 +- .../models/keyManagement/StorableKey.kt | 7 -- .../atala/prism/walletsdk/pluto/PlutoImpl.kt | 95 +++++++++---------- .../prism/walletsdk/prismagent/PrismAgent.kt | 7 +- .../data/PrivateKey.sq | 6 +- .../prism/walletsdk/mercury/PlutoMock.kt | 5 +- .../prism/walletsdk/prismagent/PlutoMock.kt | 5 +- 17 files changed, 120 insertions(+), 78 deletions(-) diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt index f39c5c0d9..eaef4a266 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt @@ -4,14 +4,16 @@ import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.apollo.utils.KMMEdPrivateKey import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.SignableKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey -class Ed25519PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey { +class Ed25519PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey, StorableKey, ExportableKey { override val type: KeyTypes = KeyTypes.EC override val keySpecification: MutableMap = mutableMapOf() @@ -56,4 +58,9 @@ class Ed25519PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey { x = raw.base64UrlEncoded ) } + + override val storableData: ByteArray + get() = raw + override val restorationIdentifier: String + get() = "ed25519+priv" } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt index 5729e0373..ff1f97e91 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt @@ -4,13 +4,15 @@ import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.apollo.utils.KMMEdPublicKey import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.VerifiableKey -class Ed25519PublicKey(nativeValue: ByteArray) : PublicKey(), VerifiableKey { +class Ed25519PublicKey(nativeValue: ByteArray) : PublicKey(), VerifiableKey, StorableKey, ExportableKey { override val type: KeyTypes = KeyTypes.EC override val keySpecification: MutableMap = mutableMapOf() override val size: Int @@ -49,4 +51,9 @@ class Ed25519PublicKey(nativeValue: ByteArray) : PublicKey(), VerifiableKey { x = raw.base64UrlEncoded ) } + + override val storableData: ByteArray + get() = raw + override val restorationIdentifier: String + get() = "ed25519+pub" } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt index d237a6bdb..df9afa160 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt @@ -6,14 +6,16 @@ import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurvePointXKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurvePointYKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.SignableKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey -class Secp256k1PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey { +class Secp256k1PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey, StorableKey, ExportableKey { override val type: KeyTypes = KeyTypes.EC override val keySpecification: MutableMap = mutableMapOf() override val size: Int @@ -57,4 +59,9 @@ class Secp256k1PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey { y = getProperty(CurvePointYKey().property).base64UrlEncoded ) } + + override val storableData: ByteArray + get() = raw + override val restorationIdentifier: String + get() = "secp256k1+priv" } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt index a3a27f6cd..a2b067a93 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt @@ -8,13 +8,15 @@ import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurvePointXKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurvePointYKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CustomKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.VerifiableKey -class Secp256k1PublicKey(nativeValue: ByteArray) : PublicKey(), VerifiableKey { +class Secp256k1PublicKey(nativeValue: ByteArray) : PublicKey(), VerifiableKey, StorableKey, ExportableKey { override val type: KeyTypes = KeyTypes.EC override val keySpecification: MutableMap = mutableMapOf() override val size: Int @@ -64,6 +66,11 @@ class Secp256k1PublicKey(nativeValue: ByteArray) : PublicKey(), VerifiableKey { ) } + override val storableData: ByteArray + get() = raw + override val restorationIdentifier: String + get() = "secp256k1+pub" + fun getEncodedCompressed(): ByteArray { return KMMECSecp256k1PublicKey(raw).getCompressed() } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt index a20337f78..0c9fa8cf5 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt @@ -4,13 +4,15 @@ import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.apollo.utils.KMMX25519PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey -class X25519PrivateKey(nativeValue: ByteArray) : PrivateKey() { +class X25519PrivateKey(nativeValue: ByteArray) : PrivateKey(), StorableKey, ExportableKey { override val type: KeyTypes = KeyTypes.EC override val keySpecification: MutableMap = mutableMapOf() override val size: Int @@ -49,4 +51,9 @@ class X25519PrivateKey(nativeValue: ByteArray) : PrivateKey() { x = raw.base64UrlEncoded ) } + + override val storableData: ByteArray + get() = raw + override val restorationIdentifier: String + get() = "x25519+priv" } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt index 8c57f0326..c2c58c4ac 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt @@ -3,12 +3,14 @@ package io.iohk.atala.prism.walletsdk.apollo.utils import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.CurveKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey -class X25519PublicKey(nativeValue: ByteArray) : PublicKey() { +class X25519PublicKey(nativeValue: ByteArray) : PublicKey(), ExportableKey, StorableKey { override val type: KeyTypes = KeyTypes.EC override val keySpecification: MutableMap = mutableMapOf() override val size: Int @@ -42,4 +44,9 @@ class X25519PublicKey(nativeValue: ByteArray) : PublicKey() { x = raw.base64UrlEncoded ) } + + override val storableData: ByteArray + get() = raw + override val restorationIdentifier: String + get() = "x25519+pub" } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/buildingblocks/Pluto.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/buildingblocks/Pluto.kt index 5e06c9342..f2390755f 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/buildingblocks/Pluto.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/buildingblocks/Pluto.kt @@ -8,6 +8,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.PeerDID import io.iohk.atala.prism.walletsdk.domain.models.PrismDIDInfo import io.iohk.atala.prism.walletsdk.domain.models.StorableCredential import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey import io.iohk.atala.prism.walletsdk.pluto.CredentialRecovery import io.iohk.atala.prism.walletsdk.pollux.models.CredentialRequestMeta import ioiohkatalaprismwalletsdkpluto.data.AvailableClaims @@ -19,7 +20,7 @@ interface Pluto { did: DID, keyPathIndex: Int, alias: String?, - privateKeys: List + privateKeys: List ) fun storePeerDID(did: DID) @@ -30,7 +31,7 @@ interface Pluto { fun storeMessages(messages: List) - fun storePrivateKeys(privateKey: PrivateKey, did: DID, keyPathIndex: Int, metaId: String? = null) + fun storePrivateKeys(privateKey: StorableKey, did: DID, keyPathIndex: Int, metaId: String? = null) fun storeMediator(mediator: DID, host: DID, routing: DID) diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Errors.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Errors.kt index 04dec6577..953c960a8 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Errors.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/Errors.kt @@ -416,6 +416,14 @@ sealed class PlutoError @JvmOverloads constructor(message: String? = null, cause override val message: String get() = "Database service already running." } + + class InvalidRestorationIdentifier : PlutoError() { + override val code: Int + get() = 49 + + override val message: String + get() = "Invalid restoration identifier" + } } /** diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/PeerDID.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/PeerDID.kt index 657500d7e..05d19c649 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/PeerDID.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/PeerDID.kt @@ -4,7 +4,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey data class PeerDID( val did: DID, - val privateKeys: Array + val privateKeys: Array ) { override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PrivateKey.kt index c268f17c6..0714abecf 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PrivateKey.kt @@ -2,7 +2,7 @@ package io.iohk.atala.prism.walletsdk.domain.models.keyManagement import io.iohk.atala.prism.walletsdk.domain.models.Curve -abstract class PrivateKey : Key(), ExportableKey { +abstract class PrivateKey : Key() { fun getCurve(): String { return this.getProperty(CurveKey().property) diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PublicKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PublicKey.kt index 359bb3360..3aacdc57a 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PublicKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/PublicKey.kt @@ -2,7 +2,7 @@ package io.iohk.atala.prism.walletsdk.domain.models.keyManagement import io.iohk.atala.prism.walletsdk.domain.models.Curve -abstract class PublicKey : Key(), ExportableKey { +abstract class PublicKey : Key() { fun getCurve(): String { return this.getProperty(CurveKey().property) diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/StorableKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/StorableKey.kt index 4a4417937..8470b975e 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/StorableKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/StorableKey.kt @@ -1,13 +1,6 @@ package io.iohk.atala.prism.walletsdk.domain.models.keyManagement -enum class SecurityLevel { - HIGH, - LOW -} - interface StorableKey { - fun store() - val securityLevel: SecurityLevel val storableData: ByteArray val restorationIdentifier: String } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt index 801e34924..5669f04dd 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt @@ -10,7 +10,6 @@ import io.iohk.atala.prism.walletsdk.apollo.utils.Ed25519PrivateKey import io.iohk.atala.prism.walletsdk.apollo.utils.Secp256k1PrivateKey import io.iohk.atala.prism.walletsdk.apollo.utils.X25519PrivateKey import io.iohk.atala.prism.walletsdk.domain.buildingblocks.Pluto -import io.iohk.atala.prism.walletsdk.domain.models.Curve import io.iohk.atala.prism.walletsdk.domain.models.DID import io.iohk.atala.prism.walletsdk.domain.models.DIDPair import io.iohk.atala.prism.walletsdk.domain.models.Mediator @@ -20,7 +19,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.PlutoError import io.iohk.atala.prism.walletsdk.domain.models.PrismDIDInfo import io.iohk.atala.prism.walletsdk.domain.models.StorableCredential import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey -import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.getKeyCurveByNameAndIndex +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey import io.iohk.atala.prism.walletsdk.pluto.data.DbConnection import io.iohk.atala.prism.walletsdk.pluto.data.isConnected import io.iohk.atala.prism.walletsdk.pollux.models.CredentialRequestMeta @@ -73,7 +72,7 @@ class PlutoImpl(private val connection: DbConnection) : Pluto { did: DID, keyPathIndex: Int, alias: String?, - privateKeys: List + privateKeys: List ) { getInstance().dIDQueries.insert( DIDDB( @@ -128,7 +127,7 @@ class PlutoImpl(private val connection: DbConnection) : Pluto { } override fun storePrivateKeys( - privateKey: PrivateKey, + storableKey: StorableKey, did: DID, keyPathIndex: Int, metaId: String? @@ -139,8 +138,8 @@ class PlutoImpl(private val connection: DbConnection) : Pluto { getInstance().privateKeyQueries.insert( PrivateKeyDB( metaId, - privateKey.getCurve(), - privateKey.getValue().base64UrlEncoded, + storableKey.restorationIdentifier, + storableKey.storableData.base64UrlEncoded, keyPathIndex, did.toString() ) @@ -152,8 +151,8 @@ class PlutoImpl(private val connection: DbConnection) : Pluto { getInstance().privateKeyQueries.insert( PrivateKeyDB( UUID.randomUUID4().toString(), - privateKey.getCurve(), - privateKey.getValue().base64UrlEncoded, + storableKey.restorationIdentifier, + storableKey.storableData.base64UrlEncoded, keyPathIndex, did.toString() ) @@ -278,27 +277,23 @@ class PlutoImpl(private val connection: DbConnection) : Pluto { .asFlow() .map { it.executeAsList() - .map { didInfo -> - try { - val keyCurve = getKeyCurveByNameAndIndex( - didInfo.curve, - didInfo.keyPathIndex - ) - when (keyCurve.curve) { - Curve.SECP256K1 -> { - Secp256k1PrivateKey(didInfo.privateKey.base64UrlDecodedBytes) - } + .map { storableKey -> + when (storableKey.restorationIdentifier) { + "secp256k1+priv" -> { + Secp256k1PrivateKey(storableKey.data_.base64UrlDecodedBytes) + } - Curve.ED25519 -> { - Ed25519PrivateKey(didInfo.privateKey.base64UrlDecodedBytes) - } + "ed25519+priv" -> { + Ed25519PrivateKey(storableKey.data_.base64UrlDecodedBytes) + } - Curve.X25519 -> { - X25519PrivateKey(didInfo.privateKey.base64UrlDecodedBytes) - } + "x25519+priv" -> { + X25519PrivateKey(storableKey.data_.base64UrlDecodedBytes) + } + + else -> { + throw PlutoError.InvalidRestorationIdentifier() } - } catch (e: IllegalStateException) { - null } } } @@ -309,22 +304,22 @@ class PlutoImpl(private val connection: DbConnection) : Pluto { .fetchPrivateKeyByID(id) .asFlow() .map { it -> - it.executeAsList().firstOrNull()?.let { - val keyCurve = getKeyCurveByNameAndIndex( - it.curve, - it.keyPathIndex - ) - when (keyCurve.curve) { - Curve.SECP256K1 -> { - Secp256k1PrivateKey(it.privateKey.base64UrlDecodedBytes) + it.executeAsList().firstOrNull()?.let { storableKey -> + when (storableKey.restorationIdentifier) { + "secp256k1+priv" -> { + Secp256k1PrivateKey(storableKey.data_.base64UrlDecodedBytes) + } + + "ed25519+priv" -> { + Ed25519PrivateKey(storableKey.data_.base64UrlDecodedBytes) } - Curve.ED25519 -> { - Ed25519PrivateKey(it.privateKey.base64UrlDecodedBytes) + "x25519+priv" -> { + X25519PrivateKey(storableKey.data_.base64UrlDecodedBytes) } - Curve.X25519 -> { - X25519PrivateKey(it.privateKey.base64UrlDecodedBytes) + else -> { + throw PlutoError.InvalidRestorationIdentifier() } } } @@ -358,22 +353,22 @@ class PlutoImpl(private val connection: DbConnection) : Pluto { allDIDs.executeAsList() .groupBy { allPeerDid -> allPeerDid.did } .map { - val privateKeyList = it.value.mapNotNull { data -> - val keyCurve = getKeyCurveByNameAndIndex( - data.curve, - data.keyPathIndex - ) - when (keyCurve.curve) { - Curve.SECP256K1 -> { - Secp256k1PrivateKey(data.privateKey.base64UrlDecodedBytes) + val privateKeyList = it.value.mapNotNull { storableKey -> + when (storableKey.restorationIdentifier) { + "secp256k1+priv" -> { + Secp256k1PrivateKey(storableKey.data_.base64UrlDecodedBytes) + } + + "ed25519+priv" -> { + Ed25519PrivateKey(storableKey.data_.base64UrlDecodedBytes) } - Curve.ED25519 -> { - Ed25519PrivateKey(data.privateKey.base64UrlDecodedBytes) + "x25519+priv" -> { + X25519PrivateKey(storableKey.data_.base64UrlDecodedBytes) } - Curve.X25519 -> { - X25519PrivateKey(data.privateKey.base64UrlDecodedBytes) + else -> { + throw PlutoError.InvalidRestorationIdentifier() } } }.toTypedArray() diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt index 990bfe99a..cfdd1fbdc 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PrismAgent.kt @@ -39,6 +39,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.Signature import io.iohk.atala.prism.walletsdk.domain.models.httpClient import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyPair import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey import io.iohk.atala.prism.walletsdk.logger.LogComponent import io.iohk.atala.prism.walletsdk.logger.Metadata import io.iohk.atala.prism.walletsdk.logger.PrismLogger @@ -315,7 +316,7 @@ class PrismAgent { did = did, keyPathIndex = keyPathIndex, alias = alias, - listOf(privateKey) + listOf(privateKey as StorableKey) ) } @@ -403,10 +404,10 @@ class PrismAgent { verificationMethods.values.forEach { if (it.type.contains("X25519")) { - pluto.storePrivateKeys(keyAgreementKeyPair.privateKey, did, 0, it.id.toString()) + pluto.storePrivateKeys(keyAgreementKeyPair.privateKey as StorableKey, did, 0, it.id.toString()) } else if (it.type.contains("Ed25519")) { pluto.storePrivateKeys( - authenticationKeyPair.privateKey, + authenticationKeyPair.privateKey as StorableKey, did, 0, it.id.toString() diff --git a/atala-prism-sdk/src/commonMain/sqldelight/io.iohk.atala.prism.walletsdk.pluto/data/PrivateKey.sq b/atala-prism-sdk/src/commonMain/sqldelight/io.iohk.atala.prism.walletsdk.pluto/data/PrivateKey.sq index 0df1bdcc0..7afb03674 100644 --- a/atala-prism-sdk/src/commonMain/sqldelight/io.iohk.atala.prism.walletsdk.pluto/data/PrivateKey.sq +++ b/atala-prism-sdk/src/commonMain/sqldelight/io.iohk.atala.prism.walletsdk.pluto/data/PrivateKey.sq @@ -1,7 +1,7 @@ CREATE TABLE PrivateKey ( id TEXT NOT NULL UNIQUE, - curve TEXT NOT NULL, - privateKey TEXT NOT NULL, + restorationIdentifier TEXT NOT NULL, + data TEXT NOT NULL, keyPathIndex INTEGER AS Int DEFAULT 0, didId TEXT NOT NULL, PRIMARY KEY (id), @@ -9,7 +9,7 @@ CREATE TABLE PrivateKey ( ); insert: -INSERT INTO PrivateKey(id, curve, privateKey, keyPathIndex, didId) +INSERT INTO PrivateKey(id, restorationIdentifier, data, keyPathIndex, didId) VALUES ?; fetchPrivateKeyByDID: diff --git a/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/mercury/PlutoMock.kt b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/mercury/PlutoMock.kt index b80172f1b..5a641e2c4 100644 --- a/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/mercury/PlutoMock.kt +++ b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/mercury/PlutoMock.kt @@ -11,6 +11,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.PrismDIDInfo import io.iohk.atala.prism.walletsdk.domain.models.StorableCredential import io.iohk.atala.prism.walletsdk.pollux.models.CredentialRequestMeta import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey import io.iohk.atala.prism.walletsdk.pluto.CredentialRecovery import ioiohkatalaprismwalletsdkpluto.data.AvailableClaims import kotlinx.coroutines.flow.Flow @@ -32,7 +33,7 @@ class PlutoMock : Pluto { did: DID, keyPathIndex: Int, alias: String?, - privateKeys: List + privateKeys: List ) { TODO("Not yet implemented") } @@ -53,7 +54,7 @@ class PlutoMock : Pluto { TODO("Not yet implemented") } - override fun storePrivateKeys(privateKey: PrivateKey, did: DID, keyPathIndex: Int, metaId: String?) { + override fun storePrivateKeys(privateKey: StorableKey, did: DID, keyPathIndex: Int, metaId: String?) { TODO("Not yet implemented") } diff --git a/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PlutoMock.kt b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PlutoMock.kt index a18097798..32015dfae 100644 --- a/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PlutoMock.kt +++ b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/prismagent/PlutoMock.kt @@ -9,6 +9,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.PeerDID import io.iohk.atala.prism.walletsdk.domain.models.PrismDIDInfo import io.iohk.atala.prism.walletsdk.domain.models.StorableCredential import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey import io.iohk.atala.prism.walletsdk.pluto.CredentialRecovery import io.iohk.atala.prism.walletsdk.pollux.models.CredentialRequestMeta import ioiohkatalaprismwalletsdkpluto.data.AvailableClaims @@ -70,7 +71,7 @@ class PlutoMock : Pluto { did: DID, keyPathIndex: Int, alias: String?, - privateKeys: List + privateKeys: List ) { storedPrismDID += did wasStorePrismDIDAndPrivateKeysCalled = true @@ -93,7 +94,7 @@ class PlutoMock : Pluto { wasStoreMessagesCalled = true } - override fun storePrivateKeys(privateKey: PrivateKey, did: DID, keyPathIndex: Int, metaId: String?) { + override fun storePrivateKeys(privateKey: StorableKey, did: DID, keyPathIndex: Int, metaId: String?) { wasStorePrivateKeysCalled = true } From 7cbaafde692af836fac284a4698bab9b462363bd Mon Sep 17 00:00:00 2001 From: Cristian G Date: Mon, 13 Nov 2023 13:54:46 -0500 Subject: [PATCH 3/4] feat: pluto inputs storable credentials to store them --- .../io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt index 5669f04dd..82252a507 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/pluto/PlutoImpl.kt @@ -353,18 +353,19 @@ class PlutoImpl(private val connection: DbConnection) : Pluto { allDIDs.executeAsList() .groupBy { allPeerDid -> allPeerDid.did } .map { - val privateKeyList = it.value.mapNotNull { storableKey -> - when (storableKey.restorationIdentifier) { + println("Restoration ID: ${it.value.get(0).restorationIdentifier}") + val privateKeyList: Array = it.value.mapNotNull { allPeerDID -> + when (allPeerDID.restorationIdentifier) { "secp256k1+priv" -> { - Secp256k1PrivateKey(storableKey.data_.base64UrlDecodedBytes) + Secp256k1PrivateKey(allPeerDID.data_.base64UrlDecodedBytes) } "ed25519+priv" -> { - Ed25519PrivateKey(storableKey.data_.base64UrlDecodedBytes) + Ed25519PrivateKey(allPeerDID.data_.base64UrlDecodedBytes) } "x25519+priv" -> { - X25519PrivateKey(storableKey.data_.base64UrlDecodedBytes) + X25519PrivateKey(allPeerDID.data_.base64UrlDecodedBytes) } else -> { From 45c16df9286c067983ee0d71bebd6a069bdeea9e Mon Sep 17 00:00:00 2001 From: Cristian G Date: Tue, 14 Nov 2023 12:13:29 -0500 Subject: [PATCH 4/4] fix: pr requested changes --- .../apollo/utils/Ed25519PrivateKey.kt | 3 +- .../apollo/utils/Ed25519PublicKey.kt | 3 +- .../apollo/utils/Secp256k1PrivateKey.kt | 3 +- .../apollo/utils/Secp256k1PublicKey.kt | 3 +- .../apollo/utils/X25519PrivateKey.kt | 3 +- .../walletsdk/apollo/utils/X25519PublicKey.kt | 3 +- .../keyManagement/ExportableImportableKey.kt | 31 +++++++++++++------ .../ExportableImportableKeyTest.kt | 24 ++++++++++++++ 8 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKeyTest.kt diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt index eaef4a266..8cb5136cf 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PrivateKey.kt @@ -8,6 +8,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKeyType import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.SignableKey @@ -37,7 +38,7 @@ class Ed25519PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey, Sto override fun getPem(): String { return PEMKey( - keyType = "EC PRIVATE KEY", + keyType = PEMKeyType.EC_PRIVATE_KEY, keyData = raw ).pemEncoded() } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt index ff1f97e91..e4ffcd981 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Ed25519PublicKey.kt @@ -8,6 +8,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKeyType import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.VerifiableKey @@ -30,7 +31,7 @@ class Ed25519PublicKey(nativeValue: ByteArray) : PublicKey(), VerifiableKey, Sto override fun getPem(): String { return PEMKey( - keyType = "EC PUBLIC KEY", + keyType = PEMKeyType.EC_PUBLIC_KEY, keyData = raw ).pemEncoded() } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt index df9afa160..c6e9d2451 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PrivateKey.kt @@ -10,6 +10,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKeyType import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.SignableKey @@ -37,7 +38,7 @@ class Secp256k1PrivateKey(nativeValue: ByteArray) : PrivateKey(), SignableKey, S override fun getPem(): String { return PEMKey( - keyType = "EC PRIVATE KEY", + keyType = PEMKeyType.EC_PRIVATE_KEY, keyData = raw ).pemEncoded() } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt index a2b067a93..87219667e 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/Secp256k1PublicKey.kt @@ -12,6 +12,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKeyType import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.VerifiableKey @@ -42,7 +43,7 @@ class Secp256k1PublicKey(nativeValue: ByteArray) : PublicKey(), VerifiableKey, S override fun getPem(): String { return PEMKey( - keyType = "EC PUBLIC KEY", + keyType = PEMKeyType.EC_PUBLIC_KEY, keyData = raw ).pemEncoded() } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt index 0c9fa8cf5..32af0c0a9 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PrivateKey.kt @@ -8,6 +8,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKeyType import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey @@ -30,7 +31,7 @@ class X25519PrivateKey(nativeValue: ByteArray) : PrivateKey(), StorableKey, Expo override fun getPem(): String { return PEMKey( - keyType = "EC PRIVATE KEY", + keyType = PEMKeyType.EC_PRIVATE_KEY, keyData = raw ).pemEncoded() } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt index c2c58c4ac..789d8c581 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/apollo/utils/X25519PublicKey.kt @@ -7,6 +7,7 @@ import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.ExportableKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.JWK import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKey +import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PEMKeyType import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PublicKey import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey @@ -23,7 +24,7 @@ class X25519PublicKey(nativeValue: ByteArray) : PublicKey(), ExportableKey, Stor override fun getPem(): String { return PEMKey( - keyType = "EC PUBLIC KEY", + keyType = PEMKeyType.EC_PUBLIC_KEY, keyData = raw ).pemEncoded() } diff --git a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKey.kt b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKey.kt index 8a78871c8..d63d5b8f3 100644 --- a/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKey.kt +++ b/atala-prism-sdk/src/commonMain/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKey.kt @@ -1,8 +1,7 @@ package io.iohk.atala.prism.walletsdk.domain.models.keyManagement -import io.iohk.atala.prism.apollo.base64.base64UrlDecoded +import io.iohk.atala.prism.apollo.base64.base64PadEncoded import io.iohk.atala.prism.apollo.base64.base64UrlDecodedBytes -import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import kotlinx.serialization.Serializable interface ExportableKey { @@ -40,15 +39,15 @@ data class JWK( val k: String? = null ) -data class PEMKey(val keyType: String, val keyData: ByteArray) { - constructor(keyType: String, keyData: String) : this(keyType, keyData.base64UrlDecodedBytes) +data class PEMKey(val keyType: PEMKeyType, val keyData: ByteArray) { + constructor(keyType: PEMKeyType, keyData: String) : this(keyType, keyData.base64UrlDecodedBytes) fun pemEncoded(): String { - val base64Data = keyData.base64UrlEncoded + val base64Data = keyData.base64PadEncoded val beginMarker = "-----BEGIN $keyType-----" val endMarker = "-----END $keyType-----" - return "$beginMarker\n$base64Data$endMarker" + return "$beginMarker\n$base64Data\n$endMarker" } companion object { @@ -61,17 +60,29 @@ data class PEMKey(val keyType: String, val keyData: ByteArray) { val beginMarker = lines[0] val endMarker = lines[lines.size - 1] - if (!beginMarker.startsWith("-----BEGIN ") || !beginMarker.endsWith("-----") || - !endMarker.startsWith("-----END ") || !endMarker.endsWith("-----") + if (beginMarker.startsWith("-----BEGIN ").not() || beginMarker.endsWith("-----").not() || + endMarker.startsWith("-----END ").not() || endMarker.endsWith("-----").not() ) { return null } - val keyType = beginMarker.substring(11, beginMarker.length - 5) + val keyType = PEMKeyType.fromString(beginMarker) ?: throw Exception("Unknown PEM Key type") + val base64Data = lines.subList(1, lines.size - 1).joinToString("") - val keyData = base64Data.base64UrlDecoded + val keyData = base64Data.base64PadEncoded return PEMKey(keyType = keyType, keyData = keyData) } } } + +enum class PEMKeyType(val value: Pair) { + EC_PRIVATE_KEY(Pair("-----BEGIN EC PRIVATE KEY-----", "-----END EC PRIVATE KEY-----")), + EC_PUBLIC_KEY(Pair("-----BEGIN EC PUBLIC KEY-----", "-----END EC PUBLIC KEY-----")); + + companion object { + fun fromString(value: String): PEMKeyType? { + return values().firstOrNull { it.value.first == value || it.value.second == value } + } + } +} diff --git a/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKeyTest.kt b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKeyTest.kt new file mode 100644 index 000000000..86d79111d --- /dev/null +++ b/atala-prism-sdk/src/commonTest/kotlin/io/iohk/atala/prism/walletsdk/domain/models/keyManagement/ExportableImportableKeyTest.kt @@ -0,0 +1,24 @@ +package io.iohk.atala.prism.walletsdk.domain.models.keyManagement + +import junit.framework.TestCase.assertNull +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull + +class ExportableImportableKeyTest { + + @Test + fun testPEMKeyTypeFromString_whenCorrectStringProvided_thenSuccess() { + val keyTypePrivate = PEMKeyType.fromString("-----BEGIN EC PRIVATE KEY-----") + assertNotNull(keyTypePrivate) + assertEquals(PEMKeyType.EC_PRIVATE_KEY, keyTypePrivate) + val keyTypePublic = PEMKeyType.fromString("-----BEGIN EC PUBLIC KEY-----") + assertNotNull(keyTypePublic) + assertEquals(PEMKeyType.EC_PUBLIC_KEY, keyTypePublic) + } + + @Test + fun testPEMKeyTypeFromString_whenWrongStringProvided_thenReturnNull() { + assertNull(PEMKeyType.fromString("-----BEGIN FAIL KEY-----")) + } +}