Skip to content

Commit c99c37a

Browse files
committed
feat: Better support for JWT presentations.
1 parent c6cbbfe commit c99c37a

File tree

4 files changed

+109
-31
lines changed

4 files changed

+109
-31
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.danubetech.verifiablecredentials.jwt;
2+
3+
import com.danubetech.verifiablecredentials.VerifiablePresentation;
4+
import com.nimbusds.jose.JWSObject;
5+
import com.nimbusds.jwt.JWTClaimsSet;
6+
7+
import java.io.IOException;
8+
import java.util.Date;
9+
import java.util.UUID;
10+
11+
public class JwtJwtVerifiablePresentation extends JwtWrappingObject<JwtVerifiableCredential> {
12+
13+
private JwtJwtVerifiablePresentation(JWTClaimsSet payload, JwtVerifiableCredential payloadObject, JWSObject jwsObject, String compactSerialization) {
14+
15+
super(payload, payloadObject, jwsObject, compactSerialization);
16+
}
17+
18+
/*
19+
* Factory methods
20+
*/
21+
22+
public static JwtJwtVerifiablePresentation fromJwtVerifiableCredential(JwtVerifiableCredential jwtVerifiableCredential, String aud) throws IOException {
23+
24+
JwtVerifiableCredential payloadJwtVerifiableCredential = jwtVerifiableCredential;
25+
VerifiablePresentation verifiablePresentation = FromJwtConverter.fromJwtVerifiableCredentialToVerifiablePresentation(payloadJwtVerifiableCredential);
26+
27+
JWTClaimsSet.Builder payloadBuilder = new JWTClaimsSet.Builder();
28+
29+
Date issueTime = new Date();
30+
31+
payloadBuilder.jwtID("urn:uuid:" + UUID.randomUUID().toString());
32+
payloadBuilder.issuer(jwtVerifiableCredential.getPayload().getSubject());
33+
payloadBuilder.issueTime(issueTime);
34+
payloadBuilder.notBeforeTime(issueTime);
35+
if (aud != null) payloadBuilder.audience(aud);
36+
37+
payloadBuilder.claim(JwtKeywords.JWT_CLAIM_VP, verifiablePresentation.getJsonObject());
38+
39+
return new JwtJwtVerifiablePresentation(payloadBuilder.build(), payloadJwtVerifiableCredential, null, null);
40+
}
41+
42+
public static JwtJwtVerifiablePresentation fromJwtVerifiableCredential(JwtVerifiableCredential jwtVerifiableCredential) throws IOException {
43+
44+
return fromJwtVerifiableCredential(jwtVerifiableCredential, null);
45+
}
46+
}
Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
package com.danubetech.verifiablecredentials.jwt;
22

3+
import com.danubetech.verifiablecredentials.VerifiableCredential;
34
import com.danubetech.verifiablecredentials.VerifiablePresentation;
45
import com.nimbusds.jose.JWSObject;
56
import com.nimbusds.jwt.JWTClaimsSet;
7+
import com.nimbusds.jwt.SignedJWT;
68

7-
import java.io.IOException;
8-
import java.util.Date;
9-
import java.util.UUID;
9+
import java.text.ParseException;
10+
import java.util.LinkedHashMap;
11+
import java.util.Map;
1012

11-
public class JwtVerifiablePresentation extends JwtWrappingObject<JwtVerifiableCredential> {
13+
public class JwtVerifiablePresentation extends JwtWrappingObject<VerifiablePresentation> {
1214

13-
private JwtVerifiablePresentation(JWTClaimsSet payload, JwtVerifiableCredential payloadObject, JWSObject jwsObject, String compactSerialization) {
15+
public JwtVerifiablePresentation(JWTClaimsSet payload, VerifiablePresentation payloadObject, JWSObject jwsObject, String compactSerialization) {
1416

1517
super(payload, payloadObject, jwsObject, compactSerialization);
1618
}
@@ -19,28 +21,14 @@ private JwtVerifiablePresentation(JWTClaimsSet payload, JwtVerifiableCredential
1921
* Factory methods
2022
*/
2123

22-
public static JwtVerifiablePresentation fromJwtVerifiableCredential(JwtVerifiableCredential jwtVerifiableCredential, String aud) throws IOException {
24+
public static JwtVerifiablePresentation fromCompactSerialization(String compactSerialization) throws ParseException {
2325

24-
JwtVerifiableCredential payloadJwtVerifiableCredential = jwtVerifiableCredential;
25-
VerifiablePresentation verifiablePresentation = FromJwtConverter.fromJwtVerifiableCredentialToVerifiablePresentation(payloadJwtVerifiableCredential);
26+
SignedJWT signedJWT = SignedJWT.parse(compactSerialization);
2627

27-
JWTClaimsSet.Builder payloadBuilder = new JWTClaimsSet.Builder();
28+
JWTClaimsSet jwtPayload = signedJWT.getJWTClaimsSet();
29+
Map<String, Object> jsonObject = (Map<String, Object>) jwtPayload.getClaims().get(JwtKeywords.JWT_CLAIM_VC);
30+
VerifiablePresentation payloadVerifiablePresentation = VerifiablePresentation.fromJsonObject(new LinkedHashMap<>(jsonObject));
2831

29-
Date issueTime = new Date();
30-
31-
payloadBuilder.jwtID("urn:uuid:" + UUID.randomUUID().toString());
32-
payloadBuilder.issuer(jwtVerifiableCredential.getPayload().getSubject());
33-
payloadBuilder.issueTime(issueTime);
34-
payloadBuilder.notBeforeTime(issueTime);
35-
if (aud != null) payloadBuilder.audience(aud);
36-
37-
payloadBuilder.claim(JwtKeywords.JWT_CLAIM_VP, verifiablePresentation.getJsonObject());
38-
39-
return new JwtVerifiablePresentation(payloadBuilder.build(), payloadJwtVerifiableCredential, null, null);
40-
}
41-
42-
public static JwtVerifiablePresentation fromJwtVerifiableCredential(JwtVerifiableCredential jwtVerifiableCredential) throws IOException {
43-
44-
return fromJwtVerifiableCredential(jwtVerifiableCredential, null);
32+
return new JwtVerifiablePresentation(jwtPayload, payloadVerifiablePresentation, signedJWT, compactSerialization);
4533
}
4634
}

src/main/java/com/danubetech/verifiablecredentials/jwt/ToJwtConverter.java

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.danubetech.verifiablecredentials.CredentialSubject;
44
import com.danubetech.verifiablecredentials.VerifiableCredential;
5+
import com.danubetech.verifiablecredentials.VerifiablePresentation;
56
import com.danubetech.verifiablecredentials.jsonld.VerifiableCredentialKeywords;
67
import com.fasterxml.jackson.core.JsonParseException;
78
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -73,8 +74,8 @@ public static JwtVerifiableCredential toJwtVerifiableCredential(VerifiableCreden
7374
jwtPayloadBuilder.audience(aud);
7475
}
7576

76-
Map<String, Object> vcClaimValue = new LinkedHashMap<>(payloadVerifiableCredential.getJsonObject());
77-
jwtPayloadBuilder.claim(JwtKeywords.JWT_CLAIM_VC, vcClaimValue);
77+
Map<String, Object> vcContent = new LinkedHashMap<>(payloadVerifiableCredential.getJsonObject());
78+
jwtPayloadBuilder.claim(JwtKeywords.JWT_CLAIM_VC, vcContent);
7879

7980
JWTClaimsSet jwtPayload = jwtPayloadBuilder.build();
8081

@@ -86,4 +87,48 @@ public static JwtVerifiableCredential toJwtVerifiableCredential(VerifiableCreden
8687
return toJwtVerifiableCredential(verifiableCredential, null);
8788
}
8889

90+
/*
91+
* from JSON-LD to JWT VP
92+
*/
93+
94+
public static JwtVerifiablePresentation toJwtVerifiablePresentation(VerifiablePresentation verifiablePresentation, String aud) {
95+
96+
JWTClaimsSet.Builder jwtPayloadBuilder = new JWTClaimsSet.Builder();
97+
98+
VerifiablePresentation payloadVerifiablePresentation = VerifiablePresentation.builder()
99+
.defaultContexts(false)
100+
.defaultTypes(false)
101+
.build();
102+
103+
JsonLDUtils.jsonLdAddAll(payloadVerifiablePresentation, verifiablePresentation.getJsonObject());
104+
105+
URI id = verifiablePresentation.getId();
106+
if (id != null) {
107+
jwtPayloadBuilder.jwtID(id.toString());
108+
JsonLDUtils.jsonLdRemove(payloadVerifiablePresentation, JsonLDKeywords.JSONLD_TERM_ID);
109+
}
110+
111+
URI holder = verifiablePresentation.getHolder();
112+
if (holder != null) {
113+
jwtPayloadBuilder.issuer(holder.toString());
114+
jwtPayloadBuilder.subject(holder.toString());
115+
JsonLDUtils.jsonLdRemove(payloadVerifiablePresentation, VerifiableCredentialKeywords.JSONLD_TERM_HOLDER);
116+
}
117+
118+
if (aud != null) {
119+
jwtPayloadBuilder.audience(aud);
120+
}
121+
122+
Map<String, Object> vpContent = new LinkedHashMap<>(payloadVerifiablePresentation.getJsonObject());
123+
jwtPayloadBuilder.claim(JwtKeywords.JWT_CLAIM_VP, vpContent);
124+
125+
JWTClaimsSet jwtPayload = jwtPayloadBuilder.build();
126+
127+
return new JwtVerifiablePresentation(jwtPayload, payloadVerifiablePresentation, null, null);
128+
}
129+
130+
public static JwtVerifiablePresentation toJwtVerifiablePresentation(VerifiablePresentation verifiablePresentation) {
131+
132+
return toJwtVerifiablePresentation(verifiablePresentation, null);
133+
}
89134
}

src/main/java/com/danubetech/verifiablecredentials/w3ctestsuite/Generator.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import com.danubetech.verifiablecredentials.VerifiableCredential;
44
import com.danubetech.verifiablecredentials.VerifiablePresentation;
55
import com.danubetech.verifiablecredentials.jwt.FromJwtConverter;
6+
import com.danubetech.verifiablecredentials.jwt.JwtJwtVerifiablePresentation;
67
import com.danubetech.verifiablecredentials.jwt.JwtVerifiableCredential;
7-
import com.danubetech.verifiablecredentials.jwt.JwtVerifiablePresentation;
88
import com.danubetech.verifiablecredentials.jwt.ToJwtConverter;
99
import com.danubetech.verifiablecredentials.validation.Validation;
1010
import com.nimbusds.jose.JOSEException;
@@ -17,7 +17,6 @@
1717
import java.io.BufferedReader;
1818
import java.io.File;
1919
import java.io.FileReader;
20-
import java.security.GeneralSecurityException;
2120
import java.text.ParseException;
2221
import java.util.Arrays;
2322
import java.util.List;
@@ -92,8 +91,8 @@ public static void main(String[] args) throws Exception {
9291

9392
jwtVerifiableCredential.sign_RSA_RS256(rsaKey);
9493

95-
JwtVerifiablePresentation jwtVerifiablePresentation = JwtVerifiablePresentation.fromJwtVerifiableCredential(jwtVerifiableCredential, argAud);
96-
output = jwtVerifiablePresentation.sign_RSA_RS256(rsaKey);
94+
JwtJwtVerifiablePresentation jwtJwtVerifiablePresentation = JwtJwtVerifiablePresentation.fromJwtVerifiableCredential(jwtVerifiableCredential, argAud);
95+
output = jwtJwtVerifiablePresentation.sign_RSA_RS256(rsaKey);
9796
} else {
9897

9998
if (argNoJws) {

0 commit comments

Comments
 (0)