Added support for VCDM 2.0
This commit is contained in:
parent
c97c455d09
commit
be7e496d47
@ -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) {
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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());
|
||||||
|
@ -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();
|
||||||
|
@ -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": {
|
||||||
|
Loading…
Reference in New Issue
Block a user