Skip to content

Commit

Permalink
fix: restore process from swift/ts jwe
Browse files Browse the repository at this point in the history
Signed-off-by: Cristian G <cristian.castro@iohk.io>
  • Loading branch information
cristianIOHK committed Jul 16, 2024
1 parent da747c5 commit 78b0e50
Show file tree
Hide file tree
Showing 11 changed files with 244 additions and 35 deletions.
2 changes: 2 additions & 0 deletions edge-agent-sdk/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ kotlin {
implementation("com.apicatalog:titanium-json-ld-jre8:1.4.0")
implementation("org.glassfish:jakarta.json:2.0.1")
implementation("io.setl:rdf-urdna:1.3")

implementation("app.cash.sqldelight:sqlite-driver:2.0.1")
}
}
val commonTest by getting {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,5 +386,13 @@ interface Pluto {

fun getAllKeysForBackUp(): Flow<List<BackupV0_0_1.Key>>

/**
* Retrieves a list of all private keys.
*
* @return A flow that emits a list of nullable [PrivateKey] objects. In case a private key is not found, null is emitted.
*/
fun getAllPrivateKeys(): Flow<List<PrivateKey?>>


suspend fun start(context: Any? = null)
}
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,7 @@ class EdgeAgent {
val backupObject = Json.decodeFromString<BackupV0_0_1>(json)

// 7. Restore the pluto instance
val restoreTask = PlutoRestoreTask(pluto, backupObject)
val restoreTask = PlutoRestoreTask(castor, pluto, backupObject)
restoreTask.run()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.hyperledger.identus.walletsdk.pluto

import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver
import org.hyperledger.identus.walletsdk.SdkPlutoDb
import org.hyperledger.identus.walletsdk.pluto.data.DbConnection

class DbConnectionInMemory : DbConnection {
override var driver: SqlDriver? = null

override suspend fun connectDb(context: Any?): SqlDriver {
val driver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)
SdkPlutoDb.Schema.create(driver)
this.driver = driver
return driver
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1235,4 +1235,33 @@ class PlutoImpl(private val connection: DbConnection) : Pluto {
val keys = keysWithDID + keysWithNoDID
return flowOf(keys)
}

override fun getAllPrivateKeys(): Flow<List<PrivateKey?>> {
return getInstance().privateKeyQueries
.fetchAllPrivateKeys()
.asFlow()
.map {
it.executeAsList()
.map { storableKey ->
when (storableKey.restorationIdentifier) {
"secp256k1+priv" -> {
Secp256k1PrivateKey(storableKey.data_.base64UrlDecodedBytes)
}

"ed25519+priv" -> {
Ed25519PrivateKey(storableKey.data_.base64UrlDecodedBytes)
}

"x25519+priv" -> {
X25519PrivateKey(storableKey.data_.base64UrlDecodedBytes)
}

else -> {
throw PlutoError.InvalidRestorationIdentifier()
}
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
package org.hyperledger.identus.walletsdk.pluto

import java.util.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
Expand All @@ -25,10 +28,12 @@ import org.hyperledger.identus.apollo.base64.base64UrlDecodedBytes
import org.hyperledger.identus.walletsdk.apollo.utils.Ed25519PrivateKey
import org.hyperledger.identus.walletsdk.apollo.utils.Secp256k1PrivateKey
import org.hyperledger.identus.walletsdk.apollo.utils.X25519PrivateKey
import org.hyperledger.identus.walletsdk.domain.buildingblocks.Castor
import org.hyperledger.identus.walletsdk.domain.buildingblocks.Pluto
import org.hyperledger.identus.walletsdk.domain.models.AttachmentDescriptor
import org.hyperledger.identus.walletsdk.domain.models.Curve
import org.hyperledger.identus.walletsdk.domain.models.DID
import org.hyperledger.identus.walletsdk.domain.models.DIDDocument
import org.hyperledger.identus.walletsdk.domain.models.Message
import org.hyperledger.identus.walletsdk.domain.models.UnknownError
import org.hyperledger.identus.walletsdk.domain.models.keyManagement.IndexKey
Expand All @@ -51,6 +56,7 @@ import kotlin.time.toDuration
* @param backup The Pluto backup object containing the data to be restored.
*/
open class PlutoRestoreTask(
private val castor: Castor,
private val pluto: Pluto,
private val backup: BackupV0_0_1
) {
Expand All @@ -60,13 +66,15 @@ open class PlutoRestoreTask(
* This method should be called to initialize or restore the necessary components.
*/
fun run() {
restoreCredentials()
restoreDidPairs()
restoreKeys()
restoreLinkSecret()
restoreMessages()
restoreMediators()
restoreDids()
CoroutineScope(Dispatchers.Default).launch {
restoreCredentials()
restoreDidPairs()
restoreKeys()
restoreLinkSecret()
restoreMessages()
restoreMediators()
restoreDids()
}
}

/**
Expand Down Expand Up @@ -140,7 +148,7 @@ open class PlutoRestoreTask(
*
* @throws UnknownError.SomethingWentWrongError if the key is invalid, it does not have index or DID
*/
private fun restoreKeys() {
private suspend fun restoreKeys() {
this.backup.keys.map {
val jwkJson = it.key.base64UrlDecoded
val jwk = Json.decodeFromString<JWK>(jwkJson)
Expand Down Expand Up @@ -173,21 +181,20 @@ open class PlutoRestoreTask(
}.forEach {
if (it.third is DID) {
if (it.third.toString().contains("peer")) {
val origDid = (it.third as DID)
val did = if (origDid.toString().contains("#")) {
val splits = origDid.toString().split("#")
DID(splits[0])
val did = (it.third as DID)
val keyId = did.toString()
if (keyId.contains("#")) {
pluto.storePrivateKeys(
it.first as StorableKey,
did,
(it.first.keySpecification[IndexKey().property])?.toInt(),
keyId
)
} else {
DID(origDid.toString())
// This else is for jwe coming from TS/Swift which do not use didUrl for private key id
// and is a requirement for us.
resolveDIDForPrivateKey(keyId, it.first)
}
val keyId = origDid.toString()
pluto.storePrivateKeys(
it.first as StorableKey,
did,
(it.first.keySpecification[IndexKey().property])?.toInt(),
keyId
)
// pluto.storePeerDID(did)
} else {
pluto.storePrismDIDAndPrivateKeys(
it.third as DID,
Expand All @@ -202,6 +209,35 @@ open class PlutoRestoreTask(
}
}

private suspend fun resolveDIDForPrivateKey(did: String, privateKey: PrivateKey) {
val document = castor.resolveDID(did)
val listOfVerificationMethods: MutableList<DIDDocument.VerificationMethod> =
mutableListOf()
document.coreProperties.forEach {
if (it is DIDDocument.Authentication) {
listOfVerificationMethods.addAll(it.verificationMethods)
}
if (it is DIDDocument.KeyAgreement) {
listOfVerificationMethods.addAll(it.verificationMethods)
}
}
val verificationMethods =
DIDDocument.VerificationMethods(listOfVerificationMethods.toTypedArray())

verificationMethods.values.forEach {
if (it.type.contains("X25519") && privateKey is X25519PrivateKey ||
it.type.contains("Ed25519") && privateKey is Ed25519PrivateKey
) {
pluto.storePrivateKeys(
privateKey as StorableKey,
DID(did),
(privateKey.keySpecification[IndexKey().property])?.toInt(),
it.id.toString()
)
}
}
}

/**
* Restores the link secret stored in the backup.
* If the backup object has a link secret, it is decoded from base64 URL encoding and stored using the pluto.storeLinkSecret method.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,8 @@ class PlutoMock : Pluto {
override suspend fun start(context: Any?) {
TODO("Not yet implemented")
}

override fun getAllPrivateKeys(): Flow<List<PrivateKey?>> {
TODO("Not yet implemented")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,8 @@ class PlutoMock : Pluto {
override suspend fun start(context: Any?) {
TODO("Not yet implemented")
}

override fun getAllPrivateKeys(): Flow<List<PrivateKey?>> {
TODO("Not yet implemented")
}
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion sampleapp/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<string name="mediator_did">Mediator DID:</string>
<string name="agent_status_label">Agent status:</string>
<string name="mediator_did_value">
did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHBzOi8vc2l0LXByaXNtLW1lZGlhdG9yLmF0YWxhcHJpc20uaW8iLCJhIjpbImRpZGNvbW0vdjIiXX19.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6IndzczovL3NpdC1wcmlzbS1tZWRpYXRvci5hdGFsYXByaXNtLmlvL3dzIiwiYSI6WyJkaWRjb21tL3YyIl19fQ
did:peer:2.Ez6LSghwSE437wnDE1pt3X6hVDUQzSjsHzinpX3XFvMjRAm7y.Vz6Mkhh1e5CEYYq6JBUcTZ6Cp2ranCWRrv7Yax3Le4N59R6dd.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6Imh0dHBzOi8vc3RhYmxlLW1lZGlhdG9yLmF0YWxhcHJpc20uaW8iLCJhIjpbImRpZGNvbW0vdjIiXX19.SeyJ0IjoiZG0iLCJzIjp7InVyaSI6IndzczovL3N0YWJsZS1tZWRpYXRvci5hdGFsYXByaXNtLmlvL3dzIiwiYSI6WyJkaWRjb21tL3YyIl19fQ
</string>
<string name="credentials_label">Credentials</string>
<string name="host_label">Host:</string>
Expand Down

0 comments on commit 78b0e50

Please sign in to comment.