Skip to content

Commit

Permalink
fix: jsonld context loading (#358)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeplotean committed Nov 10, 2023
1 parent e567ba4 commit f748423
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 9 deletions.
1 change: 1 addition & 0 deletions service-matrix.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
id.walt.services.ecosystems.essif.didebsi.DidEbsiService=id.walt.services.ecosystems.essif.didebsi.WaltIdDidEbsiService
id.walt.services.ecosystems.essif.jsonrpc.JsonRpcService=id.walt.services.ecosystems.essif.jsonrpc.WaltIdJsonRpcService
id.walt.services.vc.JsonLdCredentialService=id.walt.services.vc.WaltIdJsonLdCredentialService
id.walt.credentials.jsonld.JsonLdDocumentLoaderService=id.walt.credentials.jsonld.LocalJsonLdDocumentLoaderService
id.walt.services.vc.JwtCredentialService=id.walt.services.vc.WaltIdJwtCredentialService
id.walt.services.crypto.CryptoService=id.walt.services.crypto.SunCryptoService
id.walt.services.keystore.KeyStoreService=id.walt.services.keystore.SqlKeyStoreService
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package id.walt.credentials.jsonld

import com.apicatalog.jsonld.loader.DocumentLoader
import id.walt.servicematrix.ServiceProvider
import id.walt.servicematrix.ServiceRegistry
import id.walt.services.WaltIdService

abstract class JsonLdDocumentLoaderService: WaltIdService() {

override val implementation: JsonLdDocumentLoaderService get() = serviceImplementation()

abstract val documentLoader: DocumentLoader

companion object : ServiceProvider {
override fun getService() = ServiceRegistry.getService(JsonLdDocumentLoaderService::class)
override fun defaultImplementation() = LocalJsonLdDocumentLoaderService()

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package id.walt.credentials.jsonld

import com.apicatalog.jsonld.loader.DocumentLoader

class LocalJsonLdDocumentLoaderService : JsonLdDocumentLoaderService() {
override val documentLoader: DocumentLoader
get() = VerifiableCredentialContexts.DOCUMENT_LOADER
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package id.walt.credentials.jsonld

import com.apicatalog.jsonld.loader.DocumentLoader
import info.weboftrust.ldsignatures.jsonld.LDSecurityContexts

class RemoteJsonLdDocumentLoaderService : JsonLdDocumentLoaderService() {
override val documentLoader: DocumentLoader
get() = LDSecurityContexts.DOCUMENT_LOADER
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package id.walt.credentials.jsonld

import com.apicatalog.jsonld.document.JsonDocument
import com.apicatalog.jsonld.http.media.MediaType
import com.apicatalog.jsonld.loader.DocumentLoader
import foundation.identity.jsonld.ConfigurableDocumentLoader
import info.weboftrust.ldsignatures.jsonld.LDSecurityContexts
import java.net.URI
import java.util.*

object VerifiableCredentialContexts {
val DOCUMENT_LOADER: DocumentLoader by lazy { ConfigurableDocumentLoader(CONTEXTS) }
private val CONTEXTS: Map<URI, JsonDocument> by lazy {
val map = LDSecurityContexts.CONTEXTS
runCatching { loadContextFiles() }.onSuccess {
map.putAll(it)
}
for ((key, value) in map) {
value.documentUrl = key
}
map
}
private val JSONLD_CONTEXT_W3C_2018_CREDENTIALS_V1 = URI.create("https://www.w3.org/2018/credentials/v1")

private fun loadContextFiles() = mapOf(
JSONLD_CONTEXT_W3C_2018_CREDENTIALS_V1 to JsonDocument.of(
MediaType.JSON_LD, Objects.requireNonNull(
VerifiableCredentialContexts::class.java.classLoader.getResourceAsStream("credentials-v1.jsonld")
)
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ enum class VerificationType {
@Serializable
data class VerificationResult(val verified: Boolean, val verificationType: VerificationType)

abstract class JsonLdCredentialService : WaltIdService() {
abstract class JsonLdCredentialService() : WaltIdService() {
override val implementation get() = serviceImplementation<JsonLdCredentialService>()

open fun sign(jsonCred: String, config: ProofConfig): String = implementation.sign(jsonCred, config)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import foundation.identity.jsonld.ConfigurableDocumentLoader
import foundation.identity.jsonld.JsonLDException
import foundation.identity.jsonld.JsonLDObject
import id.walt.auditor.VerificationPolicyResult
import id.walt.credentials.jsonld.JsonLdDocumentLoaderService
import id.walt.credentials.w3c.*
import id.walt.credentials.w3c.schema.SchemaValidatorFactory
import id.walt.crypto.Key
Expand All @@ -19,7 +20,6 @@ import id.walt.services.keystore.KeyStoreService
import id.walt.signatory.ProofConfig
import id.walt.signatory.ProofType
import info.weboftrust.ldsignatures.LdProof
import info.weboftrust.ldsignatures.jsonld.LDSecurityContexts
import info.weboftrust.ldsignatures.verifier.LdVerifier
import mu.KotlinLogging
import org.json.JSONObject
Expand All @@ -31,10 +31,10 @@ import java.util.*

private val log = KotlinLogging.logger {}

open class WaltIdJsonLdCredentialService : JsonLdCredentialService() {
open class WaltIdJsonLdCredentialService() : JsonLdCredentialService() {

private val keyStore: KeyStoreService
get() = ContextManager.keyStore
private val keyStore: KeyStoreService get() = ContextManager.keyStore
private val documentLoaderService: JsonLdDocumentLoaderService get() = JsonLdDocumentLoaderService.getService()

init {
Ed25519Provider.set(TinkEd25519Provider())
Expand Down Expand Up @@ -109,13 +109,13 @@ open class WaltIdJsonLdCredentialService : JsonLdCredentialService() {
log.debug { "Signing jsonLd object with: issuerDid (${config.issuerDid}), domain (${config.domain}), nonce (${config.nonce}" }

val jsonLdObject: JsonLDObject = JsonLDObject.fromJson(jsonCred)
val confLoader = LDSecurityContexts.DOCUMENT_LOADER as ConfigurableDocumentLoader
val confLoader = documentLoaderService.documentLoader as ConfigurableDocumentLoader

confLoader.isEnableHttp = true
confLoader.isEnableHttps = true
confLoader.isEnableFile = true
confLoader.isEnableLocalCache = true
jsonLdObject.documentLoader = LDSecurityContexts.DOCUMENT_LOADER
jsonLdObject.documentLoader = documentLoaderService.documentLoader

val vm = config.issuerVerificationMethod ?: config.issuerDid
val key = keyStore.load(vm)
Expand Down Expand Up @@ -182,7 +182,7 @@ open class WaltIdJsonLdCredentialService : JsonLdCredentialService() {

log.debug { "Verification key for: $vm is: $publicKey" }

val confLoader = LDSecurityContexts.DOCUMENT_LOADER as ConfigurableDocumentLoader
val confLoader = documentLoaderService.documentLoader as ConfigurableDocumentLoader

confLoader.isEnableHttp = true
confLoader.isEnableHttps = true
Expand All @@ -192,7 +192,7 @@ open class WaltIdJsonLdCredentialService : JsonLdCredentialService() {
log.debug { "Document loader config: isEnableHttp (${confLoader.isEnableHttp}), isEnableHttps (${confLoader.isEnableHttps}), isEnableFile (${confLoader.isEnableFile}), isEnableLocalCache (${confLoader.isEnableLocalCache})" }

val jsonLdObject = JsonLDObject.fromJson(vcOrVp)
jsonLdObject.documentLoader = LDSecurityContexts.DOCUMENT_LOADER
jsonLdObject.documentLoader = documentLoaderService.documentLoader
log.debug { "Decoded Json LD object: $jsonLdObject" }

val ldProof = LdProof.getFromJsonLDObject(jsonLdObject)
Expand Down
237 changes: 237 additions & 0 deletions src/main/resources/credentials-v1.jsonld
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
{
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"VerifiableCredential": {
"@id": "https://www.w3.org/2018/credentials#VerifiableCredential",
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"cred": "https://www.w3.org/2018/credentials#",
"sec": "https://w3id.org/security#",
"xsd": "http://www.w3.org/2001/XMLSchema#",

"credentialSchema": {
"@id": "cred:credentialSchema",
"@type": "@id",
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"cred": "https://www.w3.org/2018/credentials#",

"JsonSchemaValidator2018": "cred:JsonSchemaValidator2018"
}
},
"credentialStatus": {"@id": "cred:credentialStatus", "@type": "@id"},
"credentialSubject": {"@id": "cred:credentialSubject", "@type": "@id"},
"evidence": {"@id": "cred:evidence", "@type": "@id"},
"expirationDate": {"@id": "cred:expirationDate", "@type": "xsd:dateTime"},
"holder": {"@id": "cred:holder", "@type": "@id"},
"issued": {"@id": "cred:issued", "@type": "xsd:dateTime"},
"issuer": {"@id": "cred:issuer", "@type": "@id"},
"issuanceDate": {"@id": "cred:issuanceDate", "@type": "xsd:dateTime"},
"proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"},
"refreshService": {
"@id": "cred:refreshService",
"@type": "@id",
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"cred": "https://www.w3.org/2018/credentials#",

"ManualRefreshService2018": "cred:ManualRefreshService2018"
}
},
"termsOfUse": {"@id": "cred:termsOfUse", "@type": "@id"},
"validFrom": {"@id": "cred:validFrom", "@type": "xsd:dateTime"},
"validUntil": {"@id": "cred:validUntil", "@type": "xsd:dateTime"}
}
},

"VerifiablePresentation": {
"@id": "https://www.w3.org/2018/credentials#VerifiablePresentation",
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"cred": "https://www.w3.org/2018/credentials#",
"sec": "https://w3id.org/security#",

"holder": {"@id": "cred:holder", "@type": "@id"},
"proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"},
"verifiableCredential": {"@id": "cred:verifiableCredential", "@type": "@id", "@container": "@graph"}
}
},

"EcdsaSecp256k1Signature2019": {
"@id": "https://w3id.org/security#EcdsaSecp256k1Signature2019",
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"sec": "https://w3id.org/security#",
"xsd": "http://www.w3.org/2001/XMLSchema#",

"challenge": "sec:challenge",
"created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"},
"domain": "sec:domain",
"expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"},
"jws": "sec:jws",
"nonce": "sec:nonce",
"proofPurpose": {
"@id": "sec:proofPurpose",
"@type": "@vocab",
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"sec": "https://w3id.org/security#",

"assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"},
"authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"}
}
},
"proofValue": "sec:proofValue",
"verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"}
}
},

"EcdsaSecp256r1Signature2019": {
"@id": "https://w3id.org/security#EcdsaSecp256r1Signature2019",
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"sec": "https://w3id.org/security#",
"xsd": "http://www.w3.org/2001/XMLSchema#",

"challenge": "sec:challenge",
"created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"},
"domain": "sec:domain",
"expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"},
"jws": "sec:jws",
"nonce": "sec:nonce",
"proofPurpose": {
"@id": "sec:proofPurpose",
"@type": "@vocab",
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"sec": "https://w3id.org/security#",

"assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"},
"authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"}
}
},
"proofValue": "sec:proofValue",
"verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"}
}
},

"Ed25519Signature2018": {
"@id": "https://w3id.org/security#Ed25519Signature2018",
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"sec": "https://w3id.org/security#",
"xsd": "http://www.w3.org/2001/XMLSchema#",

"challenge": "sec:challenge",
"created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"},
"domain": "sec:domain",
"expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"},
"jws": "sec:jws",
"nonce": "sec:nonce",
"proofPurpose": {
"@id": "sec:proofPurpose",
"@type": "@vocab",
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"sec": "https://w3id.org/security#",

"assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"},
"authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"}
}
},
"proofValue": "sec:proofValue",
"verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"}
}
},

"RsaSignature2018": {
"@id": "https://w3id.org/security#RsaSignature2018",
"@context": {
"@version": 1.1,
"@protected": true,

"challenge": "sec:challenge",
"created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"},
"domain": "sec:domain",
"expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"},
"jws": "sec:jws",
"nonce": "sec:nonce",
"proofPurpose": {
"@id": "sec:proofPurpose",
"@type": "@vocab",
"@context": {
"@version": 1.1,
"@protected": true,

"id": "@id",
"type": "@type",

"sec": "https://w3id.org/security#",

"assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"},
"authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"}
}
},
"proofValue": "sec:proofValue",
"verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"}
}
},

"proof": {"@id": "https://w3id.org/security#proof", "@type": "@id", "@container": "@graph"}
}
}

0 comments on commit f748423

Please sign in to comment.