Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: KeyRestoration #111

Merged
merged 4 commits into from
Nov 21, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: implement key restoration
  • Loading branch information
cristianIOHK committed Nov 2, 2023
commit 997aa18bbb8c399bb776e67212016286a38c4332
Original file line number Diff line number Diff line change
@@ -6,9 +6,12 @@ import io.iohk.atala.prism.apollo.utils.Mnemonic
import io.iohk.atala.prism.walletsdk.apollo.helpers.BytesOps
import io.iohk.atala.prism.walletsdk.apollo.utils.Ed25519KeyPair
import io.iohk.atala.prism.walletsdk.apollo.utils.Ed25519PrivateKey
import io.iohk.atala.prism.walletsdk.apollo.utils.Ed25519PublicKey
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.ApolloError
import io.iohk.atala.prism.walletsdk.domain.models.Curve
@@ -19,8 +22,10 @@ import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.DerivationPathK
import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.IndexKey
import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyTypes
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.RawKey
import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.SeedKey
import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.StorableKey
import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.TypeKey

/**
@@ -108,9 +113,7 @@ class ApolloImpl : Apollo {
throw ApolloError.InvalidIndex("Index must be an integer")
}
val derivationPath =
if (properties[DerivationPathKey().property] != null &&
properties[DerivationPathKey().property] !is String
) {
if (properties[DerivationPathKey().property] != null && properties[DerivationPathKey().property] !is String) {
throw ApolloError.InvalidDerivationPath("Derivation path must be a string")
} else {
"m/$index'/0'/0'"
@@ -143,4 +146,52 @@ class ApolloImpl : Apollo {
}
throw ApolloError.InvalidKeyType(TypeKey().property, KeyTypes.values().map { it.type }.toTypedArray())
}

override fun isPrivateKeyData(identifier: String, data: ByteArray): Boolean {
return identifier.endsWith("priv")
}

override fun isPublicKeyData(identifier: String, data: ByteArray): Boolean {
return identifier.endsWith("pub")
}

override fun restorePrivateKey(key: StorableKey): PrivateKey {
return when (key.restorationIdentifier) {
"secp256k1+priv" -> {
Secp256k1PrivateKey(key.storableData)
}

"x25519+priv" -> {
X25519PrivateKey(key.storableData)
}

"ed25519+priv" -> {
Ed25519PrivateKey(key.storableData)
}

else -> {
throw ApolloError.RestorationFailedNoIdentifierOrInvalid()
}
}
}

override fun restorePublicKey(key: StorableKey): PublicKey {
return when (key.restorationIdentifier) {
"secp256k1+pub" -> {
Secp256k1PublicKey(key.storableData)
}

"x25519+pub" -> {
X25519PublicKey(key.storableData)
}

"ed25519+pub" -> {
Ed25519PublicKey(key.storableData)
}

else -> {
throw ApolloError.RestorationFailedNoIdentifierOrInvalid()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -3,13 +3,14 @@ package io.iohk.atala.prism.walletsdk.domain.buildingblocks
import io.iohk.atala.prism.apollo.derivation.MnemonicLengthException
import io.iohk.atala.prism.walletsdk.domain.models.Seed
import io.iohk.atala.prism.walletsdk.domain.models.SeedWords
import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.KeyRestoration
import io.iohk.atala.prism.walletsdk.domain.models.keyManagement.PrivateKey
import kotlin.jvm.Throws

/**
* Apollo defines the set of cryptographic operations that are used in the Atala PRISM.
*/
interface Apollo {
interface Apollo : KeyRestoration {

/**
* Creates a random set of mnemonic phrases that can be used as a seed for generating
Original file line number Diff line number Diff line change
@@ -16,7 +16,8 @@ abstract interface Error {
* This object may include an error code, an error message, and possibly an array of underlying errors. If the error
* received does not conform to the [Error] interface, it will be classified as an [UnknownPrismError].
*/
abstract class UnknownPrismError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : Error, Throwable(message, cause) {
abstract class UnknownPrismError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : Error,
Throwable(message, cause) {

override val code: Int?
get() = null
@@ -36,7 +37,8 @@ abstract class UnknownPrismError @JvmOverloads constructor(message: String? = nu
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
abstract class KnownPrismError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : Error, Throwable(message, cause) {
abstract class KnownPrismError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : Error,
Throwable(message, cause) {
override val code: Int?
get() = null
override val message: String?
@@ -54,7 +56,8 @@ abstract class KnownPrismError @JvmOverloads constructor(message: String? = null
* This object may include an error code, an error message, and possibly an array of underlying errors.
* If the error received does not conform to the [KnownPrismError], it will be classified as an [UnknownPrismError].
*/
abstract class UnknownError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : UnknownPrismError(message, cause) {
abstract class UnknownError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) :
UnknownPrismError(message, cause) {

class SomethingWentWrongError(
message: String? = null,
@@ -78,7 +81,8 @@ abstract class UnknownError @JvmOverloads constructor(message: String? = null, c
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class CommonError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {
sealed class CommonError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) :
KnownPrismError(message, cause) {
class InvalidURLError(val url: String) : CommonError() {
override val code: Int
get() = -2
@@ -103,7 +107,8 @@ sealed class CommonError @JvmOverloads constructor(message: String? = null, caus
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class ApolloError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {
sealed class ApolloError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) :
KnownPrismError(message, cause) {
class InvalidMnemonicWord(private val invalidWords: Array<String>? = null) : ApolloError() {
override val code: Int
get() = 11
@@ -180,6 +185,14 @@ sealed class ApolloError @JvmOverloads constructor(message: String? = null, caus
override val message: String
get() = invalidMessage
}

class RestorationFailedNoIdentifierOrInvalid() : ApolloError() {

override val code: Int
get() = 20
override val message: String
get() = "Restoration failed: no identifier or invalid"
}
}

/**
@@ -189,7 +202,8 @@ sealed class ApolloError @JvmOverloads constructor(message: String? = null, caus
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class CastorError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {
sealed class CastorError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) :
KnownPrismError(message, cause) {
class KeyCurveNotSupported(val curve: String) : CastorError() {
override val code: Int
get() = 21
@@ -276,7 +290,8 @@ sealed class CastorError @JvmOverloads constructor(message: String? = null, caus
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class MercuryError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {
sealed class MercuryError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) :
KnownPrismError(message, cause) {

class NoDIDReceiverSetError : MercuryError() {
override val code: Int
@@ -349,7 +364,8 @@ sealed class MercuryError @JvmOverloads constructor(message: String? = null, cau
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class PlutoError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {
sealed class PlutoError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) :
KnownPrismError(message, cause) {
class MissingDataPersistence(val type: String, private val affecting: String) :
PlutoError() {
override val code: Int
@@ -425,7 +441,8 @@ sealed class PlutoError @JvmOverloads constructor(message: String? = null, cause
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class PolluxError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {
sealed class PolluxError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) :
KnownPrismError(message, cause) {
class InvalidPrismDID : PolluxError() {
override val code: Int
get() = 53
@@ -434,7 +451,8 @@ sealed class PolluxError @JvmOverloads constructor(message: String? = null, caus
get() = "To create a JWT presentation a Prism DID is required"
}

class InvalidCredentialError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : PolluxError(message, cause) {
class InvalidCredentialError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) :
PolluxError(message, cause) {
override val code: Int
get() = 51

@@ -466,7 +484,10 @@ sealed class PolluxError @JvmOverloads constructor(message: String? = null, caus
get() = "No domain or challenge found as part of the offer json"
}

class InvalidCredentialDefinitionError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : PolluxError(message, cause) {
class InvalidCredentialDefinitionError @JvmOverloads constructor(
message: String? = null,
cause: Throwable? = null
) : PolluxError(message, cause) {
override val code: Int
get() = 56

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.iohk.atala.prism.walletsdk.domain.models.keyManagement

interface KeyRestoration {

fun isPrivateKeyData(identifier: String, data: ByteArray): Boolean

fun isPublicKeyData(identifier: String, data: ByteArray): Boolean

fun restorePrivateKey(key: StorableKey): PrivateKey

fun restorePublicKey(key: StorableKey): PublicKey
}