@@ -53,7 +93,6 @@ public interface VerificationMethod {
// Upon removal, move logic to constructor without type parameter
@Deprecated(since = "2.3.0")
static VerificationMethod of(String kid, String type, String publicKeyJwk) throws VerificationMethodException {
-
JsonObject jsonObj;
try {
jsonObj = JsonParser.parseString(publicKeyJwk).getAsJsonObject();
@@ -61,41 +100,9 @@ static VerificationMethod of(String kid, String type, String publicKeyJwk) throw
throw new VerificationMethodException("The supplied string does not represent a public key JWK", exc);
}
- var crv = jsonObj.get("crv");
- var x = jsonObj.get("x");
- var y = jsonObj.get("y");
-
- var kty = jsonObj.get("kty");
- if (kty == null || !kty.isJsonPrimitive()) {
- throw new VerificationMethodException("Expected property 'kty' to be a string.");
- }
- switch (kty.getAsString()) {
- case "OKP" -> {
- if (crv == null || !crv.isJsonPrimitive() || !"Ed25519".equals(crv.getAsString())) {
- throw new VerificationMethodException("Only curve 'Ed25519' is supported for key type OKP.");
- }
- if (x == null || !x.isJsonPrimitive() || x.getAsString().isEmpty()) {
- throw new VerificationMethodException("Property 'x' must be set to a string.");
- }
- }
- case "EC" -> {
- if (crv == null || !crv.isJsonPrimitive() || !"P-256".equals(crv.getAsString())) {
- throw new VerificationMethodException("Only curve 'P-256' is supported for key type EC.");
- }
- if (x == null || !x.isJsonPrimitive() || x.getAsString().isEmpty()) {
- throw new VerificationMethodException("Property 'x' must be set to a string.");
- }
- if (y == null || !y.isJsonPrimitive() || y.getAsString().isEmpty()) {
- throw new VerificationMethodException("Property 'y' must be set to a string.");
- }
- }
- default -> {
- throw new VerificationMethodException("Key type %s not supported.".formatted(kty.getAsString()));
- }
- }
+ validateJwk(jsonObj);
return new VerificationMethod() {
-
@Override
public String getIdFragment() {
return kid;
@@ -294,43 +301,41 @@ public int hashCode() {
}
/**
- * As specified
- * and w.r.t. RFC3986
- *
- * @return a string that conforms to the DID URL Syntax
- */
- String getIdFragment();
-
- /**
- * As specified
- * and w.r.t. RFC3986
- *
- * @return a string that references exactly one verification method type
- */
- @Deprecated(since = "2.3.0")
- String getType();
-
- /**
- * As specified:
- *
supportedJWSAlgorithms() {
- return Set.of(this.getAlgorithm());
+ public JCAContext getJCAContext() {
+ return this.signer.getJCAContext();
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusEd25519ProofOfPossessionJWSSignerImpl.java b/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusEd25519ProofOfPossessionJWSSignerImpl.java
index 4f5b688d..4968533c 100644
--- a/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusEd25519ProofOfPossessionJWSSignerImpl.java
+++ b/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusEd25519ProofOfPossessionJWSSignerImpl.java
@@ -5,12 +5,11 @@
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jose.jca.JCAContext;
import com.nimbusds.jose.util.Base64URL;
-import java.security.KeyException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableEntryException;
+import java.security.*;
+import java.security.interfaces.EdECPrivateKey;
import java.util.Set;
/**
@@ -19,9 +18,9 @@
*
* To be used in conjunction with {@link ProofOfPossessionCreator#ProofOfPossessionCreator(ProofOfPossessionJWSSigner)}.
*/
-@Deprecated(since = "1.9.0")
public class PrimusEd25519ProofOfPossessionJWSSignerImpl extends PrimusEd25519VerificationMethodKeyProviderImpl implements ProofOfPossessionJWSSigner {
- final private String kid;
+ private final String kid;
+ private final JCAContext jcaContext = new JCAContext();
/**
* @see PrimusEd25519VerificationMethodKeyProviderImpl#PrimusEd25519VerificationMethodKeyProviderImpl(PrimusKeyStoreLoader, String, String)
@@ -32,6 +31,11 @@ public PrimusEd25519ProofOfPossessionJWSSignerImpl(PrimusKeyStoreLoader primus,
this.kid = kid;
}
+ public PrimusEd25519ProofOfPossessionJWSSignerImpl(KeyPair keyPair, String kid, PrimusKeyStoreLoader primus) {
+ super(keyPair, primus);
+ this.kid = kid;
+ }
+
@Override
public String getKid() {
return this.kid;
@@ -39,7 +43,7 @@ public String getKid() {
@Override
public JWSAlgorithm getAlgorithm() {
- return JWSAlgorithm.Ed25519;
+ return JWSAlgorithm.EdDSA;
}
@Override
@@ -51,4 +55,9 @@ public Set supportedJWSAlgorithms() {
public Base64URL sign(JWSHeader jwsHeader, byte[] bytes) throws JOSEException {
return Base64URL.encode(super.generateSignature(bytes));
}
+
+ @Override
+ public JCAContext getJCAContext() {
+ return jcaContext;
+ }
}
diff --git a/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusEd25519VerificationMethodKeyProviderImpl.java b/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusEd25519VerificationMethodKeyProviderImpl.java
index d72e983c..f916ade8 100644
--- a/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusEd25519VerificationMethodKeyProviderImpl.java
+++ b/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusEd25519VerificationMethodKeyProviderImpl.java
@@ -5,10 +5,7 @@
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
-import java.security.KeyException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableEntryException;
+import java.security.*;
/**
* The {@link PrimusEd25519VerificationMethodKeyProviderImpl} class is a {@link VerificationMethodKeyProvider} implementation
@@ -44,6 +41,10 @@ public PrimusEd25519VerificationMethodKeyProviderImpl(PrimusKeyStoreLoader primu
super(primus.loadKeyPair(alias, password), primus.getKeyStore().getProvider());
}
+ public PrimusEd25519VerificationMethodKeyProviderImpl(KeyPair keyPair, PrimusKeyStoreLoader primus) {
+ super(keyPair, primus.getKeyStore().getProvider());
+ }
+
/**
* A simple wrapper for PrimusEncoding#optionallyUnderifyRS helper.
*/
diff --git a/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusKeyStoreLoader.java b/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusKeyStoreLoader.java
index c8c684f7..c068c322 100644
--- a/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusKeyStoreLoader.java
+++ b/src/main/java/ch/admin/bj/swiyu/didtoolbox/securosys/primus/PrimusKeyStoreLoader.java
@@ -4,10 +4,10 @@
import lombok.Getter;
import java.io.*;
- import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.security.*;
- import java.security.cert.CertificateException;
+import java.security.cert.CertificateException;
import java.util.Locale;
import java.util.Properties;
@@ -25,7 +25,7 @@ public class PrimusKeyStoreLoader {
public static final String PROVIDER_CLASS = "com.securosys.primus.jce.PrimusProvider";
private static final String KEY_STORE_TYPE_GETTER = "getKeyStoreTypeName";
private static final String PROVIDER_NAME_GETTER = "getProviderName";
- @Getter(AccessLevel.PACKAGE)
+ @Getter(AccessLevel.PUBLIC)
private final KeyStore keyStore;
/**
@@ -221,7 +221,7 @@ private String toCredentialFileLine(String value) {
* @throws KeyException
*/
@SuppressWarnings("PMD.UnusedAssignment")
- KeyPair loadKeyPair(String alias, String password)
+ public KeyPair loadKeyPair(String alias, String password)
throws UnrecoverableEntryException, KeyStoreException, NoSuchAlgorithmException, KeyException {
var keyStore = this.getKeyStore();
diff --git a/src/main/plantuml/DidLogCreatorContext-create.puml b/src/main/plantuml/DidLogCreatorContext-create.puml
index 720d21d7..f2616b82 100644
--- a/src/main/plantuml/DidLogCreatorContext-create.puml
+++ b/src/main/plantuml/DidLogCreatorContext-create.puml
@@ -5,6 +5,7 @@ participant ch.admin.bj.swiyu.didtoolbox.context.DidLogCreatorContext
participant ch.admin.bj.swiyu.didtoolbox.context.DidLogStrategyFactory
participant ch.admin.bj.swiyu.didtoolbox.TdwCreator
participant ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+participant ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
participant ch.admin.bj.swiyu.didtoolbox.webvh.WebVerifiableHistoryCreator
participant ch.admin.bj.swiyu.didtoolbox.context.DidLogCreatorStrategy
@@ -39,6 +40,18 @@ activate ch.admin.bj.swiyu.didtoolbox.context.DidLogCreatorContext
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : of
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : validateJwk
+ activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : void
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.context.DidLogCreatorContext : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
@@ -51,6 +64,18 @@ activate ch.admin.bj.swiyu.didtoolbox.context.DidLogCreatorContext
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : of
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : validateJwk
+ activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : void
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.context.DidLogCreatorContext : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
@@ -75,6 +100,18 @@ activate ch.admin.bj.swiyu.didtoolbox.context.DidLogCreatorContext
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : of
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : validateJwk
+ activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : void
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.context.DidLogCreatorContext : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
@@ -87,6 +124,18 @@ activate ch.admin.bj.swiyu.didtoolbox.context.DidLogCreatorContext
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : of
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : validateJwk
+ activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : void
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.context.DidLogCreatorContext : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
diff --git a/src/main/plantuml/DidLogUpdaterContext-update.puml b/src/main/plantuml/DidLogUpdaterContext-update.puml
index 209a3bad..fc2ed1c4 100644
--- a/src/main/plantuml/DidLogUpdaterContext-update.puml
+++ b/src/main/plantuml/DidLogUpdaterContext-update.puml
@@ -5,6 +5,7 @@ participant ch.admin.bj.swiyu.didtoolbox.context.DidLogUpdaterContext
participant ch.admin.bj.swiyu.didtoolbox.context.DidLogStrategyFactory
participant ch.admin.bj.swiyu.didtoolbox.TdwUpdater
participant ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+participant ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
participant ch.admin.bj.swiyu.didtoolbox.webvh.WebVerifiableHistoryUpdater
participant ch.admin.bj.swiyu.didtoolbox.context.DidLogUpdaterStrategy
@@ -39,6 +40,18 @@ activate ch.admin.bj.swiyu.didtoolbox.context.DidLogUpdaterContext
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : of
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : validateJwk
+ activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : void
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.context.DidLogUpdaterContext : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
@@ -51,6 +64,18 @@ activate ch.admin.bj.swiyu.didtoolbox.context.DidLogUpdaterContext
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : of
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : validateJwk
+ activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : void
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.context.DidLogUpdaterContext : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
@@ -75,6 +100,18 @@ activate ch.admin.bj.swiyu.didtoolbox.context.DidLogUpdaterContext
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : of
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : validateJwk
+ activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : void
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.context.DidLogUpdaterContext : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
@@ -87,6 +124,18 @@ activate ch.admin.bj.swiyu.didtoolbox.context.DidLogUpdaterContext
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : of
activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : validateJwk
+ activate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod -> ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm : toString
+ activate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : java.lang.String
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.CryptographicAlgorithm
+ ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : void
+ deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
deactivate ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod --> ch.admin.bj.swiyu.didtoolbox.context.DidLogUpdaterContext : ch.admin.bj.swiyu.didtoolbox.model.VerificationMethod
diff --git a/src/test/java/ch/admin/bj/swiyu/didtoolbox/AbstractUtilTestBase.java b/src/test/java/ch/admin/bj/swiyu/didtoolbox/AbstractUtilTestBase.java
index d2f319c8..6c883c19 100644
--- a/src/test/java/ch/admin/bj/swiyu/didtoolbox/AbstractUtilTestBase.java
+++ b/src/test/java/ch/admin/bj/swiyu/didtoolbox/AbstractUtilTestBase.java
@@ -45,7 +45,7 @@ public abstract class AbstractUtilTestBase {
final protected static VcDataIntegrityCryptographicSuite TEST_CRYPTO_SUITE_JKS;
/**
- * Sharing the very same keys ({@link #TEST_PRIVATE_KEY_MULTIBASE}, {@link #TEST_PUBLIC_KEY_MULTIBASE}) with {@link #TEST_POP_JWS_SIGNER}
+ * Sharing the very same keys ({@link #TEST_PRIVATE_KEY_MULTIBASE}, {@link #TEST_PUBLIC_KEY_MULTIBASE})
*/
final protected static VcDataIntegrityCryptographicSuite TEST_CRYPTO_SUITE;
@@ -74,11 +74,8 @@ public abstract class AbstractUtilTestBase {
/**
* Sharing the very same keys ({@link #TEST_PRIVATE_KEY_MULTIBASE}, {@link #TEST_PUBLIC_KEY_MULTIBASE}) with {@link #TEST_CRYPTO_SUITE}
*/
- final protected static ProofOfPossessionJWSSigner TEST_POP_JWS_SIGNER;
final static String TEST_POP_JWS_KID = "did:webvh:SCID:example.com#key-1";
- final static String TEST_POP_JWS_KID_ANOTHER = "did:webvh:SCID:example.com#key-2";
-
/**
* Collection of signing/verifying Ed25519 keys in various (appropriate) format intended for testing purposes only
*
@@ -160,9 +157,8 @@ public abstract class AbstractUtilTestBase {
try {
// Using (example) keys from https://www.w3.org/TR/vc-di-eddsa/#example-private-and-public-keys-for-signature-0
- var suite = new EdDsaJcs2022ProofOfPossessionJWSSignerImpl(TEST_PRIVATE_KEY_MULTIBASE, TEST_POP_JWS_KID);
- TEST_POP_JWS_SIGNER = suite;
- TEST_CRYPTO_SUITE = suite;
+ var suite =
+ TEST_CRYPTO_SUITE = new EdDsaJcs2022VcDataIntegrityCryptographicSuite(TEST_PRIVATE_KEY_MULTIBASE);;
// Total 3 (PrivateKeyEntry) entries available in the JKS: myalias/myalias2/myalias3
var suiteJks = new EdDsaJcs2022JWSSigner(
diff --git a/src/test/java/ch/admin/bj/swiyu/didtoolbox/BlackboxIT.java b/src/test/java/ch/admin/bj/swiyu/didtoolbox/BlackboxIT.java
index fcb41479..10b67adb 100644
--- a/src/test/java/ch/admin/bj/swiyu/didtoolbox/BlackboxIT.java
+++ b/src/test/java/ch/admin/bj/swiyu/didtoolbox/BlackboxIT.java
@@ -1,5 +1,6 @@
package ch.admin.bj.swiyu.didtoolbox;
+import ch.admin.bj.swiyu.didtoolbox.model.DidLogMetaPeekerException;
import ch.admin.bj.swiyu.didtoolbox.model.WebVerifiableHistoryDidLogMetaPeeker;
import com.beust.jcommander.internal.DefaultConsole;
import org.junit.jupiter.api.Test;
@@ -106,17 +107,7 @@ void createUpdateAndDeactivateDidLog_thenFailUpdate(@TempDir Path tempDir) throw
didLog = cliOutput.toString();
cliOutput.reset();
- // FIXME: the current didresolver does not yet throw an exception when trying to resolve a deactivated did.
- // The below line should work once the didresolver exhibits the desired behavior.
- // assertThrows(() -> WebVerifiableHistoryDidLogMetaPeeker.peek(didLog), DidLogMetaPeekerException.class);
- // Current workaround is to try and update a deactivated did log, which fails.
- var didLogFilePathV3 = tempDir + "/didlogV3.jsonl";
- try (var writer = new PrintWriter(didLogFilePathV3, StandardCharsets.UTF_8)) {
- writer.write(didLog);
- }
- var updateDeactivatedDidLog = new String[]{"update", "-d", didLogFilePathV3, "-s", "./src/test/data/private.pem", "-v", "./src/test/data/public.pem", "-a", "assert-key-03,./src/test/data/assert-key-01.pub", "-t", "auth-key-03,./src/test/data/auth-key-01.pub"};
- assertEquals(1, main.run(updateDeactivatedDidLog));
- var out = cliOutput.toString();
- assertTrue(out.contains("can no longer be updated"));
+ final var finalDidLog = didLog;
+ assertThrows(DidLogMetaPeekerException.class, () -> WebVerifiableHistoryDidLogMetaPeeker.peek(finalDidLog));
}
}
\ No newline at end of file
diff --git a/src/test/java/ch/admin/bj/swiyu/didtoolbox/EdDsaJcs2022ProofOfPossessionJWSSignerImpl.java b/src/test/java/ch/admin/bj/swiyu/didtoolbox/EdDsaJcs2022ProofOfPossessionJWSSignerImpl.java
deleted file mode 100644
index 355c4290..00000000
--- a/src/test/java/ch/admin/bj/swiyu/didtoolbox/EdDsaJcs2022ProofOfPossessionJWSSignerImpl.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package ch.admin.bj.swiyu.didtoolbox;
-
-import ch.admin.bj.swiyu.didtoolbox.vc_data_integrity.EdDsaJcs2022VcDataIntegrityCryptographicSuite;
-import ch.admin.bj.swiyu.didtoolbox.vc_data_integrity.VcDataIntegrityCryptographicSuiteException;
-import com.nimbusds.jose.JOSEException;
-import com.nimbusds.jose.JWSAlgorithm;
-import com.nimbusds.jose.JWSHeader;
-import com.nimbusds.jose.util.Base64URL;
-
-import java.util.Set;
-
-/**
- * Intended for unit testing purposes only.
- */
-//@SuppressWarnings("PMD")
-class EdDsaJcs2022ProofOfPossessionJWSSignerImpl extends EdDsaJcs2022VcDataIntegrityCryptographicSuite implements ProofOfPossessionJWSSigner {
- private final String kid;
-
- EdDsaJcs2022ProofOfPossessionJWSSignerImpl(String privateKeyMultibase, String kid) throws VcDataIntegrityCryptographicSuiteException {
- super(privateKeyMultibase);
- this.kid = kid;
- }
-
- @Override
- public String getKid() {
- return this.kid;
- }
-
- @Override
- public JWSAlgorithm getAlgorithm() {
- return JWSAlgorithm.Ed25519;
- }
-
- @Override
- public Set supportedJWSAlgorithms() {
- return Set.of(this.getAlgorithm());
- }
-
- @Override
- public Base64URL sign(JWSHeader jwsHeader, byte[] bytes) throws JOSEException {
- return Base64URL.encode(this.generateSignature(bytes));
- }
-}
diff --git a/src/test/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionCreatorTest.java b/src/test/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionCreatorTest.java
index d8893956..ab050488 100644
--- a/src/test/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionCreatorTest.java
+++ b/src/test/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionCreatorTest.java
@@ -1,29 +1,34 @@
package ch.admin.bj.swiyu.didtoolbox;
import ch.admin.bj.swiyu.didtoolbox.model.WebVerifiableHistoryDidLogMetaPeeker;
+import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import org.junit.jupiter.api.Test;
import java.nio.file.Path;
import java.time.Duration;
+import java.util.Set;
import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
@SuppressWarnings("PMD")
class ProofOfPossessionCreatorTest extends AbstractUtilTestBase {
private static final Duration ONE_DAY_LONG = Duration.ofDays(1);
@Test
- void testCreateJWT_valid() throws Exception {
+ void create_withValidParameters_returnsValidJWT() throws Exception {
var nonce = "test_nonce";
var didLog = buildInitialWebVerifiableHistoryDidLogEntry(TEST_CRYPTO_SUITE);
var didLogMeta = WebVerifiableHistoryDidLogMetaPeeker.peek(didLog);
- var crypto = new EcP256ProofOfPossessionJWSSigner(Path.of("src/test/data/assert-key-01"), didLogMeta.getDidDoc().getId() + "#my-assert-key-01");
+ var crypto = ProofOfPossessionJWSSigner.of(Path.of("src/test/data/assert-key-01"), didLogMeta.getDidDoc().getId() + "#my-assert-key-01");
var proofCreator = new ProofOfPossessionCreator(crypto);
- var pop = proofCreator.create(nonce, Duration.ofDays(90));
+ var pop = proofCreator.create(nonce, ONE_DAY_LONG);
var header = pop.getHeader();
assertEquals(JWSAlgorithm.ES256, pop.getHeader().getAlgorithm());
@@ -42,56 +47,49 @@ void testCreateJWT_valid() throws Exception {
}
@Test
- void testCreateInvalid() throws Exception {
+ void create_withInvalidSigner_throwsProofOfPossessionCreatorException() throws Exception {
+ var exceptionMessage = "mock exception";
var nonce = "my_nonce";
-
- // NOTE The very same keys are shared only between:
- // - EXAMPLE_VERIFICATION_METHOD_KEY_PROVIDER and EXAMPLE_POP_JWS_SIGNER
- // - EXAMPLE_VERIFICATION_METHOD_KEY_PROVIDER_ANOTHER and EXAMPLE_POP_JWS_SIGNER_ANOTHER
-
- // for the purpose, you may also use EXAMPLE_POP_JWS_SIGNER_ANOTHER here, instead
- var didLog = buildInitialTdwDidLogEntry(TEST_CRYPTO_SUITE_ANOTHER);
+ var signer = mock(ProofOfPossessionJWSSigner.class);
+ when(signer.getAlgorithm()).thenReturn(JWSAlgorithm.EdDSA);
+ when(signer.getKid()).thenReturn(TEST_POP_JWS_KID);
+ when(signer.supportedJWSAlgorithms()).thenReturn(Set.of(JWSAlgorithm.EdDSA));
+ when(signer.sign(any(), any())).thenThrow(new JOSEException(exceptionMessage));
// create proof
- var proof = new ProofOfPossessionCreator(TEST_POP_JWS_SIGNER)
- .create(nonce, ONE_DAY_LONG);
+ var creator = new ProofOfPossessionCreator(signer);
+ var ex = assertThrowsExactly(ProofOfPossessionCreatorException.class, () -> creator.create(nonce, ONE_DAY_LONG));
+ assertTrue(ex.getMessage().contains(exceptionMessage));
+ }
- // verify JWT (head/payload) claims
- var header = proof.getHeader();
- assertEquals(JWSAlgorithm.Ed25519, header.getAlgorithm());
+ @Test
+ void create_withoutDuration_throwsProofOfPossessionCreatorException() throws Exception {
+ var nonce = "test_nonce";
- // CAUTION: MUST differ!
- assertFalse(didLog.contains(header.getKeyID()));
+ var didLog = buildInitialWebVerifiableHistoryDidLogEntry(TEST_CRYPTO_SUITE);
+ var didLogMeta = WebVerifiableHistoryDidLogMetaPeeker.peek(didLog);
- var payload = proof.getPayload().toJSONObject();
- assertNotNull(payload.get("exp"));
- assertNotNull(payload.get("nonce"));
- assertEquals(nonce, payload.get("nonce").toString());
+ var crypto = new EcP256ProofOfPossessionJWSSigner(Path.of("src/test/data/assert-key-01"), didLogMeta.getDidDoc().getId() + "#my-assert-key-01");
+ var proofCreator = new ProofOfPossessionCreator(crypto);
- // CAUTION: MUST be invalid
- assertFalse(new ProofOfPossessionVerifier(didLog).isValid(proof, nonce));
+ assertThrowsExactly(NullPointerException.class, () -> proofCreator.create(nonce, null));
}
@Test
- void testCreateValidJWT_fail() throws Exception {
- var nonce = "my_nonce";
+ void create_withNonce_returnsJWTWithNullNonce() throws Exception {
+ var didLog = buildInitialWebVerifiableHistoryDidLogEntry(TEST_CRYPTO_SUITE);
+ var didLogMeta = WebVerifiableHistoryDidLogMetaPeeker.peek(didLog);
- var didLog = buildInitialTdwDidLogEntry(TEST_CRYPTO_SUITE);
+ var crypto = new EcP256ProofOfPossessionJWSSigner(Path.of("src/test/data/assert-key-01"), didLogMeta.getDidDoc().getId() + "#my-assert-key-01");
+ var proofCreator = new ProofOfPossessionCreator(crypto);
- // create proof
- var proof = new ProofOfPossessionCreator(TEST_POP_JWS_SIGNER)
- .create(nonce, ONE_DAY_LONG);
-
- // verify JWT (head/payload) claims
- var header = proof.getHeader();
- assertEquals(JWSAlgorithm.Ed25519, header.getAlgorithm());
- assertFalse(didLog.contains(header.getKeyID()));
- var payload = proof.getPayload().toJSONObject();
- assertNotNull(payload.get("exp"));
- assertNotNull(payload.get("nonce"));
- assertEquals(nonce, payload.get("nonce").toString());
+ var pop = proofCreator.create(null, ONE_DAY_LONG);
- // verify proof
- assertFalse(new ProofOfPossessionVerifier(didLog).isValid(proof, nonce));
+ var header = pop.getHeader();
+ assertEquals(JWSAlgorithm.ES256, pop.getHeader().getAlgorithm());
+ assertTrue(didLog.contains(header.getKeyID()));
+
+ var payload = pop.getPayload().toJSONObject();
+ assertNull(payload.get("nonce"));
}
}
diff --git a/src/test/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionJWSSignerTest.java b/src/test/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionJWSSignerTest.java
new file mode 100644
index 00000000..e4846042
--- /dev/null
+++ b/src/test/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionJWSSignerTest.java
@@ -0,0 +1,49 @@
+package ch.admin.bj.swiyu.didtoolbox;
+
+import ch.admin.bj.swiyu.didtoolbox.vc_data_integrity.VcDataIntegrityCryptographicSuiteException;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import org.junit.jupiter.api.Test;
+
+import java.nio.file.Path;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ProofOfPossessionJWSSignerTest {
+
+ private static final String KID = "did:webvh:scid:example.com#kid";
+
+ @Test
+ void of_validP256Pem_returnsJWSSigner() {
+ var path = Path.of("src/test/data/assert-key-01");
+ var signer = assertDoesNotThrow(() -> ProofOfPossessionJWSSigner.of(path, KID));
+
+ assertEquals(JWSAlgorithm.ES256, signer.getAlgorithm());
+ assertEquals(KID, signer.getKid());
+ assertNotNull(signer.getJCAContext());
+
+ var data = "Hello, world!".getBytes();
+ var header = new JWSHeader(JWSAlgorithm.ES256);
+ assertDoesNotThrow(() -> signer.sign(header, data));
+ }
+
+ @Test
+ void of_validEd25519Pem_returnsJWSSigner() {
+ var path = Path.of("src/test/data/private.pem");
+ var signer = assertDoesNotThrow(() -> ProofOfPossessionJWSSigner.of(path, KID));
+
+ assertEquals(JWSAlgorithm.EdDSA, signer.getAlgorithm());
+ assertEquals(KID, signer.getKid());
+ assertNotNull(signer.getJCAContext());
+
+ var data = "Hello, world!".getBytes();
+ var header = new JWSHeader(JWSAlgorithm.EdDSA);
+ assertDoesNotThrow(() -> signer.sign(header, data));
+ }
+
+ @Test
+ void of_invalidPemFile_returnsJWSSigner() {
+ var path = Path.of("src/test/data/README.md");
+ assertThrowsExactly(VcDataIntegrityCryptographicSuiteException.class, () -> ProofOfPossessionJWSSigner.of(path, KID));
+ }
+}
diff --git a/src/test/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionVerifierTest.java b/src/test/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionVerifierTest.java
index 6c46523c..928e98c6 100644
--- a/src/test/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionVerifierTest.java
+++ b/src/test/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionVerifierTest.java
@@ -2,17 +2,24 @@
import ch.admin.bj.swiyu.didtoolbox.model.WebVerifiableHistoryDidLogMetaPeeker;
import ch.admin.eid.did_sidekicks.DidDoc;
+import com.nimbusds.jose.JWSAlgorithm;
+import com.nimbusds.jose.JWSHeader;
+import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.nio.file.Path;
+import java.text.ParseException;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
@SuppressWarnings("PMD")
class ProofOfPossessionVerifierTest extends AbstractUtilTestBase {
+ private static final String NONCE = "example_nonce";
private static final Duration ONE_DAY_LONG = Duration.ofDays(1);
String didLog;
@@ -35,28 +42,44 @@ void testProofOfPossessionConstructor() {
}
@Test
- void testVerify() {
- var nonce = "my_nonce";
+ void isValid_withCreatorCreatedPoP_returnsTrue() {
+ // create proof
+ var proof = assertDoesNotThrow(() -> new ProofOfPossessionCreator(signer).create(NONCE, ONE_DAY_LONG));
+
+ var verifier = assertDoesNotThrow(() -> new ProofOfPossessionVerifier(didLog));
+ assertTrue(verifier.isValid(proof, NONCE));
+ }
+ @Test
+ void verify_withP256Key_doesNotThrow() {
// create proof
- var proof = assertDoesNotThrow(() -> new ProofOfPossessionCreator(signer).create(nonce, ONE_DAY_LONG));
+ var proof = assertDoesNotThrow(() -> new ProofOfPossessionCreator(signer).create(NONCE, ONE_DAY_LONG));
var verifier = assertDoesNotThrow(() -> new ProofOfPossessionVerifier(didLog));
- assertTrue(verifier.isValid(proof, nonce));
+ assertDoesNotThrow(() -> verifier.verify(proof, NONCE));
+ }
- assertDoesNotThrow(() -> verifier.verify(proof, nonce));
+ @Test
+ void verify_withEd25519Key_doesNotThrow() {
+ var didLog = """
+ {"versionId":"1-QmPuz69mEWiTum1PCzmu5zUgdG4vCKWi4FkBZTnMvGYHSa","versionTime":"2026-07-22T07:18:47Z","parameters":{"method":"did:webvh:1.0","scid":"QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP","updateKeys":["z6Mks5QkVWEK4w1GirvtzWpCkXUMoeiCEgTLdmuPTwpzxmLi"],"portable":false},"state":{"id":"did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com","profile_version":"swiss-profile-anchor:1.0.0","authentication":["did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com#auth-key-01","did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com#auth-key-02"],"assertionMethod":["did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com#assert-key-01","did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com#assert-key-02"],"verificationMethod":[{"id":"did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com#auth-key-01","controller":"did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com","type":"JsonWebKey2020","publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"OfyYdxv2AjSTMddJHONMFHnXLcZnPiQ1KGFa-AX75x0","kid":"auth-key-01"}},{"id":"did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com#auth-key-02","controller":"did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com","type":"JsonWebKey2020","publicKeyJwk":{"kty":"EC","crv":"P-256","kid":"auth-key-02","x":"CCw9szn4CYfHmTKluoERTU40QOX68ghbxQWz7HUsjuI","y":"6Bf9ySbmakgFx-aApAN2okcvZ-nqW-HvARS_mQd9010"}},{"id":"did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com#assert-key-01","controller":"did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com","type":"JsonWebKey2020","publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"-BfbOxS0VRGntlDa8TmcoXfEZP_EvpgKox67sARrlsE","kid":"assert-key-01"}},{"id":"did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com#assert-key-02","controller":"did:webvh:QmSDKjwjKxjf9Bie8F6V9Up9j6LUtv8TRawKVP64dVQXdP:example.com","type":"JsonWebKey2020","publicKeyJwk":{"kty":"EC","crv":"P-256","kid":"assert-key-02","x":"arXHklzxgekECtQ9QwTfEuCVMrJSdCte7KUWFrKQ8kI","y":"0NS2Z8ydCXU7IJoM86shegENExHgLGPfPx3Yi9YK9kM"}}]},"proof":[{"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","created":"2026-07-22T07:18:47Z","verificationMethod":"did:key:z6Mks5QkVWEK4w1GirvtzWpCkXUMoeiCEgTLdmuPTwpzxmLi#z6Mks5QkVWEK4w1GirvtzWpCkXUMoeiCEgTLdmuPTwpzxmLi","proofPurpose":"assertionMethod","proofValue":"z53mYjrN7WBdPoxp8LBCMbm7koYAqGCkEJQiu6TqjUTKk8x8oGGcM9PWSUX3mDzXAEuzjjhEFpEcCb4TwjCt6eqRf"}]}
+ """;
+ var jwt = "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDp3ZWJ2aDpRbVNES2p3akt4amY5QmllOEY2VjlVcDlqNkxVdHY4VFJhd0tWUDY0ZFZRWGRQOmV4YW1wbGUuY29tI2F1dGgta2V5LTAxIiwidHlwIjoiSldUIn0.eyJpc3MiOiJkaWQ6d2Vidmg6UW1TREtqd2pLeGpmOUJpZThGNlY5VXA5ajZMVXR2OFRSYXdLVlA2NGRWUVhkUDpleGFtcGxlLmNvbSIsImV4cCI6MTAwMDAwMDAwMDAsIm5vbmNlIjoibXlfbm9uY2UiLCJpYXQiOjE3ODQ3MDQ2Mjh9.eOF7PmbJwQ4qDtwpjH3yOVzUL9FC7V2VGEki0xgITOwrSD_uHfXCjZNJhELrno-TwsBaWh0t5Pf__beoT2-0Cw";
+ var verifier = assertDoesNotThrow(() -> new ProofOfPossessionVerifier(didLog));
+ var signedJWT = assertDoesNotThrow(() -> SignedJWT.parse(jwt));
+ assertDoesNotThrow(() -> verifier.verify(signedJWT, "my_nonce"));
}
@Test
void verify_KeyNotInDidLog() {
var nonce = "my_nonce";
signer = assertDoesNotThrow(() -> new EcP256ProofOfPossessionJWSSigner(Path.of("src/test/data/assert-key-01"), didDoc.getId() + "#my-assert-key-01-not-in-doc"));
- var proof = assertDoesNotThrow(() -> new ProofOfPossessionCreator(signer).create(nonce, ONE_DAY_LONG));
+ var proof = assertDoesNotThrow(() -> new ProofOfPossessionCreator(signer).create(NONCE, ONE_DAY_LONG));
// for the purpose, you may also use EXAMPLE_POP_JWS_SIGNER_ANOTHER here, instead
var verifier = assertDoesNotThrow(() -> new ProofOfPossessionVerifier(didLog)); // CAUTION: Using a whole other key
- var exc = assertThrowsExactly(ProofOfPossessionVerifierException.class, () -> verifier.verify(proof, nonce));
+ var exc = assertThrowsExactly(ProofOfPossessionVerifierException.class, () -> verifier.verify(proof, NONCE));
assertEquals(ProofOfPossessionVerifierException.ErrorCause.KEY_MISMATCH, exc.getErrorCause());
}
@@ -76,7 +99,7 @@ void verify_nonceMismatch_thenFailure() {
var proof = assertDoesNotThrow(() -> new ProofOfPossessionCreator(signer).create(nonce, ONE_DAY_LONG));
var verifier = assertDoesNotThrow(() -> new ProofOfPossessionVerifier(didLog));
- var exc = assertThrowsExactly(ProofOfPossessionVerifierException.class, () -> verifier.verify(proof, "foo"));
+ var exc = assertThrowsExactly(ProofOfPossessionVerifierException.class, () -> verifier.verify(proof, NONCE));
assertEquals(ProofOfPossessionVerifierException.ErrorCause.INVALID_NONCE, exc.getErrorCause());
}
@@ -87,7 +110,51 @@ void verify_unsupportedAlgorithm_thenFailure() {
var signedJWT = assertDoesNotThrow(() -> SignedJWT.parse(jwt));
var verifier = assertDoesNotThrow(() -> new ProofOfPossessionVerifier(didLog));
- var exc = assertThrowsExactly(ProofOfPossessionVerifierException.class, () -> verifier.verify(signedJWT, "foo"));
+ var exc = assertThrowsExactly(ProofOfPossessionVerifierException.class, () -> verifier.verify(signedJWT, NONCE));
assertEquals(ProofOfPossessionVerifierException.ErrorCause.UNSUPPORTED_ALGORITHM, exc.getErrorCause());
}
+
+ @Test
+ void verify_unparsableJWT_throwsProofOfPossessionVerifierException() throws ParseException {
+ var jwt = mock(SignedJWT.class);
+ var header = mock(JWSHeader.class);
+
+ when(jwt.getHeader()).thenReturn(header);
+ when(header.getAlgorithm()).thenReturn(JWSAlgorithm.EdDSA);
+ when(jwt.getJWTClaimsSet()).thenThrow(new ParseException("mock exception", 1));
+
+ var verifier = assertDoesNotThrow(() -> new ProofOfPossessionVerifier(didLog));
+ var exc = assertThrowsExactly(ProofOfPossessionVerifierException.class, () -> verifier.verify(jwt, NONCE));
+ assertEquals(ProofOfPossessionVerifierException.ErrorCause.UNPARSABLE, exc.getErrorCause());
+ }
+
+ @Test
+ void verify_getNonceThrowsException_throwsProofOfPossessionVerifierException() throws ParseException {
+ var jwt = mock(SignedJWT.class);
+ var header = mock(JWSHeader.class);
+ var claims = mock(JWTClaimsSet.class);
+
+ when(jwt.getHeader()).thenReturn(header);
+ when(header.getAlgorithm()).thenReturn(JWSAlgorithm.EdDSA);
+ when(jwt.getJWTClaimsSet()).thenReturn(claims);
+ when(claims.getStringClaim("nonce")).thenThrow(new ParseException("mock exception", 1));
+
+ var verifier = assertDoesNotThrow(() -> new ProofOfPossessionVerifier(didLog));
+ var exc = assertThrowsExactly(ProofOfPossessionVerifierException.class, () -> verifier.verify(jwt, NONCE));
+ assertEquals(ProofOfPossessionVerifierException.ErrorCause.UNPARSABLE, exc.getErrorCause());
+ }
+
+ @Test
+ void verify_noClaimset_throwsProofOfPosessionVerifierException() throws ParseException {
+ var jwt = mock(SignedJWT.class);
+ var header = mock(JWSHeader.class);
+
+ when(jwt.getHeader()).thenReturn(header);
+ when(header.getAlgorithm()).thenReturn(JWSAlgorithm.EdDSA);
+ when(jwt.getJWTClaimsSet()).thenThrow(new ParseException("mock exception", 1));
+
+ var verifier = assertDoesNotThrow(() -> new ProofOfPossessionVerifier(didLog));
+ var exc = assertThrowsExactly(ProofOfPossessionVerifierException.class, () -> verifier.verify(jwt, NONCE));
+ assertEquals(ProofOfPossessionVerifierException.ErrorCause.UNPARSABLE, exc.getErrorCause());
+ }
}
diff --git a/src/test/java/ch/admin/bj/swiyu/didtoolbox/jcommander/AbstractKeyMaterialDidLogCommandTest.java b/src/test/java/ch/admin/bj/swiyu/didtoolbox/jcommander/AbstractKeyMaterialDidLogCommandTest.java
index 60c8a869..64759a12 100644
--- a/src/test/java/ch/admin/bj/swiyu/didtoolbox/jcommander/AbstractKeyMaterialDidLogCommandTest.java
+++ b/src/test/java/ch/admin/bj/swiyu/didtoolbox/jcommander/AbstractKeyMaterialDidLogCommandTest.java
@@ -162,4 +162,9 @@ void getAuthentications_withoutMethodsAndExistingPrivateKeyFileNoOverwrite_throw
assertThrowsExactly(IOException.class, () -> command.getAuthentications(tmpDir));
}
+ @Test
+ void cryptoAlgorithm_perDefault_isP256() {
+ var command = new Command();
+ assertEquals(CryptographicAlgorithm.P256, command.cryptoAlgorithm);
+ }
}
diff --git a/src/test/java/ch/admin/bj/swiyu/didtoolbox/model/CryptographicAlgorithmTest.java b/src/test/java/ch/admin/bj/swiyu/didtoolbox/model/CryptographicAlgorithmTest.java
new file mode 100644
index 00000000..e90c2d69
--- /dev/null
+++ b/src/test/java/ch/admin/bj/swiyu/didtoolbox/model/CryptographicAlgorithmTest.java
@@ -0,0 +1,14 @@
+package ch.admin.bj.swiyu.didtoolbox.model;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class CryptographicAlgorithmTest {
+
+ @Test
+ void toString_returnsAlgorithmName() {
+ assertEquals("P-256", CryptographicAlgorithm.P256.toString());
+ assertEquals("Ed25519", CryptographicAlgorithm.ED25519.toString());
+ }
+}
diff --git a/src/test/java/ch/admin/bj/swiyu/didtoolbox/model/DidMethodEnumTest.java b/src/test/java/ch/admin/bj/swiyu/didtoolbox/model/DidMethodEnumTest.java
new file mode 100644
index 00000000..1dd2ba86
--- /dev/null
+++ b/src/test/java/ch/admin/bj/swiyu/didtoolbox/model/DidMethodEnumTest.java
@@ -0,0 +1,86 @@
+package ch.admin.bj.swiyu.didtoolbox.model;
+
+import org.junit.jupiter.api.Test;
+
+import java.text.ParseException;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class DidMethodEnumTest {
+
+ @Test
+ void parse_null_returnsNull() {
+ var version = assertDoesNotThrow(() -> DidMethodEnum.parse(null));
+ assertEquals(null, version);
+ }
+
+ @Test
+ void parse_tdwMixedCase_returnsTdw() {
+ var tdwStrig = "dId:TDw:0.3";
+ var version = assertDoesNotThrow(() -> DidMethodEnum.parse(tdwStrig));
+ assertEquals(DidMethodEnum.TDW_0_3, version);
+ }
+
+ @Test
+ void parse_webvhMixedCase_returnsTdw() {
+ var webvhString = "DiD:wEBvH:1.0";
+ var version = assertDoesNotThrow(() -> DidMethodEnum.parse(webvhString));
+ assertEquals(DidMethodEnum.WEBVH_1_0, version);
+ }
+
+ @Test
+ void parse_tdwWithWrongVersion_returnsTdw() {
+ var tdwString = "DiD:tDw:1.0";
+ assertThrowsExactly(ParseException.class, () -> DidMethodEnum.parse(tdwString));
+ }
+
+ @Test
+ void parse_webvhWithWrongVersion_returnsTdw() {
+ var webvhString = "DiD:wEBvH:0.3";
+ assertThrowsExactly(ParseException.class, () -> DidMethodEnum.parse(webvhString));
+ }
+
+ @Test
+ void isTdw03() {
+ assertTrue(DidMethodEnum.TDW_0_3.isTdw03());
+ assertFalse(DidMethodEnum.WEBVH_1_0.isTdw03());
+ }
+
+ @Test
+ void isWebv10() {
+ assertFalse(DidMethodEnum.TDW_0_3.isWebVh10());
+ assertTrue(DidMethodEnum.WEBVH_1_0.isWebVh10());
+ }
+
+ @Test
+ void detectDidMethod_withValidTdwLog_returnsTdw() {
+ var tdw = """
+ ["1-QmRVQ8EFiYfGqLXTpHSYMYXMcpFZwsy58gBeFYBEG3RPgj","2026-07-27T05:13:16Z",{"method":"did:tdw:0.3","scid":"QmY8Qa5YJynh7syyaUuBYSBJX18DjuYZ2BKsYBXoAv2VeC","updateKeys":["z6MkffRFEaq5wypbXTNK7AvmhvTWf4XiKVLomouvkpjuRPmP"],"portable":false},{"value":{"id":"did:tdw:QmY8Qa5YJynh7syyaUuBYSBJX18DjuYZ2BKsYBXoAv2VeC:example.com","authentication":["did:tdw:QmY8Qa5YJynh7syyaUuBYSBJX18DjuYZ2BKsYBXoAv2VeC:example.com#auth-key-01"],"assertionMethod":["did:tdw:QmY8Qa5YJynh7syyaUuBYSBJX18DjuYZ2BKsYBXoAv2VeC:example.com#assert-key-01"],"verificationMethod":[{"id":"did:tdw:QmY8Qa5YJynh7syyaUuBYSBJX18DjuYZ2BKsYBXoAv2VeC:example.com#auth-key-01","controller":"did:tdw:QmY8Qa5YJynh7syyaUuBYSBJX18DjuYZ2BKsYBXoAv2VeC:example.com","type":"JsonWebKey2020","publicKeyJwk":{"kty":"EC","crv":"P-256","kid":"auth-key-01","x":"5mEj0G8RrCIK6Y-LFN0XAwEpRwhvyqwuqZ-4yQp6p4U","y":"q5-z3xdICaa7hTAfc-0HTiyR-5XklJTsjfcKWG9tGaw"}},{"id":"did:tdw:QmY8Qa5YJynh7syyaUuBYSBJX18DjuYZ2BKsYBXoAv2VeC:example.com#assert-key-01","controller":"did:tdw:QmY8Qa5YJynh7syyaUuBYSBJX18DjuYZ2BKsYBXoAv2VeC:example.com","type":"JsonWebKey2020","publicKeyJwk":{"kty":"EC","crv":"P-256","kid":"assert-key-01","x":"bwUStKHLIRy3RN1lyqgOdgTXO8h80KfcbGIZdn0wzEY","y":"JJG7jrkfY8PpW_yjHMJoB8GbuXpZWdPGX06vGAJlfOY"}}]}},[{"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","created":"2026-07-27T05:13:16Z","verificationMethod":"did:key:z6MkffRFEaq5wypbXTNK7AvmhvTWf4XiKVLomouvkpjuRPmP#z6MkffRFEaq5wypbXTNK7AvmhvTWf4XiKVLomouvkpjuRPmP","proofPurpose":"authentication","challenge":"1-QmRVQ8EFiYfGqLXTpHSYMYXMcpFZwsy58gBeFYBEG3RPgj","proofValue":"z5SjoNbsuT8z7WTvhVFWtLA8HNiteaQVsViYktcQ9EBtBaXEzqpbSCUSnqBw8io7MmLJMYy2Y3L9CAw7FySzWGoLs"}]]
+ """;
+ var version = assertDoesNotThrow(() -> DidMethodEnum.detectDidMethod(tdw));
+ assertEquals(DidMethodEnum.TDW_0_3, version);
+ }
+
+ @Test
+ void detectDidMethod_withValidWebvhLog_returnsWebvh() {
+ var webvh = """
+ {"versionId":"1-QmRYUsgbt7VLoNNWoG2KNAjTHgiRVXGMTJZ2arPAp54HZv","versionTime":"2026-07-27T05:11:17Z","parameters":{"method":"did:webvh:1.0","scid":"QmNZxwVtNp68iTXdZUwjMMqyPS7Xj5JTZpr424whqkLXyW","updateKeys":["z6MkhcZ1SvznbP5SdGqDXFJeZWtMebj9sFvk7VdLVBwBs57Z"],"portable":false},"state":{"id":"did:webvh:QmNZxwVtNp68iTXdZUwjMMqyPS7Xj5JTZpr424whqkLXyW:example.com","profile_version":"swiss-profile-anchor:1.0.0","authentication":["did:webvh:QmNZxwVtNp68iTXdZUwjMMqyPS7Xj5JTZpr424whqkLXyW:example.com#auth-key-01"],"assertionMethod":["did:webvh:QmNZxwVtNp68iTXdZUwjMMqyPS7Xj5JTZpr424whqkLXyW:example.com#assert-key-01"],"verificationMethod":[{"id":"did:webvh:QmNZxwVtNp68iTXdZUwjMMqyPS7Xj5JTZpr424whqkLXyW:example.com#auth-key-01","controller":"did:webvh:QmNZxwVtNp68iTXdZUwjMMqyPS7Xj5JTZpr424whqkLXyW:example.com","type":"JsonWebKey2020","publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"pKBaly1Q4Ef6ZQDLmMHYYM40JvdvsBSEmUrqD6AxUeE","kid":"auth-key-01"}},{"id":"did:webvh:QmNZxwVtNp68iTXdZUwjMMqyPS7Xj5JTZpr424whqkLXyW:example.com#assert-key-01","controller":"did:webvh:QmNZxwVtNp68iTXdZUwjMMqyPS7Xj5JTZpr424whqkLXyW:example.com","type":"JsonWebKey2020","publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"AAuX9zdzGa2lm8NgLGpDm0iwDEfhjf3t7yMGhrJYkEQ","kid":"assert-key-01"}}]},"proof":[{"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","created":"2026-07-27T05:11:17Z","verificationMethod":"did:key:z6MkhcZ1SvznbP5SdGqDXFJeZWtMebj9sFvk7VdLVBwBs57Z#z6MkhcZ1SvznbP5SdGqDXFJeZWtMebj9sFvk7VdLVBwBs57Z","proofPurpose":"assertionMethod","proofValue":"z26ATsdLQXp2kBSCEPwSyasGChdqUJJ6gaHmQbzrrXSSjxoauL5SxqgKwNpa51WLQ1GwbgG2k3nccbbDtpgi5AsxA"}]}
+ """;
+ var version = assertDoesNotThrow(() -> DidMethodEnum.detectDidMethod(webvh));
+ assertEquals(DidMethodEnum.WEBVH_1_0, version);
+ }
+
+ @Test
+ void detectDidMethod_nonDidLogJson_throws() {
+ var json = """
+ {"foo": "bar", "numbers: [1,2,3,4,5]}
+ """;
+ assertThrowsExactly(DidLogMetaPeekerException.class, () -> DidMethodEnum.detectDidMethod(json));
+ }
+
+ @Test
+ void detectDidMethod_ofNull_throwsNullPointerException() {
+ String didLog = null;
+ assertThrowsExactly(NullPointerException.class,() -> DidMethodEnum.detectDidMethod(didLog));
+ }
+}
diff --git a/src/test/java/ch/admin/bj/swiyu/didtoolbox/model/ProfileVersionTest.java b/src/test/java/ch/admin/bj/swiyu/didtoolbox/model/ProfileVersionTest.java
new file mode 100644
index 00000000..49f6b6b7
--- /dev/null
+++ b/src/test/java/ch/admin/bj/swiyu/didtoolbox/model/ProfileVersionTest.java
@@ -0,0 +1,19 @@
+package ch.admin.bj.swiyu.didtoolbox.model;
+
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class ProfileVersionTest {
+
+ @Test
+ void toString_returnsFormattedProfileVersion() {
+ assertEquals("swiss-profile-anchor:1.0.0", ProfileVersion.SWISS_PROFILE_ANCHOR_1_0_0.toString());
+ }
+
+ @Test
+ void getLatest_returnsProfileAnchor1_0_0() {
+ assertEquals(ProfileVersion.SWISS_PROFILE_ANCHOR_1_0_0, ProfileVersion.getLatest());
+ }
+}
diff --git a/src/test/java/ch/admin/bj/swiyu/didtoolbox/vc_data_integrity/VcDataIntegrityCryptographicSuiteTest.java b/src/test/java/ch/admin/bj/swiyu/didtoolbox/vc_data_integrity/VcDataIntegrityCryptographicSuiteTest.java
new file mode 100644
index 00000000..a8a3b105
--- /dev/null
+++ b/src/test/java/ch/admin/bj/swiyu/didtoolbox/vc_data_integrity/VcDataIntegrityCryptographicSuiteTest.java
@@ -0,0 +1,40 @@
+package ch.admin.bj.swiyu.didtoolbox.vc_data_integrity;
+
+import org.junit.jupiter.api.Test;
+
+import java.time.ZonedDateTime;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
+
+public class VcDataIntegrityCryptographicSuiteTest {
+
+ @Test
+ void verifyProof_defaultImplementation_throwsIllegalArgumentException() {
+ var cryptoSuite = new CryptographicSuite();
+ assertThrowsExactly(IllegalArgumentException.class, () -> cryptoSuite.verifyProof("", ""));
+ }
+
+ // Class that just implements the VcDataIntegrityCryptographicSuite interface to test the default implementations.
+ private class CryptographicSuite implements VcDataIntegrityCryptographicSuite {
+ @Override
+ public String addProof(String unsecuredDocument, String challenge, String proofPurpose, ZonedDateTime dateTime) throws VcDataIntegrityCryptographicSuiteException {
+ return "";
+ }
+
+ @Override
+ public String getVerificationKeyMultibase() {
+ return "";
+ }
+
+ @Override
+ public byte[] generateSignature(byte[] message) {
+ return new byte[0];
+ }
+
+ @Override
+ public boolean isKeyMultibaseInSet(Set multibaseEncodedKeys) {
+ return false;
+ }
+ }
+}