Added support for VCDM 2.0

This commit is contained in:
Xavi Aracil 2024-03-21 17:25:15 +01:00
parent c97c455d09
commit be7e496d47
6 changed files with 395 additions and 321 deletions

View File

@ -13,7 +13,7 @@ public class Ed25519Signature2022LdVerifier extends LdVerifier<Ed25519Signature2
public Ed25519Signature2022LdVerifier(ByteVerifier verifier) { public Ed25519Signature2022LdVerifier(ByteVerifier verifier) {
super(SignatureSuites.SIGNATURE_SUITE_ED25519SIGNATURE2022, verifier, new URDNA2015Canonicalizer()); super(SignatureSuites.SIGNATURE_SUITE_ED25519SIGNATURE2022, verifier, new URDNA2015Canonicalizer(Eddsa2022LdProof.builder()));
} }
public Ed25519Signature2022LdVerifier(byte[] publicKey) { public Ed25519Signature2022LdVerifier(byte[] publicKey) {

View File

@ -0,0 +1,53 @@
package org.oneedtech.inspect.vc.verification;
import com.danubetech.keyformats.crypto.ByteVerifier;
import com.danubetech.keyformats.crypto.impl.Ed25519_EdDSA_PublicKeyVerifier;
import com.danubetech.keyformats.jose.JWSAlgorithm;
import info.weboftrust.ldsignatures.LdProof;
import info.weboftrust.ldsignatures.verifier.LdVerifier;
import io.ipfs.multibase.Multibase;
import java.security.GeneralSecurityException;
public class Ed25519Signature2022VCDM20LdVerifier extends LdVerifier<Ed25519Signature2022SignatureSuite> {
public Ed25519Signature2022VCDM20LdVerifier(ByteVerifier verifier) {
super(SignatureSuites.SIGNATURE_SUITE_ED25519SIGNATURE2022, verifier, new URDNA2015Canonicalizer(Eddsa2022v2LdProof.builder()));
}
public Ed25519Signature2022VCDM20LdVerifier(byte[] publicKey) {
this(new Ed25519_EdDSA_PublicKeyVerifier(publicKey));
}
public Ed25519Signature2022VCDM20LdVerifier() {
this((ByteVerifier) null);
}
public static boolean verify(byte[] signingInput, LdProof ldProof, ByteVerifier verifier) throws GeneralSecurityException {
// verify
String proofValue = ldProof.getProofValue();
if (proofValue == null) throw new GeneralSecurityException("No 'proofValue' in proof.");
boolean verify;
byte[] bytes = Multibase.decode(proofValue);
verify = verifier.verify(signingInput, bytes, JWSAlgorithm.EdDSA);
// done
return verify;
}
@Override
public boolean verify(byte[] signingInput, LdProof ldProof) throws GeneralSecurityException {
return verify(signingInput, ldProof, this.getVerifier());
}
}

View File

@ -0,0 +1,49 @@
package org.oneedtech.inspect.vc.verification;
import java.net.URI;
import com.apicatalog.jsonld.loader.DocumentLoader;
import foundation.identity.jsonld.JsonLDObject;
import foundation.identity.jsonld.JsonLDUtils;
import info.weboftrust.ldsignatures.LdProof;
public class Eddsa2022v2LdProof extends LdProof {
public static final URI[] DEFAULT_JSONLD_CONTEXTS = { LDSecurityContexts.JSONLD_CONTEXT_W3ID_VC_V2 };
public static final DocumentLoader DEFAULT_DOCUMENT_LOADER = LDSecurityContexts.DOCUMENT_LOADER;
public static Builder<? extends Builder<?>> builder() {
return new Builder(new Eddsa2022v2LdProof());
}
/*
* Factory methods
*/
public static class Builder<B extends Builder<B>> extends LdProof.Builder<B> {
private boolean addCryptosuite = true;
public Builder(LdProof jsonLdObject) {
super(jsonLdObject);
}
@Override
public B base(JsonLDObject base) {
addCryptosuite = false;
return super.base(base);
}
@Override
public LdProof build() {
super.build();
if (addCryptosuite) {
JsonLDUtils.jsonLdAdd(this.jsonLdObject, "cryptosuite", "eddsa-rdfc-2022");
}
return (LdProof) this.jsonLdObject;
}
}
}

View File

@ -15,6 +15,7 @@ import foundation.identity.jsonld.ConfigurableDocumentLoader;
public class LDSecurityContexts { public class LDSecurityContexts {
public static final URI JSONLD_CONTEXT_W3ID_SUITES_ED25519_2022_V1 = URI.create("https://w3id.org/security/data-integrity/v1"); public static final URI JSONLD_CONTEXT_W3ID_SUITES_ED25519_2022_V1 = URI.create("https://w3id.org/security/data-integrity/v1");
public static final URI JSONLD_CONTEXT_W3ID_VC_V2 = URI.create("https://www.w3.org/ns/credentials/v2");
public static final Map<URI, JsonDocument> CONTEXTS; public static final Map<URI, JsonDocument> CONTEXTS;
public static final DocumentLoader DOCUMENT_LOADER; public static final DocumentLoader DOCUMENT_LOADER;
@ -29,6 +30,8 @@ public class LDSecurityContexts {
CONTEXTS.put(JSONLD_CONTEXT_W3ID_SUITES_ED25519_2022_V1, CONTEXTS.put(JSONLD_CONTEXT_W3ID_SUITES_ED25519_2022_V1,
JsonDocument.of(MediaType.JSON_LD, Resources.getResource("contexts/data-integrity-v1.jsonld").openStream())); JsonDocument.of(MediaType.JSON_LD, Resources.getResource("contexts/data-integrity-v1.jsonld").openStream()));
CONTEXTS.put(JSONLD_CONTEXT_W3ID_VC_V2,
JsonDocument.of(MediaType.JSON_LD, Resources.getResource("contexts/credentials-v2.jsonld").openStream()));
for (Map.Entry<URI, JsonDocument> context : CONTEXTS.entrySet()) { for (Map.Entry<URI, JsonDocument> context : CONTEXTS.entrySet()) {
context.getValue().setDocumentUrl(context.getKey()); context.getValue().setDocumentUrl(context.getKey());

View File

@ -1,28 +1,29 @@
package org.oneedtech.inspect.vc.verification; package org.oneedtech.inspect.vc.verification;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.List;
import foundation.identity.jsonld.JsonLDException; import foundation.identity.jsonld.JsonLDException;
import foundation.identity.jsonld.JsonLDObject; import foundation.identity.jsonld.JsonLDObject;
import info.weboftrust.ldsignatures.LdProof; import info.weboftrust.ldsignatures.LdProof;
import info.weboftrust.ldsignatures.canonicalizer.Canonicalizer; import info.weboftrust.ldsignatures.canonicalizer.Canonicalizer;
import info.weboftrust.ldsignatures.util.SHAUtil; import info.weboftrust.ldsignatures.util.SHAUtil;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.List;
public class URDNA2015Canonicalizer extends Canonicalizer { public class URDNA2015Canonicalizer extends Canonicalizer {
public URDNA2015Canonicalizer() { private LdProof.Builder<?> proofBuilder;
public URDNA2015Canonicalizer(LdProof.Builder<?> proofBuilder) {
super(List.of("urdna2015")); super(List.of("urdna2015"));
this.proofBuilder = proofBuilder;
} }
@Override @Override
public byte[] canonicalize(LdProof ldProof, JsonLDObject jsonLdObject) throws IOException, GeneralSecurityException, JsonLDException { public byte[] canonicalize(LdProof ldProof, JsonLDObject jsonLdObject) throws IOException, GeneralSecurityException, JsonLDException {
// construct the LD proof without proof values // construct the LD proof without proof values
LdProof ldProofWithoutProofValues = proofBuilder
LdProof ldProofWithoutProofValues = Eddsa2022LdProof.builder()
.base(ldProof) .base(ldProof)
.defaultContexts(true) .defaultContexts(true)
.build(); .build();

View File

@ -2,10 +2,8 @@
"@context": { "@context": {
"@protected": true, "@protected": true,
"@vocab": "https://www.w3.org/ns/credentials/issuer-dependent#", "@vocab": "https://www.w3.org/ns/credentials/issuer-dependent#",
"id": "@id", "id": "@id",
"type": "@type", "type": "@type",
"kid": { "kid": {
"@id": "https://www.iana.org/assignments/jose#kid", "@id": "https://www.iana.org/assignments/jose#kid",
"@type": "@id" "@type": "@id"
@ -65,7 +63,6 @@
"...": { "...": {
"@id": "https://www.iana.org/assignments/jwt#..." "@id": "https://www.iana.org/assignments/jwt#..."
}, },
"digestSRI": { "digestSRI": {
"@id": "https://www.w3.org/2018/credentials#digestSRI", "@id": "https://www.w3.org/2018/credentials#digestSRI",
"@type": "https://www.w3.org/2018/credentials#sriString" "@type": "https://www.w3.org/2018/credentials#sriString"
@ -74,25 +71,18 @@
"@id": "https://w3id.org/security#digestMultibase", "@id": "https://w3id.org/security#digestMultibase",
"@type": "https://w3id.org/security#multibase" "@type": "https://w3id.org/security#multibase"
}, },
"mediaType": { "mediaType": {
"@id": "https://schema.org/encodingFormat" "@id": "https://schema.org/encodingFormat"
}, },
"description": "https://schema.org/description", "description": "https://schema.org/description",
"name": "https://schema.org/name", "name": "https://schema.org/name",
"EnvelopedVerifiableCredential": "https://www.w3.org/2018/credentials#EnvelopedVerifiableCredential",
"EnvelopedVerifiableCredential":
"https://www.w3.org/2018/credentials#EnvelopedVerifiableCredential",
"VerifiableCredential": { "VerifiableCredential": {
"@id": "https://www.w3.org/2018/credentials#VerifiableCredential", "@id": "https://www.w3.org/2018/credentials#VerifiableCredential",
"@context": { "@context": {
"@protected": true, "@protected": true,
"id": "@id", "id": "@id",
"type": "@type", "type": "@type",
"credentialSchema": { "credentialSchema": {
"@id": "https://www.w3.org/2018/credentials#credentialSchema", "@id": "https://www.w3.org/2018/credentials#credentialSchema",
"@type": "@id" "@type": "@id"
@ -146,15 +136,12 @@
} }
} }
}, },
"VerifiablePresentation": { "VerifiablePresentation": {
"@id": "https://www.w3.org/2018/credentials#VerifiablePresentation", "@id": "https://www.w3.org/2018/credentials#VerifiablePresentation",
"@context": { "@context": {
"@protected": true, "@protected": true,
"id": "@id", "id": "@id",
"type": "@type", "type": "@type",
"holder": { "holder": {
"@id": "https://www.w3.org/2018/credentials#holder", "@id": "https://www.w3.org/2018/credentials#holder",
"@type": "@id" "@type": "@id"
@ -176,36 +163,27 @@
} }
} }
}, },
"JsonSchemaCredential": "https://www.w3.org/2018/credentials#JsonSchemaCredential", "JsonSchemaCredential": "https://www.w3.org/2018/credentials#JsonSchemaCredential",
"JsonSchema": { "JsonSchema": {
"@id": "https://www.w3.org/2018/credentials#JsonSchema", "@id": "https://www.w3.org/2018/credentials#JsonSchema",
"@context": { "@context": {
"@protected": true, "@protected": true,
"id": "@id", "id": "@id",
"type": "@type", "type": "@type",
"jsonSchema": { "jsonSchema": {
"@id": "https://w3.org/2018/credentials#jsonSchema", "@id": "https://w3.org/2018/credentials#jsonSchema",
"@type": "@json" "@type": "@json"
} }
} }
}, },
"BitstringStatusListCredential": "https://www.w3.org/ns/credentials/status#BitstringStatusListCredential", "BitstringStatusListCredential": "https://www.w3.org/ns/credentials/status#BitstringStatusListCredential",
"BitstringStatusList": { "BitstringStatusList": {
"@id": "https://www.w3.org/ns/credentials/status#BitstringStatusList", "@id": "https://www.w3.org/ns/credentials/status#BitstringStatusList",
"@context": { "@context": {
"@protected": true, "@protected": true,
"id": "@id", "id": "@id",
"type": "@type", "type": "@type",
"statusPurpose": "https://www.w3.org/ns/credentials/status#statusPurpose",
"statusPurpose":
"https://www.w3.org/ns/credentials/status#statusPurpose",
"encodedList": { "encodedList": {
"@id": "https://www.w3.org/ns/credentials/status#encodedList", "@id": "https://www.w3.org/ns/credentials/status#encodedList",
"@type": "https://w3id.org/security#multibase" "@type": "https://w3id.org/security#multibase"
@ -217,38 +195,28 @@
"@id": "https://www.w3.org/ns/credentials/status#statusMessage", "@id": "https://www.w3.org/ns/credentials/status#statusMessage",
"@context": { "@context": {
"@protected": true, "@protected": true,
"id": "@id", "id": "@id",
"type": "@type", "type": "@type",
"status": "https://www.w3.org/ns/credentials/status#status", "status": "https://www.w3.org/ns/credentials/status#status",
"message": "https://www.w3.org/ns/credentials/status#message" "message": "https://www.w3.org/ns/credentials/status#message"
} }
} }
} }
}, },
"BitstringStatusListEntry": { "BitstringStatusListEntry": {
"@id": "@id": "https://www.w3.org/ns/credentials/status#BitstringStatusListEntry",
"https://www.w3.org/ns/credentials/status#BitstringStatusListEntry",
"@context": { "@context": {
"@protected": true, "@protected": true,
"id": "@id", "id": "@id",
"type": "@type", "type": "@type",
"statusPurpose": "https://www.w3.org/ns/credentials/status#statusPurpose",
"statusPurpose": "statusListIndex": "https://www.w3.org/ns/credentials/status#statusListIndex",
"https://www.w3.org/ns/credentials/status#statusPurpose",
"statusListIndex":
"https://www.w3.org/ns/credentials/status#statusListIndex",
"statusListCredential": { "statusListCredential": {
"@id": "@id": "https://www.w3.org/ns/credentials/status#statusListCredential",
"https://www.w3.org/ns/credentials/status#statusListCredential",
"@type": "@id" "@type": "@id"
} }
} }
}, },
"DataIntegrityProof": { "DataIntegrityProof": {
"@id": "https://w3id.org/security#DataIntegrityProof", "@id": "https://w3id.org/security#DataIntegrityProof",
"@context": { "@context": {