Skip to content

Commit

Permalink
fix: cheqd import (#308)
Browse files Browse the repository at this point in the history
  • Loading branch information
waltkb authored May 30, 2023
2 parents b5634ce + 285bcc9 commit 1d39563
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 22 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ dependencies {
api("decentralized-identity:jsonld-common-java:1.1.0")
implementation("com.goterl:lazysodium-java:5.1.4")
implementation("net.java.dev.jna:jna:5.12.1")
implementation("com.github.multiformats:java-multibase:v1.1.0")
implementation("com.github.multiformats:java-multibase:v1.1.1")
implementation("com.microsoft.azure:azure-keyvault:1.2.6")
implementation("com.microsoft.azure:azure-client-authentication:1.7.14")
implementation("com.nimbusds:nimbus-jose-jwt:9.30.2")
Expand Down
40 changes: 25 additions & 15 deletions src/main/kotlin/id/walt/services/did/DidService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import id.walt.services.CryptoProvider
import id.walt.services.WaltIdServices
import id.walt.services.context.ContextManager
import id.walt.services.crypto.CryptoService
import id.walt.services.did.resolvers.*
import id.walt.services.did.resolvers.DidResolverFactory
import id.walt.services.ecosystems.cheqd.CheqdService
import id.walt.services.ecosystems.iota.IotaService
import id.walt.services.ecosystems.iota.IotaWrapper
Expand All @@ -24,11 +24,6 @@ import id.walt.services.keystore.KeyType
import id.walt.services.vc.JsonLdCredentialService
import id.walt.signatory.ProofConfig
import io.ipfs.multibase.Multibase
import io.ktor.client.*
import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.util.*
import mu.KotlinLogging
import org.bouncycastle.asn1.edec.EdECObjectIdentifiers
import org.bouncycastle.asn1.x509.AlgorithmIdentifier
Expand Down Expand Up @@ -291,12 +286,14 @@ object DidService {

//region did-resolve
fun resolve(did: String, options: DidOptions? = null): Did = resolve(DidUrl.from(did), options)
fun resolve(didUrl: DidUrl, options: DidOptions? = null): Did = didResolverFactory.create(didUrl.method).resolve(didUrl, options)
fun resolve(didUrl: DidUrl, options: DidOptions? = null): Did =
didResolverFactory.create(didUrl.method).resolve(didUrl, options)
//endregion

//region did-import
fun importDid(did: String) {
val did2 = did.replace("-", ":")
//val did2 = did.replace("-", ":") FIXME
val did2 = did // FIXME
resolveAndStore(did2)

when {
Expand Down Expand Up @@ -452,8 +449,10 @@ object DidService {

vm.publicKeyBase58 ?: return null

if (!setOf(Ed25519VerificationKey2018.name, Ed25519VerificationKey2019.name, Ed25519VerificationKey2020.name).contains(
vm.type
if (vm.type !in setOf(
Ed25519VerificationKey2018.name,
Ed25519VerificationKey2019.name,
Ed25519VerificationKey2020.name
)
) {
log.warn { "Key import does currently not support verification-key algorithm: ${vm.type}" }
Expand All @@ -478,19 +477,30 @@ object DidService {

vm.publicKeyMultibase ?: return null

if (!setOf(Ed25519VerificationKey2018.name, Ed25519VerificationKey2019.name, Ed25519VerificationKey2020.name).contains(
vm.type
if (vm.type !in setOf(
Ed25519VerificationKey2018.name,
Ed25519VerificationKey2019.name,
Ed25519VerificationKey2020.name
)
) {
log.warn { "Key import does currently not support verification-key algorithm: ${vm.type}" }
// TODO: support RSA and Secp256k1
return null
}

val rawMultibaseDecoded = Multibase.decode(vm.publicKeyMultibase)

val multibaseDecoded: ByteArray = when {
rawMultibaseDecoded.size == 34 && did.startsWith("did:cheqd:") ->
rawMultibaseDecoded.drop(2).toByteArray()

else -> rawMultibaseDecoded
}

val keyFactory = KeyFactory.getInstance("Ed25519")

val pubKeyInfo =
SubjectPublicKeyInfo(AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), Multibase.decode(vm.publicKeyMultibase))
val pubKeyInfo = SubjectPublicKeyInfo(AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), multibaseDecoded)

val x509KeySpec = X509EncodedKeySpec(pubKeyInfo.encoded)

val pubKey = keyFactory.generatePublic(x509KeySpec)
Expand Down Expand Up @@ -528,7 +538,7 @@ object DidService {
//endregion

fun isDidEbsiV1(did: String): Boolean = checkIsDidEbsiAndVersion(did, 1)

fun isDidEbsiV2(did: String): Boolean = checkIsDidEbsiAndVersion(did, 2)

private fun checkIsDidEbsiAndVersion(did: String, version: Int): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ object CheqdService {

private const val verificationMethod = "Ed25519VerificationKey2020"
private const val methodSpecificIdAlgo = "uuid"
private const val registrarUrl = "https://registrar.walt.id/cheqd"

//private const val registrarUrl = "https://registrar.walt.id/cheqd"
private const val registrarUrl = "https://did-registrar.cheqd.net"
private const val registrarApiVersion = "1.0"
private const val didCreateUrl =
"$registrarUrl/$registrarApiVersion/did-document?verificationMethod=%s&methodSpecificIdAlgo=%s&network=%s&publicKeyHex=%s"
Expand Down Expand Up @@ -73,7 +75,7 @@ object CheqdService {
} ?: throw IllegalArgumentException("Failed to fetch the did document from cheqd registrar helper")
}

fun deactivateDid(did: String){
fun deactivateDid(did: String) {
val job = initiateDidJob(didCreateUrl, KlaxonWithConverters().toJsonString(JobDeactivateRequest(did)))
?: throw Exception("Failed to initialize the did onboarding process")
val signatures = signPayload(KeyId(""), job)
Expand All @@ -86,11 +88,11 @@ object CheqdService {
?: throw Exception("Failed to finalize the did onboarding process")
}

fun updateDid(did: String){
fun updateDid(did: String) {
TODO()
}

private fun initiateDidJob(url: String, body: String) = let{
private fun initiateDidJob(url: String, body: String) = let {
val response = runBlocking {
client.post(url) {
contentType(ContentType.Application.Json)
Expand All @@ -100,7 +102,7 @@ object CheqdService {
KlaxonWithConverters().parse<JobActionResponse>(response)
}

private fun finalizeDidJob(url: String, jobId: String, verificationMethodId: String, signatures: List<String>) = let{
private fun finalizeDidJob(url: String, jobId: String, verificationMethodId: String, signatures: List<String>) = let {
val actionResponse = runBlocking {
client.post(url) {
contentType(ContentType.Application.Json)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class FileSystemHKVStore(configPath: String) : HKVStoreService() {
private fun dataDirCombinePath(key: Path) = configuration.dataDirectory.combineSafe(key)

companion object {
private const val MAX_KEY_SIZE = 100
private const val MAX_KEY_SIZE = 111
private const val hashMappingDesc = "FileSystemHKVStore hash mappings properties"
}
}
55 changes: 55 additions & 0 deletions src/test/kotlin/id/walt/ecosystems/CheqdTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package id.walt.ecosystems

import id.walt.auditor.Auditor
import id.walt.auditor.policies.SignaturePolicy
import id.walt.credentials.w3c.W3CIssuer
import id.walt.model.DidMethod
import id.walt.servicematrix.ServiceMatrix
import id.walt.services.did.DidService
import id.walt.services.keystore.KeyStoreService
import id.walt.signatory.ProofConfig
import id.walt.signatory.Signatory
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.shouldBe

class CheqdTest : StringSpec({

ServiceMatrix("service-matrix.properties")

var did: String? = null

"Generating fresh did:cheqd" {
println("Generating did:cheqd...")
did = DidService.create(DidMethod.cheqd)
println("Created did: $did")
}

var vc: String? = null

"Create VC with did:cheqd" {
vc = Signatory.getService().issue("VerifiableId", ProofConfig(did!!, did!!), issuer = W3CIssuer(did!!))
println("Generated VC: $vc")
}

"Remove did:cheqd from keystore" {
KeyStoreService.getService().delete(did!!)
println("Deleted: $did")
}

"Test did:cheqd verification" {
val verificationResult = Auditor.getService().verify(vc!!, listOf(SignaturePolicy()))

verificationResult.policyResults.entries.forEach {
if (it.value.isFailure) {
println("ERROR at ${it.key}")
it.value.errors.forEachIndexed { index, throwable ->
println("Error #$index: ${throwable.message}")
throwable.printStackTrace()
}
} else println("OK: ${it.key}")
}
verificationResult.result shouldBe true

}

})

0 comments on commit 1d39563

Please sign in to comment.