Skip to content

Commit

Permalink
Dev (#2)
Browse files Browse the repository at this point in the history
* feat(model): make data classes serializable

data classes are not serializable.  Serialization is needed to export Wallet to a json file

- Add Serializable annotation
- modify updateWallet to use upsert (update/insert)

* feat(dlt): add public and private key to DID

Public and private keys are not stored on the DID. Add required code to store them as hex strings

* feat(didpeer): add DIDPeer functions

- add createPeerDID
- add resolvePeerDID
- add pack
- add unpack

* feat: update dependencies

* fix(didpeer): fix routing keys

* refactor(qr): clean code

* feat(dlt,model): add addKey and revokeKey functionality

* refactor(dlt,storage): add comments, refactor exception handling

* refactor(dlt,storage): add comments, refactor exception handling

* refactor(dlt,model,storage): refactor model and credential management

* refactor(DLT,Storage,Model): add comments, refactor exception handling

* feat(config,storage): recfactor db name handling

* feat(dlt): return prism DID document as json

* refactor(Storage,Model): add comments

* refactor(Storage): change exception type

* fix(gradle): change env vars

remove hyphen from env vars

* build(gradle): Change version
  • Loading branch information
Essbante authored Mar 9, 2022
1 parent 2ed36d3 commit 8114f82
Show file tree
Hide file tree
Showing 9 changed files with 668 additions and 198 deletions.
21 changes: 12 additions & 9 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
}

group = "com.rootsid.wal"
version = "1.0-SNAPSHOT"
version = "1.0.0"

repositories {
mavenCentral()
Expand All @@ -23,16 +23,15 @@ repositories {

dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.10")

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2")

implementation("org.litote.kmongo:kmongo:4.4.0")

// needed for cryptography primitives implementation
implementation("io.iohk.atala:prism-crypto:1.2.0")
implementation("io.iohk.atala:prism-identity:1.2.0")
implementation("io.iohk.atala:prism-credentials:1.2.0")
implementation("io.iohk.atala:prism-api:1.2.0")
implementation("io.iohk.atala:prism-crypto:1.3.0")
implementation("io.iohk.atala:prism-identity:1.3.0")
implementation("io.iohk.atala:prism-credentials:1.3.0")
implementation("io.iohk.atala:prism-api:1.3.0")

// Fixes a build issue
implementation("com.soywiz.korlibs.krypto:krypto-jvm:2.0.6")
Expand All @@ -43,6 +42,10 @@ dependencies {
implementation("org.boofcv:boofcv-kotlin:0.39.1")
implementation("org.boofcv:boofcv-WebcamCapture:0.39.1")

// DIDComm
implementation("org.didcommx:didcomm:0.3.0")
implementation("org.didcommx:peerdid:0.3.0")

implementation("org.junit.jupiter:junit-jupiter:5.8.2")
}

Expand All @@ -59,8 +62,8 @@ publishing {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/roots-id/wal-library")
credentials {
username = System.getenv("ROOTS-ID_USER")
password = System.getenv("ROOTS-ID_PASSWORD")
username = System.getenv("ROOTSID_USER")
password = System.getenv("ROOTSID_PASSWORD")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.rootsid.wal.library

/**
* Constant
*
* @constructor Create empty Constant
*/
object Constant {
const val MNEMONIC_SEPARATOR = ","
const val TESTNET_URL = "https://explorer.cardano-testnet.iohkdev.io/en/transaction?id="
}
package com.rootsid.wal.library

/**
* Constant
*
* @constructor Create empty Constant
*/
object Config {
const val MNEMONIC_SEPARATOR = ","
const val TESTNET_URL = "https://explorer.cardano-testnet.iohkdev.io/en/transaction?id="
var DB_NAME = "wal"
}
57 changes: 57 additions & 0 deletions src/main/kotlin/com/rootsid/wal/library/DIDDocResolverPeerDID.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.rootsid.wal.library

import org.didcommx.didcomm.common.VerificationMaterial
import org.didcommx.didcomm.common.VerificationMaterialFormat
import org.didcommx.didcomm.common.VerificationMethodType
import org.didcommx.didcomm.diddoc.DIDCommService
import org.didcommx.didcomm.diddoc.DIDDoc
import org.didcommx.didcomm.diddoc.DIDDocResolver
import org.didcommx.didcomm.diddoc.VerificationMethod
import org.didcommx.didcomm.utils.toJson
import org.didcommx.peerdid.DIDCommServicePeerDID
import org.didcommx.peerdid.DIDDocPeerDID
import org.didcommx.peerdid.VerificationMaterialFormatPeerDID
import org.didcommx.peerdid.resolvePeerDID
import java.util.Optional

class DIDDocResolverPeerDID : DIDDocResolver {

override fun resolve(did: String): Optional<DIDDoc> {
// request DID Doc in JWK format
val didDocJson = resolvePeerDID(did, format = VerificationMaterialFormatPeerDID.JWK)
val didDoc = DIDDocPeerDID.fromJson(didDocJson)

didDoc.keyAgreement
return Optional.ofNullable(
DIDDoc(
did = did,
keyAgreements = didDoc.agreementKids,
authentications = didDoc.authenticationKids,
verificationMethods = (didDoc.authentication + didDoc.keyAgreement).map {
VerificationMethod(
id = it.id,
type = VerificationMethodType.JSON_WEB_KEY_2020,
controller = it.controller,
verificationMaterial = VerificationMaterial(
format = VerificationMaterialFormat.JWK,
value = toJson(it.verMaterial.value)
)
)
},
didCommServices = didDoc.service?.mapNotNull {
when (it) {
is DIDCommServicePeerDID ->
DIDCommService(
id = it.id,
serviceEndpoint = it.serviceEndpoint,
routingKeys = it.routingKeys,
accept = it.accept
)
else -> null
}
}
?: emptyList()
)
)
}
}
120 changes: 120 additions & 0 deletions src/main/kotlin/com/rootsid/wal/library/DIDPeer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package com.rootsid.wal.library

import org.didcommx.didcomm.DIDComm
import org.didcommx.didcomm.message.Message
import org.didcommx.didcomm.model.PackEncryptedParams
import org.didcommx.didcomm.model.PackEncryptedResult
import org.didcommx.didcomm.model.UnpackParams
import org.didcommx.didcomm.secret.generateEd25519Keys
import org.didcommx.didcomm.secret.generateX25519Keys
import org.didcommx.didcomm.secret.jwkToSecret
import org.didcommx.didcomm.utils.divideDIDFragment
import org.didcommx.didcomm.utils.toJson
import org.didcommx.peerdid.*
import java.util.UUID

fun createPeerDID(
authKeysCount: Int = 1,
agreementKeysCount: Int = 1,
serviceEndpoint: String? = null,
serviceRoutingKeys: List<String>,
secretResolver: SecretResolver
): String {
// 1. generate keys in JWK format
val x25519keyPairs = (1..agreementKeysCount).map { generateX25519Keys() }
val ed25519keyPairs = (1..authKeysCount).map { generateEd25519Keys() }

// 2. prepare the keys for peer DID lib
val authPublicKeys = ed25519keyPairs.map {
VerificationMaterialAuthentication(
format = VerificationMaterialFormatPeerDID.JWK,
type = VerificationMethodTypeAuthentication.JSON_WEB_KEY_2020,
value = it.public
)
}
val agreemPublicKeys = x25519keyPairs.map {
VerificationMaterialAgreement(
format = VerificationMaterialFormatPeerDID.JWK,
type = VerificationMethodTypeAgreement.JSON_WEB_KEY_2020,
value = it.public
)
}

// 3. generate service
val service = serviceEndpoint?.let {
toJson(
DIDCommServicePeerDID(
id = "new-id",
type = SERVICE_DIDCOMM_MESSAGING,
serviceEndpoint = it,
routingKeys = serviceRoutingKeys,
accept = listOf("didcomm/v2")
).toDict()
)
}

// 4. call peer DID lib
// if we have just one key (auth), then use numalg0 algorithm
// otherwise use numalg2 algorithm
val did = if (authPublicKeys.size == 1 && agreemPublicKeys.isEmpty() && service.isNullOrEmpty())
createPeerDIDNumalgo0(authPublicKeys[0])
else
createPeerDIDNumalgo2(
signingKeys = authPublicKeys,
encryptionKeys = agreemPublicKeys,
service = service
)

// 5. set KIDs as in DID DOC for secrets and store the secret in the secrets resolver
val didDoc = DIDDocPeerDID.fromJson(resolvePeerDID(did, VerificationMaterialFormatPeerDID.JWK))
didDoc.agreementKids.zip(x25519keyPairs).forEach {
val privateKey = it.second.private.toMutableMap()
privateKey["kid"] = it.first
secretResolver.addKey(jwkToSecret(privateKey))
}
didDoc.authenticationKids.zip(ed25519keyPairs).forEach {
val privateKey = it.second.private.toMutableMap()
privateKey["kid"] = it.first
secretResolver.addKey(jwkToSecret(privateKey))
}
return did
}

fun resolvePeerDID(did: String, format: VerificationMaterialFormatPeerDID) =
org.didcommx.peerdid.resolvePeerDID(did, format)

fun pack(
data: String,
to: String,
from: String? = null,
signFrom: String? = null,
protectSender: Boolean = true,
secretsResolver: SecretResolver
): PackEncryptedResult {
val didComm = DIDComm(DIDDocResolverPeerDID(), secretsResolver)
val message = Message.builder(
id = UUID.randomUUID().toString(),
body = mapOf("msg" to data),
type = "my-protocol/1.0"
).build()
var builder = PackEncryptedParams
.builder(message, to)
.forward(false)
.protectSenderId(protectSender)
builder = from?.let { builder.from(it) } ?: builder
builder = signFrom?.let { builder.signFrom(it) } ?: builder
val params = builder.build()
return didComm.packEncrypted(params)
}

fun unpack(packedMsg: String, secretResolver: SecretResolver): UnpackResult {
val didComm = DIDComm(DIDDocResolverPeerDID(), secretResolver)
val res = didComm.unpack(UnpackParams.Builder(packedMsg).build())
val msg = res.message.body["msg"].toString()
val to = res.metadata.encryptedTo?.let { divideDIDFragment(it.first()).first() } ?: ""
val from = res.metadata.encryptedFrom?.let { divideDIDFragment(it).first() }
return UnpackResult(
message = msg,
from = from, to = to, res = res
)
}
Loading

0 comments on commit 8114f82

Please sign in to comment.