Added implementaiton of eddsa-2022 cryptosuite verifier

This commit is contained in:
Xavi Aracil 2023-05-29 11:14:48 +02:00
parent f44a4a67bf
commit 6287dde672
6 changed files with 229 additions and 0 deletions

View File

@ -0,0 +1,52 @@
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 Ed25519Signature2022LdVerifier extends LdVerifier<Ed25519Signature2022SignatureSuite> {
public Ed25519Signature2022LdVerifier(ByteVerifier verifier) {
super(SignatureSuites.SIGNATURE_SUITE_ED25519SIGNATURE2022, verifier, new URDNA2015Canonicalizer());
}
public Ed25519Signature2022LdVerifier(byte[] publicKey) {
this(new Ed25519_EdDSA_PublicKeyVerifier(publicKey));
}
public Ed25519Signature2022LdVerifier() {
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,28 @@
package org.oneedtech.inspect.vc.verification;
import com.danubetech.keyformats.jose.JWSAlgorithm;
import com.danubetech.keyformats.jose.KeyTypeName;
import info.weboftrust.ldsignatures.suites.SignatureSuite;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class Ed25519Signature2022SignatureSuite extends SignatureSuite {
Ed25519Signature2022SignatureSuite() {
super(
"DataIntegrityProof",
URI.create("https://www.w3.org/TR/vc-di-eddsa"),
URI.create("https://w3id.org/security#URDNA2015"),
URI.create("http://w3id.org/digests#sha256"),
URI.create("http://w3id.org/security#ed25519"),
List.of(KeyTypeName.Ed25519),
Map.of(KeyTypeName.Ed25519, List.of(JWSAlgorithm.EdDSA)),
Arrays.asList(LDSecurityContexts.JSONLD_CONTEXT_W3ID_SUITES_ED25519_2022_V1,
info.weboftrust.ldsignatures.jsonld.LDSecurityContexts.JSONLD_CONTEXT_W3ID_SECURITY_V3));
}
}

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 Eddsa2022LdProof extends LdProof {
public static final URI[] DEFAULT_JSONLD_CONTEXTS = { LDSecurityContexts.JSONLD_CONTEXT_W3ID_SUITES_ED25519_2022_V1 };
public static final DocumentLoader DEFAULT_DOCUMENT_LOADER = LDSecurityContexts.DOCUMENT_LOADER;
public static Builder<? extends Builder<?>> builder() {
return new Builder(new Eddsa2022LdProof());
}
/*
* 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-2022");
}
return (LdProof) this.jsonLdObject;
}
}
}

View File

@ -0,0 +1,43 @@
package org.oneedtech.inspect.vc.verification;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import com.apicatalog.jsonld.JsonLdError;
import com.apicatalog.jsonld.document.JsonDocument;
import com.apicatalog.jsonld.http.media.MediaType;
import com.apicatalog.jsonld.loader.DocumentLoader;
import com.google.common.io.Resources;
import foundation.identity.jsonld.ConfigurableDocumentLoader;
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 Map<URI, JsonDocument> CONTEXTS;
public static final DocumentLoader DOCUMENT_LOADER;
static {
try {
CONTEXTS = new HashMap<>();
CONTEXTS.putAll(info.weboftrust.ldsignatures.jsonld.LDSecurityContexts.CONTEXTS);
CONTEXTS.put(JSONLD_CONTEXT_W3ID_SUITES_ED25519_2022_V1,
JsonDocument.of(MediaType.JSON_LD, Resources.getResource("contexts/data-integrity-v1.jsonld").openStream()));
for (Map.Entry<URI, JsonDocument> context : CONTEXTS.entrySet()) {
context.getValue().setDocumentUrl(context.getKey());
}
} catch (JsonLdError | IOException ex) {
throw new ExceptionInInitializerError(ex);
}
DOCUMENT_LOADER = new ConfigurableDocumentLoader(CONTEXTS);
}
}

View File

@ -0,0 +1,5 @@
package org.oneedtech.inspect.vc.verification;
public class SignatureSuites {
public static final Ed25519Signature2022SignatureSuite SIGNATURE_SUITE_ED25519SIGNATURE2022 = new Ed25519Signature2022SignatureSuite();
}

View File

@ -0,0 +1,52 @@
package org.oneedtech.inspect.vc.verification;
import foundation.identity.jsonld.JsonLDException;
import foundation.identity.jsonld.JsonLDObject;
import info.weboftrust.ldsignatures.LdProof;
import info.weboftrust.ldsignatures.canonicalizer.Canonicalizer;
import info.weboftrust.ldsignatures.util.SHAUtil;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.List;
public class URDNA2015Canonicalizer extends Canonicalizer {
public URDNA2015Canonicalizer() {
super(List.of("urdna2015"));
}
@Override
public byte[] canonicalize(LdProof ldProof, JsonLDObject jsonLdObject) throws IOException, GeneralSecurityException, JsonLDException {
// construct the LD proof without proof values
LdProof ldProofWithoutProofValues = Eddsa2022LdProof.builder()
.base(ldProof)
.defaultContexts(true)
.build();
LdProof.removeLdProofValues(ldProofWithoutProofValues);
// construct the LD object without proof
JsonLDObject jsonLdObjectWithoutProof = JsonLDObject.builder()
.base(jsonLdObject)
.build();
jsonLdObjectWithoutProof.setDocumentLoader(jsonLdObject.getDocumentLoader());
LdProof.removeFromJsonLdObject(jsonLdObjectWithoutProof);
// canonicalize the LD proof and LD object
String canonicalizedLdProofWithoutProofValues = ldProofWithoutProofValues.normalize("urdna2015");
String canonicalizedJsonLdObjectWithoutProof = jsonLdObjectWithoutProof.normalize("urdna2015");
// construct the canonicalization result
byte[] canonicalizationResult = new byte[64];
System.arraycopy(SHAUtil.sha256(canonicalizedLdProofWithoutProofValues), 0, canonicalizationResult, 0, 32);
System.arraycopy(SHAUtil.sha256(canonicalizedJsonLdObjectWithoutProof), 0, canonicalizationResult, 32, 32);
return canonicalizationResult;
}
}