Skip to content

Commit b2452f5

Browse files
[feature] OID4VCI / Credential Response Encryption
1 parent fa54dba commit b2452f5

File tree

7 files changed

+94
-8
lines changed

7 files changed

+94
-8
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<properties>
1313
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1414

15-
<authlete.java.common.version>3.83</authlete.java.common.version>
15+
<authlete.java.common.version>3.86</authlete.java.common.version>
1616
<authlete.java.jaxrs.version>2.66</authlete.java.jaxrs.version>
1717
<javax.servlet-api.version>3.0.1</javax.servlet-api.version>
1818
<jersey.version>2.30.1</jersey.version>

src/main/java/com/authlete/jaxrs/server/api/vci/BatchCredentialEndpoint.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ private Response issue(
137137
case CALLER_ERROR:
138138
return ResponseUtil.internalServerErrorJson(content, headers);
139139

140+
case BAD_REQUEST:
141+
return ResponseUtil.badRequestJson(content, headers);
142+
140143
case UNAUTHORIZED:
141144
return ResponseUtil.unauthorized(accessToken, content, headers);
142145

@@ -146,6 +149,9 @@ private Response issue(
146149
case OK:
147150
return ResponseUtil.okJson(content, headers);
148151

152+
case OK_JWT:
153+
return ResponseUtil.okJwt(content, headers);
154+
149155
case INTERNAL_SERVER_ERROR:
150156
default:
151157
return ResponseUtil.internalServerErrorJson(content, headers);

src/main/java/com/authlete/jaxrs/server/api/vci/CredentialEndpoint.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ private Response issue(
139139
case CALLER_ERROR:
140140
return ResponseUtil.internalServerErrorJson(content, headers);
141141

142+
case BAD_REQUEST:
143+
return ResponseUtil.badRequestJson(content, headers);
144+
142145
case UNAUTHORIZED:
143146
return ResponseUtil.unauthorized(accessToken, content, headers);
144147

@@ -148,9 +151,15 @@ private Response issue(
148151
case OK:
149152
return ResponseUtil.okJson(content, headers);
150153

154+
case OK_JWT:
155+
return ResponseUtil.okJwt(content, headers);
156+
151157
case ACCEPTED:
152158
return ResponseUtil.acceptedJson(content, headers);
153159

160+
case ACCEPTED_JWT:
161+
return ResponseUtil.acceptedJwt(content, headers);
162+
154163
case INTERNAL_SERVER_ERROR:
155164
default:
156165
return ResponseUtil.internalServerErrorJson(content, headers);

src/main/java/com/authlete/jaxrs/server/api/vci/CredentialOfferPageModel.java

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.io.IOException;
2222
import java.net.URLEncoder;
2323
import java.util.Base64;
24+
import java.util.List;
2425
import java.util.Map;
2526
import javax.imageio.ImageIO;
2627
import com.authlete.common.dto.CredentialOfferCreateRequest;
@@ -57,12 +58,7 @@ public class CredentialOfferPageModel extends AuthorizationPageModel
5758

5859

5960
private static final String DEFAULT_CREDENTIALS = "[\n" +
60-
" {\n" +
61-
" \"format\": \"vc+sd-jwt\",\n" +
62-
" \"credential_definition\": {\n" +
63-
" \"type\": \"IdentityCredential\"\n" +
64-
" }\n" +
65-
" }\n" +
61+
" \"IdentityCredential\"\n" +
6662
"]";
6763

6864

@@ -165,11 +161,53 @@ public CredentialOfferCreateRequest toRequest(final User user)
165161
.setUserPinRequired(this.userPinRequired)
166162
.setUserPinLength(this.userPinLength)
167163
.setDuration(this.duration)
168-
.setCredentials(this.credentials)
164+
.setCredentials(parseAsStringArray("credentials", this.credentials))
169165
.setSubject(user.getSubject());
170166
}
171167

172168

169+
private String[] parseAsStringArray(String name, String json)
170+
{
171+
List<?> list = parseAsList(name, json);
172+
173+
if (list == null)
174+
{
175+
return null;
176+
}
177+
178+
int size = list.size();
179+
180+
for (int i = 0; i < size; i++)
181+
{
182+
Object element = list.get(i);
183+
184+
if (!(element instanceof String))
185+
{
186+
throw ExceptionUtil.badRequestException(String.format(
187+
"All the elements in the '%s' array must be a string, but the element at the index %d is not.",
188+
name, i));
189+
}
190+
}
191+
192+
return list.stream().map(element -> (String)element).toArray(String[]::new);
193+
}
194+
195+
196+
private List<?> parseAsList(String name, String json)
197+
{
198+
try
199+
{
200+
// Parse as a JSON array.
201+
return new Gson().fromJson(json, List.class);
202+
}
203+
catch (Exception cause)
204+
{
205+
throw ExceptionUtil.badRequestException(String.format(
206+
"The value of '%s' should be a JSON array.", name));
207+
}
208+
}
209+
210+
173211
public String getCredentials()
174212
{
175213
return credentials;

src/main/java/com/authlete/jaxrs/server/api/vci/DeferredCredentialEndpoint.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,18 @@ private Response issue(
147147
case CALLER_ERROR:
148148
return ResponseUtil.internalServerErrorJson(content, headers);
149149

150+
case BAD_REQUEST:
151+
return ResponseUtil.badRequestJson(content, headers);
152+
150153
case FORBIDDEN:
151154
return ResponseUtil.forbiddenJson(content, headers);
152155

153156
case OK:
154157
return ResponseUtil.okJson(content, headers);
155158

159+
case OK_JWT:
160+
return ResponseUtil.okJwt(content, headers);
161+
156162
case INTERNAL_SERVER_ERROR:
157163
default:
158164
return ResponseUtil.internalServerErrorJson(content, headers);

src/main/java/com/authlete/jaxrs/server/util/ProcessingUtil.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
public class ProcessingUtil
1616
{
1717

18+
@SuppressWarnings("unchecked")
1819
public static <K, V> Map<K, V> flattenMultivaluedMap(final MultivaluedMap<K, V> multimap)
1920
{
2021
return multimap.entrySet().stream()

src/main/java/com/authlete/jaxrs/server/util/ResponseUtil.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ public class ResponseUtil
5252
private static final MediaType MEDIA_TYPE_JSON =
5353
MediaType.APPLICATION_JSON_TYPE.withCharset("UTF-8");
5454

55+
/**
56+
* {@code "application/jwt"}
57+
*/
58+
private static final MediaType MEDIA_TYPE_JWT =
59+
new MediaType("application", "jwt");
60+
61+
5562

5663
/**
5764
* Build a "text/plain" response of "200 OK".
@@ -95,6 +102,12 @@ public static Response okJson(String entity, Map<String, Object> headers)
95102
}
96103

97104

105+
public static Response okJwt(String entity, Map<String, Object> headers)
106+
{
107+
return builderForJwt(Status.OK, entity, headers).build();
108+
}
109+
110+
98111
/**
99112
* Build a "text/html" response of "200 OK".
100113
*
@@ -137,6 +150,12 @@ public static Response acceptedJson(String entity, Map<String, Object> headers)
137150
}
138151

139152

153+
public static Response acceptedJwt(String entity, Map<String, Object> headers)
154+
{
155+
return builderForJwt(Status.ACCEPTED, entity, headers).build();
156+
}
157+
158+
140159
/**
141160
* Build a response of "204 No Content".
142161
*
@@ -455,6 +474,13 @@ private static ResponseBuilder builderForJson(
455474
}
456475

457476

477+
private static ResponseBuilder builderForJwt(
478+
Status status, String entity, Map<String, Object> headers)
479+
{
480+
return builder(status, entity, MEDIA_TYPE_JWT, headers);
481+
}
482+
483+
458484
private static ResponseBuilder builder(
459485
Status status, Object entity, MediaType type, Map<String, Object> headers)
460486
{

0 commit comments

Comments
 (0)