Skip to content

Commit 87ffd06

Browse files
committed
EIDOMNI-708: Reviewer remarks taken into account, hence cleanup and optimization
1 parent 7dacfd7 commit 87ffd06

19 files changed

Lines changed: 205 additions & 74 deletions

examples/using-pre-rotation-keys/src/main/java/org/examples/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static String build() throws URISyntaxException, IOException, DidLogCreatorStrat
5959
//,NextKeyHashesDidMethodParameter.of(RandomEd25519KeyStore.rotate().getPublicKey())
6060
))
6161
.assertionMethods(Set.of(VerificationMethod.of("my-assert-key-01", Path.of("../../src/test/data/assert-key-01.pub"))))
62-
//.authentications(Set.of(VerificationMethod.of("my-auth-key-01", Path.of("../../src/test/data/auth-key-01.pub"))))
62+
.authentications(Set.of(VerificationMethod.of("my-auth-key-01", Path.of("../../src/test/data/auth-key-01.pub"))))
6363
.build()
6464
.create(URL.of(new URI("https://identifier-reg.trust-infra.swiyu-int.admin.ch/api/v1/did/18fa7c77-9dd1-4e20-a147-fb1bec146085"), null))
6565
).append(System.lineSeparator());

src/main/java/ch/admin/bj/swiyu/didtoolbox/AbstractDidLogEntryBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ public abstract class AbstractDidLogEntryBuilder {
2121

2222
protected DidLogMeta didLogMeta;
2323

24-
protected static JsonObject buildVerificationMethodWithPublicKeyJwk(String didTDW, String keyID, String publicKeyJwk) {
24+
protected static JsonObject buildVerificationMethodWithPublicKeyJwk(String did, String fragmentId, String publicKeyJwk) {
2525

2626
var verificationMethodObj = new JsonObject();
27-
verificationMethodObj.addProperty("id", didTDW + "#" + keyID);
27+
verificationMethodObj.addProperty("id", did + "#" + fragmentId);
2828
// CAUTION The "controller" property must not be present w.r.t.:
2929
// - https://confluence.bit.admin.ch/x/3e0EMw
3030
verificationMethodObj.addProperty("type", "JsonWebKey2020");

src/main/java/ch/admin/bj/swiyu/didtoolbox/JwkUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public static String loadECPublicJWKasJSON(Path ecPublicPemPath, String kid) thr
6363
throw new IllegalArgumentException(String.format("The supplied key ID (kid) of the JWK '%s' must be a regular case-sensitive string featuring no URIs reserved characters", kid));
6464
}
6565

66-
ECPublicKey publicKey = (ECPublicKey) PemUtils.parsePemPublicKey(Files.newBufferedReader(ecPublicPemPath));
66+
var publicKey = (ECPublicKey) PemUtils.parsePemPublicKey(Files.newBufferedReader(ecPublicPemPath));
6767

6868
return (new ECKey.Builder(Curve.P_256, publicKey)).keyID(kid).build().toPublicJWK().toJSONString();
6969
}

src/main/java/ch/admin/bj/swiyu/didtoolbox/PemUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ static PrivateKey parsePemPrivateKey(Reader pemPrivateKeyReader) throws IOExcept
8383
throw new IllegalArgumentException("The supplied reader features no PEM-encoded private key");
8484
}
8585

86-
static PublicKey parsePemPublicKey(Reader pemPublicKeyReader) throws IOException {
86+
public static PublicKey parsePemPublicKey(Reader pemPublicKeyReader) throws IOException {
8787
final PEMParser parser = new PEMParser(pemPublicKeyReader);
8888
var pemObj = parser.readObject();
8989

src/main/java/ch/admin/bj/swiyu/didtoolbox/ProofOfPossessionCreatorException.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ public class ProofOfPossessionCreatorException extends Exception {
1313
@Serial
1414
private static final long serialVersionUID = -8688911417489177064L;
1515

16-
public ProofOfPossessionCreatorException(String message) {
17-
super(message);
18-
}
19-
2016
public ProofOfPossessionCreatorException(Exception e) {
2117
super(e);
2218
}
Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,71 @@
11
package ch.admin.bj.swiyu.didtoolbox.model;
22

3+
import ch.admin.bj.swiyu.didtoolbox.PemUtils;
34
import com.nimbusds.jose.jwk.Curve;
45
import com.nimbusds.jose.jwk.ECKey;
56

7+
import java.io.IOException;
8+
import java.nio.file.Files;
9+
import java.nio.file.Path;
610
import java.security.interfaces.ECPublicKey;
711

812
/**
913
* <a href="https://www.w3.org/TR/did-1.0/#verification-material">Verification material</a> is any information that is used by a process that applies a
1014
* <a href="https://www.w3.org/TR/did-1.0/#dfn-verification-method">verification method</a>.
1115
* <p>
16+
* This interface models <a href="https://www.w3.org/TR/did-1.0/#verification-material">verification material</a> with sole focus on
17+
* <a href="https://www.w3.org/TR/did-1.0/#dfn-publickeyjwk">publicKeyJwk</a> property. Ergo, beware that also optional
18+
* <a href="https://www.w3.org/TR/did-1.0/#dfn-publickeymultibase">publicKeyMultibase</a> property is at this point not
19+
* (yet) relevant for the interface and therefore not (yet) modeled.
20+
* <p>
1221
* The interface also features a several convenient static factory methods focusing on standard Java types typically used for the purpose
13-
* of holding EC/P-256 public keys e.g. {@link ECPublicKey}.
22+
* of holding public EC keys, e.g. {@link ECPublicKey} or {@link Path}.
23+
*
24+
* @since 1.9.0
1425
*/
1526
public interface VerificationMaterial {
1627

1728
/**
1829
* Yet another static factory method of the interface.
1930
* <p>
20-
* Assuming the supplied {@code ecPublicKey} represents a valid EC/P-256 public key,
21-
* a valid {@link VerificationMaterial} object is returned of type <a href="https://w3c-ccg.github.io/lds-jws2020/">JsonWebKey2020</a>.
31+
* For the supplied public Elliptic Curve key {@code ecPublicKey},
32+
* a valid {@link VerificationMaterial} implementation object is returned featuring {@link #getPublicKeyJwk()} method
33+
* that always returns JSON representation of the Elliptic Curve JWK with any private values removed.
34+
* The cryptographic curve is always P-256 (secp256r1, also called prime256v1, OID = 1.2.840.10045.3.1.7).
2235
*
2336
* @param kid non-empty string representing a <a href="https://www.rfc-editor.org/rfc/rfc7517#section-4.5">"kid" (Key ID) Parameter</a>
24-
* @param ecPublicKey valid EC/P-256 public key
25-
* @return a valid {@link VerificationMaterial} implementation object, never {@code null}
37+
* @param ecPublicKey The public EC key to represent. Must not be {@code null}
38+
* @return a valid {@link VerificationMaterial} implementation object representing Elliptic Curve JWK with any
39+
* private values removed, never {@code null}
2640
*/
2741
static VerificationMaterial of(String kid, ECPublicKey ecPublicKey) {
2842

29-
return new VerificationMaterial() {
30-
@Override
31-
public String getPublicKeyJwk() {
32-
return (new ECKey.Builder(Curve.P_256, ecPublicKey)).keyID(kid).build().toPublicJWK().toJSONString();
33-
}
43+
return () -> (new ECKey.Builder(Curve.P_256, ecPublicKey)).keyID(kid).build().toPublicJWK().toJSONString();
44+
}
3445

35-
@Override
36-
public String getPublicKeyMultibase() {
37-
return null;
38-
}
39-
};
46+
/**
47+
* Yet another static factory method of the interface.
48+
* <p>
49+
* For the supplied public Elliptic Curve key {@code ecPublicKey},
50+
* a valid {@link VerificationMaterial} implementation object is returned featuring {@link #getPublicKeyJwk()} method
51+
* that always returns JSON representation of the Elliptic Curve JWK with any private values removed.
52+
* The cryptographic curve is always P-256 (secp256r1, also called prime256v1, OID = 1.2.840.10045.3.1.7).
53+
*
54+
* @param kid non-empty string representing a <a href="https://www.rfc-editor.org/rfc/rfc7517#section-4.5">"kid" (Key ID) Parameter</a>
55+
* @param ecPublicKeyPemPath file featuring a proper public EC key in PEM format
56+
* @return a valid {@link VerificationMaterial} implementation object representing Elliptic Curve JWK with any
57+
* @throws IOException if the supplied {@code ecPublicKeyPemPath} does not feature a proper public EC key in PEM format
58+
* private values removed, never {@code null}
59+
*/
60+
static VerificationMaterial of(String kid, Path ecPublicKeyPemPath) throws IOException {
61+
var ecPublicKey = (ECPublicKey) PemUtils.parsePemPublicKey(Files.newBufferedReader(ecPublicKeyPemPath));
62+
return () -> (new ECKey.Builder(Curve.P_256, ecPublicKey)).keyID(kid).build().toPublicJWK().toJSONString();
4063
}
4164

4265
/**
4366
* As <a href="https://www.w3.org/TR/did-1.0/#dfn-publickeyjwk">specified</a>:
4467
* <pre>
45-
* The publicKeyJwk property is OPTIONAL. If present, the value MUST be a map representing a JSON Web Key that conforms to [RFC7517].
68+
* The {@code publicKeyJwk} property is OPTIONAL. If present, the value MUST be a map representing a JSON Web Key that conforms to [RFC7517].
4669
* The map MUST NOT contain "d", or any other members of the private information class as described in Registration Template.
4770
* It is RECOMMENDED that verification methods that use JWKs [RFC7517] to represent their public keys use the value of kid as their fragment identifier.
4871
* It is RECOMMENDED that JWK kid values are set to the public key fingerprint [RFC7638].
@@ -52,16 +75,4 @@ public String getPublicKeyMultibase() {
5275
* Or {@code null} denoting its optional nature.
5376
*/
5477
String getPublicKeyJwk();
55-
56-
/**
57-
* As <a href="https://www.w3.org/TR/did-1.0/#dfn-publickeymultibase">specified</a>:
58-
* <pre>
59-
* The publicKeyMultibase property is OPTIONAL. This feature is non-normative.
60-
* If present, the value MUST be a string representation of a [MULTIBASE] encoded public key.
61-
* </pre>
62-
*
63-
* @return a string representation of a [MULTIBASE] encoded public key.
64-
* Or {@code null} denoting its optional nature.
65-
*/
66-
String getPublicKeyMultibase();
6778
}

src/main/java/ch/admin/bj/swiyu/didtoolbox/model/VerificationMethod.java

Lines changed: 115 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
package ch.admin.bj.swiyu.didtoolbox.model;
22

3-
import ch.admin.bj.swiyu.didtoolbox.JwkUtils;
43
import com.google.gson.JsonObject;
54
import com.google.gson.JsonParser;
65
import com.google.gson.JsonSyntaxException;
76

87
import java.io.IOException;
98
import java.nio.file.Path;
109
import java.security.interfaces.ECPublicKey;
11-
import java.security.spec.InvalidKeySpecException;
1210
import java.util.Objects;
1311

1412
/**
@@ -18,23 +16,39 @@
1816
* or authorize interactions with the <a href="https://www.w3.org/TR/did-1.0/#dfn-did-subjects">DID subject</a> or associated parties.
1917
* <p>
2018
* The interface also features a several convenient static factory methods focusing on standard Java types typically used for the purpose
21-
* of holding EC/P-256 public keys e.g. {@link ECPublicKey}, {@link Path} or {@link String}.
19+
* of holding public EC public keys e.g. {@link ECPublicKey}, {@link Path} or {@link String}.
20+
*
21+
* @since 1.9.0
2222
*/
2323
public interface VerificationMethod {
2424

25+
/**
26+
* The string representation of the
27+
* <a href="https://www.w3.org/TR/did-1.0/#dfn-verification-method">verification method</a> type behind
28+
* <a href="https://w3c-ccg.github.io/lds-jws2020/#json-web-key-2020">JsonWebKey2020</a>, which is
29+
* the type of the verification method for the signature suite {@code JsonWebSignature2020}.
30+
*/
31+
String VM_TYPE_JSON_WEB_KEY_2020 = "JsonWebKey2020";
32+
2533
/**
2634
* Yet another static factory method of the interface.
2735
* <p>
28-
* Assuming the supplied {@code publicKeyJwk} represents a proper EC/P-256 <a href="https://www.rfc-editor.org/rfc/rfc7517">JSON Web Key (JWK)</a>,
29-
* a valid {@link VerificationMethod} object is returned of type <a href="https://w3c-ccg.github.io/lds-jws2020/">JsonWebKey2020</a>.
36+
* Assuming the supplied {@code publicKeyJwk} represents a proper <a href="https://www.rfc-editor.org/rfc/rfc7517">JSON Web Key (JWK)</a>
37+
* featuring <a href="https://www.rfc-editor.org/rfc/rfc7517#section-4.1">"kty" (Key Type)</a>, {@code crv}, {@code x} and {@code y} parameters,
38+
* a valid {@link VerificationMethod} implementation object is returned featuring
39+
* {@link VerificationMethod#getVerificationMaterial()} method that always returns a valid
40+
* {@link VerificationMaterial} implementation object of type {@code type}
41+
* (e.g. {@link #VM_TYPE_JSON_WEB_KEY_2020}).
3042
*
3143
* @param kid non-empty string representing a <a href="https://www.rfc-editor.org/rfc/rfc7517#section-4.5">"kid" (Key ID) Parameter</a>
44+
* @param type string representation of a <a href="https://www.w3.org/TR/did-1.0/#dfn-verification-method">verification method</a> type
45+
* (e.g. <{@link #VM_TYPE_JSON_WEB_KEY_2020})
3246
* @param publicKeyJwk string representation of a <a href="https://www.rfc-editor.org/rfc/rfc7517">JSON Web Key (JWK)</a>
3347
* @return a valid {@link VerificationMethod} implementation object, never {@code null}
3448
* @throws VerificationMethodException if the supplied {@code publicKeyJwk} does not represent a proper
35-
* <a href="https://www.rfc-editor.org/rfc/rfc7517">JSON Web Key (JWK)</a>
49+
* <a href="https://www.rfc-editor.org/rfc/rfc7517">JSON Web Key (JWK)</a> as described above
3650
*/
37-
static VerificationMethod of(String kid, String publicKeyJwk) throws VerificationMethodException {
51+
static VerificationMethod of(String kid, String type, String publicKeyJwk) throws VerificationMethodException {
3852

3953
JsonObject jsonObj;
4054
try {
@@ -60,7 +74,7 @@ public String getIdFragment() {
6074

6175
@Override
6276
public String getType() {
63-
return "JsonWebKey2020";
77+
return type;
6478
}
6579

6680
@Override
@@ -71,11 +85,6 @@ public String getPublicKeyJwk() {
7185
jsonObj.addProperty("kid", kid);
7286
return jsonObj.toString();
7387
}
74-
75-
@Override
76-
public String getPublicKeyMultibase() {
77-
return null;
78-
}
7988
};
8089
}
8190

@@ -94,33 +103,100 @@ public int hashCode() {
94103
/**
95104
* Yet another static factory method of the interface.
96105
* <p>
97-
* Assuming the supplied {@code pemPath} denotes a file featuring a proper EC/P-256 public key,
98-
* a valid {@link VerificationMethod} object is returned of type <a href="https://w3c-ccg.github.io/lds-jws2020/">JsonWebKey2020</a>.
106+
* It is nothing but a variant of the {@link #of(String, String, String)}
107+
* static factory method having {@link #VM_TYPE_JSON_WEB_KEY_2020} as {@code type}.
108+
*
109+
* @see #of(String, String, String)
110+
* @see #VM_TYPE_JSON_WEB_KEY_2020
111+
*/
112+
static VerificationMethod of(String kid, String publicKeyJwk) throws VerificationMethodException {
113+
return VerificationMethod.of(kid, VM_TYPE_JSON_WEB_KEY_2020, publicKeyJwk);
114+
}
115+
116+
/**
117+
* Yet another static factory method of the interface.
118+
* <p>
119+
* Assuming the supplied {@code ecPublicKeyPemPath} denotes a file featuring a proper (PEM-encoded) public EC key,
120+
* a valid {@link VerificationMethod} implementation object is returned featuring
121+
* {@link VerificationMethod#getVerificationMaterial()} method that always returns a valid
122+
* {@link VerificationMaterial} implementation object of type {@code type}
123+
* (e.g. {@link #VM_TYPE_JSON_WEB_KEY_2020}).
99124
*
100-
* @param kid non-empty string representing a <a href="https://www.rfc-editor.org/rfc/rfc7517#section-4.5">"kid" (Key ID) Parameter</a>
101-
* @param pemPath file featuring a proper EC/P-256 public key in PEM format
125+
* @param kid non-empty string representing a <a href="https://www.rfc-editor.org/rfc/rfc7517#section-4.5">"kid" (Key ID) Parameter</a>
126+
* @param type string representation of a <a href="https://www.w3.org/TR/did-1.0/#dfn-verification-method">verification method</a> type
127+
* (e.g. <{@link #VM_TYPE_JSON_WEB_KEY_2020})
128+
* @param ecPublicKeyPemPath file featuring a proper public EC key in PEM format
102129
* @return a valid {@link VerificationMethod} implementation object, never {@code null}
103-
* @throws VerificationMethodException if the supplied {@code pemPath} does not feature a proper EC/P-256 public key in PEM format
130+
* @throws VerificationMethodException if the supplied {@code ecPublicKeyPemPath} does not feature a proper public EC key in PEM format
131+
* @see #of(String, String, String)
104132
*/
105-
static VerificationMethod of(String kid, Path pemPath) throws VerificationMethodException {
133+
static VerificationMethod of(String kid, String type, Path ecPublicKeyPemPath) throws VerificationMethodException {
134+
135+
VerificationMaterial vm;
106136
try {
107-
return VerificationMethod.of(kid, JwkUtils.loadECPublicJWKasJSON(pemPath, kid));
108-
} catch (IOException | InvalidKeySpecException exc) {
137+
vm = VerificationMaterial.of(kid, ecPublicKeyPemPath);
138+
} catch (IOException exc) {
109139
throw new VerificationMethodException(exc);
110140
}
141+
142+
return new VerificationMethod() {
143+
@Override
144+
public String getIdFragment() {
145+
return kid;
146+
}
147+
148+
@Override
149+
public String getType() {
150+
return type;
151+
}
152+
153+
@Override
154+
public VerificationMaterial getVerificationMaterial() {
155+
return vm;
156+
}
157+
158+
@Override
159+
public boolean equals(Object obj) {
160+
return this.defaultEquals(obj);
161+
}
162+
163+
@Override
164+
public int hashCode() {
165+
return Objects.hash(this.getIdFragment());
166+
}
167+
};
111168
}
112169

113170
/**
114171
* Yet another static factory method of the interface.
115172
* <p>
116-
* Assuming the supplied {@code publicKeyJwk} represents a valid EC/P-256 public key,
117-
* a valid {@link VerificationMethod} object is returned of type <a href="https://w3c-ccg.github.io/lds-jws2020/">JsonWebKey2020</a>.
173+
* It is nothing but a variant of the {@link #of(String, String, Path)}
174+
* static factory method having {@link #VM_TYPE_JSON_WEB_KEY_2020} as {@code type}.
175+
*
176+
* @see #of(String, String, Path)
177+
* @see #VM_TYPE_JSON_WEB_KEY_2020
178+
*/
179+
static VerificationMethod of(String kid, Path pemPath) throws VerificationMethodException {
180+
return VerificationMethod.of(kid, VM_TYPE_JSON_WEB_KEY_2020, pemPath);
181+
}
182+
183+
/**
184+
* Yet another static factory method of the interface.
185+
* <p>
186+
* For the supplied public EC key {@code ecPublicKey},
187+
* a valid {@link VerificationMethod} implementation object is returned featuring
188+
* {@link VerificationMethod#getVerificationMaterial()} method that always returns a valid
189+
* {@link VerificationMaterial} implementation object of type {@code type}
190+
* (e.g. {@link #VM_TYPE_JSON_WEB_KEY_2020}).
118191
*
119192
* @param kid non-empty string representing a <a href="https://www.rfc-editor.org/rfc/rfc7517#section-4.5">"kid" (Key ID) Parameter</a>
120-
* @param ecPublicKey valid EC/P-256 public key
193+
* @param type string representation of a <a href="https://www.w3.org/TR/did-1.0/#dfn-verification-method">verification method</a> type
194+
* (e.g. <{@link #VM_TYPE_JSON_WEB_KEY_2020})
195+
* @param ecPublicKey valid public EC public key
121196
* @return a valid {@link VerificationMethod} implementation object, never {@code null}
197+
* @see VerificationMaterial#of(String, ECPublicKey)
122198
*/
123-
static VerificationMethod of(String kid, ECPublicKey ecPublicKey) {
199+
static VerificationMethod of(String kid, String type, ECPublicKey ecPublicKey) {
124200
return new VerificationMethod() {
125201
@Override
126202
public String getIdFragment() {
@@ -129,7 +205,7 @@ public String getIdFragment() {
129205

130206
@Override
131207
public String getType() {
132-
return "JsonWebKey2020";
208+
return type;
133209
}
134210

135211
@Override
@@ -149,6 +225,19 @@ public int hashCode() {
149225
};
150226
}
151227

228+
/**
229+
* Yet another static factory method of the interface.
230+
* <p>
231+
* It is nothing but a variant of the {@link #of(String, String, ECPublicKey)}
232+
* static factory method having {@link #VM_TYPE_JSON_WEB_KEY_2020} as {@code type}.
233+
*
234+
* @see #of(String, String, ECPublicKey)
235+
* @see #VM_TYPE_JSON_WEB_KEY_2020
236+
*/
237+
static VerificationMethod of(String kid, ECPublicKey ecPublicKey) {
238+
return VerificationMethod.of(kid, VM_TYPE_JSON_WEB_KEY_2020, ecPublicKey);
239+
}
240+
152241
/**
153242
* As <a href="https://www.w3.org/TR/did-1.0/#dfn-verificationmethod">specified</a>
154243
* and w.r.t. <a href="https://www.rfc-editor.org/rfc/rfc3986#section-3.5">RFC3986</a>

0 commit comments

Comments
 (0)