49
49
import java .security .spec .X509EncodedKeySpec ;
50
50
import java .time .Instant ;
51
51
import java .util .*;
52
+
52
53
import com .uid2 .shared .store .reader .RotatingS3KeyProvider ;
53
54
import com .uid2 .shared .model .S3Key ;
54
55
@@ -78,7 +79,6 @@ public class CoreVerticle extends AbstractVerticle {
78
79
private final ISaltMetadataProvider saltMetadataProvider ;
79
80
private final IPartnerMetadataProvider partnerMetadataProvider ;
80
81
private final OperatorJWTTokenProvider operatorJWTTokenProvider ;
81
- private final JwtService jwtService ;
82
82
private final RotatingS3KeyProvider s3KeyProvider ;
83
83
84
84
public CoreVerticle (ICloudStorage cloudStorage ,
@@ -96,7 +96,6 @@ public CoreVerticle(ICloudStorage cloudStorage,
96
96
97
97
this .attestationService = attestationService ;
98
98
this .attestationTokenService = attestationTokenService ;
99
- this .jwtService = jwtService ;
100
99
this .enclaveIdentifierProvider = enclaveIdentifierProvider ;
101
100
this .enclaveIdentifierProvider .addListener (this .attestationService );
102
101
this .s3KeyProvider = s3KeyProvider ;
@@ -108,7 +107,7 @@ public CoreVerticle(ICloudStorage cloudStorage,
108
107
enforceJwt = false ;
109
108
}
110
109
111
- this .attestationMiddleware = new AttestationMiddleware (this .attestationTokenService , this . jwtService , jwtAudience , jwtIssuer , enforceJwt );
110
+ this .attestationMiddleware = new AttestationMiddleware (this .attestationTokenService , jwtService , jwtAudience , jwtIssuer , enforceJwt );
112
111
113
112
this .auth = new AuthMiddleware (authProvider );
114
113
@@ -225,15 +224,15 @@ private void handleAttestAsync(RoutingContext rc) {
225
224
try {
226
225
json = rc .body ().asJsonObject ();
227
226
} catch (DecodeException e ) {
228
- setAttestationFailureReason (rc , AttestationFailureReason . REQUEST_BODY_IS_NOT_VALID_JSON );
227
+ setAttestationFailureReason (rc , AttestationFailure . BAD_PAYLOAD , Collections . singletonMap ( "cause" , AttestationFailure . BAD_PAYLOAD . explain ()) );
229
228
Error ("request body is not a valid json" , 400 , rc , null );
230
229
return ;
231
230
}
232
231
233
232
String request = json == null ? null : json .getString ("attestation_request" );
234
233
235
234
if (request == null || request .isEmpty ()) {
236
- setAttestationFailureReason (rc , AttestationFailureReason . NO_ATTESTATION_REQUEST_ATTACHED );
235
+ setAttestationFailureReason (rc , AttestationFailure . BAD_PAYLOAD , Collections . singletonMap ( "cause" , AttestationFailure . BAD_PAYLOAD . explain ()) );
237
236
Error ("no attestation_request attached" , 400 , rc , null );
238
237
return ;
239
238
}
@@ -243,22 +242,44 @@ private void handleAttestAsync(RoutingContext rc) {
243
242
try {
244
243
attestationService .attest (protocol , request , clientPublicKey , ar -> {
245
244
if (!ar .succeeded ()) {
246
- setAttestationFailureReason (rc , AttestationFailureReason .ATTESTATION_FAILURE , Collections .singletonMap ("cause" , ar .cause ().getMessage ()));
245
+ if (ar .cause () instanceof AttestationClientException ace && ace .IsClientError ()) {
246
+ setAttestationFailureReason (rc , ace .getAttestationFailure (), Collections .singletonMap ("reason" , ace .getAttestationFailure ().explain ()));
247
+ logger .warn ("attestation failure: " , ace );
248
+ Error ("attestation failure" , 400 , rc , ace .getAttestationFailure ().explain ());
249
+ return ;
250
+ }
251
+
252
+ // 500 is only for unknown errors in the attestation processing
253
+ setAttestationFailureReason (rc , AttestationFailure .INTERNAL_ERROR , Collections .singletonMap ("cause" , ar .cause ().getMessage ()));
247
254
logger .warn ("attestation failure: " , ar .cause ());
248
255
Error ("attestation failure" , 500 , rc , null );
249
256
return ;
250
257
}
251
258
252
259
final AttestationResult attestationResult = ar .result ();
253
260
if (!attestationResult .isSuccess ()) {
254
- setAttestationFailureReason (rc , AttestationFailureReason .ATTESTATION_FAILURE , Collections .singletonMap ("reason" , attestationResult .getReason ()));
255
- Error (attestationResult .getReason (), 401 , rc , null );
256
- return ;
261
+ AttestationFailure failure = attestationResult .getFailure ();
262
+ switch (failure ) {
263
+ case AttestationFailure .BAD_FORMAT :
264
+ case AttestationFailure .INVALID_PROTOCOL :
265
+ case AttestationFailure .BAD_CERTIFICATE :
266
+ case AttestationFailure .BAD_PAYLOAD :
267
+ case AttestationFailure .UNKNOWN_ATTESTATION_URL :
268
+ case AttestationFailure .FORBIDDEN_ENCLAVE :
269
+ setAttestationFailureReason (rc , failure , Collections .singletonMap ("reason" , attestationResult .getReason ()));
270
+ Error (attestationResult .getReason (), 403 , rc , failure .explain ());
271
+ return ;
272
+ case AttestationFailure .UNKNOWN :
273
+ case AttestationFailure .INTERNAL_ERROR :
274
+ setAttestationFailureReason (rc , failure , Collections .singletonMap ("reason" , attestationResult .getReason ()));
275
+ Error (attestationResult .getReason (), 500 , rc , failure .explain ());
276
+ return ;
277
+ }
257
278
}
258
279
259
280
if (json .containsKey ("operator_type" ) && !operator .getOperatorType ().name ().equalsIgnoreCase (json .getString ("operator_type" ))) {
260
- setAttestationFailureReason (rc , AttestationFailureReason . ATTESTATION_FAILURE );
261
- Error ("attestation failure; invalid operator type" , 400 , rc , null );
281
+ setAttestationFailureReason (rc , AttestationFailure . INVALID_TYPE , Collections . singletonMap ( "reason" , AttestationFailure . INVALID_TYPE . explain ()) );
282
+ Error ("attestation failure; invalid operator type" , 403 , rc , null );
262
283
return ;
263
284
}
264
285
@@ -294,16 +315,16 @@ private void handleAttestAsync(RoutingContext rc) {
294
315
}
295
316
}
296
317
} catch (Exception e ) {
297
- Error ("attestation failure" , 500 , rc , null );
318
+ Error ("attestation failure" , 500 , rc , AttestationFailure . INTERNAL_ERROR . explain () );
298
319
return ;
299
320
}
300
321
301
322
logger .info ("attestation successful for SiteId: {}, Operator name: {}, protocol: {}" , operator .getSiteId (), operator .getName (), protocol );
302
323
Success (rc , responseObj );
303
324
});
304
325
} catch (AttestationService .NotFound e ) {
305
- setAttestationFailureReason (rc , AttestationFailureReason .INVALID_PROTOCOL );
306
- Error ("protocol not found" , 500 , rc , null );
326
+ setAttestationFailureReason (rc , AttestationFailure .INVALID_PROTOCOL , Collections . singletonMap ( "cause" , AttestationFailure . INVALID_PROTOCOL . explain ()) );
327
+ Error ("protocol not found" , 403 , rc , null );
307
328
}
308
329
}
309
330
@@ -316,7 +337,7 @@ private static String encodeAttestationToken(RoutingContext rc, AttestationResul
316
337
cipher .init (Cipher .ENCRYPT_MODE , publicKey );
317
338
return Base64 .getEncoder ().encodeToString (cipher .doFinal (encodedAttestationToken .getBytes (StandardCharsets .UTF_8 )));
318
339
} catch (Exception e ) {
319
- setAttestationFailureReason (rc , AttestationFailureReason . RESPONSE_ENCRYPTION_EXCEPTION , Collections .singletonMap ("exception" , e .getMessage ()));
340
+ setAttestationFailureReason (rc , AttestationFailure . RESPONSE_ENCRYPTION_ERROR , Collections .singletonMap ("exception" , e .getMessage ()));
320
341
logger .warn ("attestation failure: exception while encrypting response" , e );
321
342
throw e ;
322
343
}
@@ -333,10 +354,9 @@ private Map.Entry<String, String> getJWTTokens(RoutingContext rc, IAuthorizable
333
354
String optOutJwtToken = this .operatorJWTTokenProvider .getOptOutJWTToken (operator .getKeyHash (), operator .getName (), operator .getRoles (), operator .getSiteId (), enclaveId , operator .getProtocol (), clientVersion , expiresAt );
334
355
String coreJwtToken = this .operatorJWTTokenProvider .getCoreJWTToken (operator .getKeyHash (), operator .getName (), operator .getRoles (), operator .getSiteId (), enclaveId , operator .getProtocol (), clientVersion , expiresAt );
335
356
336
- Map .Entry <String , String > tokens = new AbstractMap .SimpleEntry <>(optOutJwtToken , coreJwtToken );
337
- return tokens ;
357
+ return new AbstractMap .SimpleEntry <>(optOutJwtToken , coreJwtToken );
338
358
} catch (JWTTokenProvider .JwtSigningException e ) {
339
- setAttestationFailureReason (rc , AttestationFailureReason .INTERNAL_ERROR , Collections .singletonMap ("exception" , e .getMessage ()));
359
+ setAttestationFailureReason (rc , AttestationFailure .INTERNAL_ERROR , Collections .singletonMap ("exception" , e .getMessage ()));
340
360
logger .error ("OptOut JWT token generation failed" , e );
341
361
throw e ;
342
362
}
@@ -346,11 +366,11 @@ private Map.Entry<String, String> getJWTTokens(RoutingContext rc, IAuthorizable
346
366
return null ;
347
367
}
348
368
349
- private static void setAttestationFailureReason (RoutingContext context , AttestationFailureReason reason ) {
369
+ private static void setAttestationFailureReason (RoutingContext context , AttestationFailure reason ) {
350
370
setAttestationFailureReason (context , reason , null );
351
371
}
352
372
353
- private static void setAttestationFailureReason (RoutingContext context , AttestationFailureReason reason , Map <String , Object > data ) {
373
+ private static void setAttestationFailureReason (RoutingContext context , AttestationFailure reason , Map <String , Object > data ) {
354
374
context .put (com .uid2 .core .Const .RoutingContextData .ATTESTATION_FAILURE_REASON_PROP , reason );
355
375
context .put (com .uid2 .core .Const .RoutingContextData .ATTESTATION_FAILURE_DATA_PROP , data );
356
376
}
@@ -523,14 +543,13 @@ JsonObject make(String name, String failReason) {
523
543
}
524
544
525
545
Object enclavesObj = main .getValue ("enclaves" );
526
- if (!(enclavesObj instanceof JsonArray )) {
546
+ if (!(enclavesObj instanceof JsonArray enclaves )) {
527
547
logger .info ("enclave register has been called without .enclaves key" );
528
548
Error ("error" , 400 , rc , ".enclaves needs to be an array" );
529
549
return ;
530
550
}
531
551
532
552
JsonArray res = new JsonArray ();
533
- JsonArray enclaves = (JsonArray ) enclavesObj ;
534
553
for (int i = 0 ; i < enclaves .size (); i ++) {
535
554
Result result = new Result ();
536
555
JsonObject item = enclaves .getJsonObject (i );
@@ -573,7 +592,11 @@ private static String getClientVersionFromHeader(RoutingContext rc, IAuthorizabl
573
592
String clientVersion = "unknown client version" ;
574
593
if (rc .request ().headers ().contains (Const .Http .AppVersionHeader )) {
575
594
var client = VertxUtils .parseClientAppVersion (rc .request ().headers ().get (Const .Http .AppVersionHeader ));
576
- clientVersion = profile .getContact () + "|" + client .getKey () + "|" + client .getValue ();
595
+ if (client != null ) {
596
+ clientVersion = profile .getContact () + "|" + client .getKey () + "|" + client .getValue ();
597
+ } else {
598
+ clientVersion = profile .getContact () + "|null client key" ;
599
+ }
577
600
}
578
601
return clientVersion ;
579
602
}
0 commit comments