diff --git a/pom.xml b/pom.xml
index 247d0a7..c8042b0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.uid2
uid2-core
- 2.20.0
+ 2.20.1-alpha-50-SNAPSHOT
UTF-8
@@ -24,7 +24,7 @@
com.uid2.core.vertx.CoreVerticle
io.vertx.core.Launcher
- 7.19.0
+ 7.20.0
${project.version}
diff --git a/src/main/java/com/uid2/core/handler/AttestationFailureHandler.java b/src/main/java/com/uid2/core/handler/AttestationFailureHandler.java
index 6d78c20..390f756 100644
--- a/src/main/java/com/uid2/core/handler/AttestationFailureHandler.java
+++ b/src/main/java/com/uid2/core/handler/AttestationFailureHandler.java
@@ -1,10 +1,10 @@
package com.uid2.core.handler;
import com.uid2.core.Const;
-import com.uid2.core.vertx.AttestationFailureReason;
import com.uid2.shared.auth.IAuthorizable;
import com.uid2.shared.auth.OperatorKey;
import com.uid2.shared.middleware.AuthMiddleware;
+import com.uid2.shared.secure.AttestationFailure;
import io.vertx.core.Handler;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.SocketAddress;
@@ -40,14 +40,14 @@ private void logAttestationFailure(RoutingContext context) {
return;
}
- final AttestationFailureReason attestationFailureReason = context.get(Const.RoutingContextData.ATTESTATION_FAILURE_REASON_PROP);
+ final AttestationFailure attestationFailure = context.get(Const.RoutingContextData.ATTESTATION_FAILURE_REASON_PROP);
final String attestationFailureDataJson = getAttestationFailureDataJson(context);
final String originatingIpAddress = getOriginatingIpAddress(context);
LOG.warn("Attestation failed. StatusCode={} Reason={} Data={} OperatorKeyHash={} OperatorKeyName={} SiteId={} Protocol={} OperatorType={} OriginatingIpAddress={}",
context.response().getStatusCode(),
- attestationFailureReason,
+ attestationFailure,
attestationFailureDataJson,
operatorKey.getKeyHash(),
operatorKey.getName(),
diff --git a/src/main/java/com/uid2/core/vertx/AttestationFailureReason.java b/src/main/java/com/uid2/core/vertx/AttestationFailureReason.java
deleted file mode 100644
index a262098..0000000
--- a/src/main/java/com/uid2/core/vertx/AttestationFailureReason.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.uid2.core.vertx;
-
-public enum AttestationFailureReason {
- /**
- * Request body is not valid JSON.
- */
- REQUEST_BODY_IS_NOT_VALID_JSON,
- /**
- * No attestation request in the request body.
- */
- NO_ATTESTATION_REQUEST_ATTACHED,
- /**
- * Exception occurred encrypting the response.
- */
- RESPONSE_ENCRYPTION_EXCEPTION,
- /**
- * Invalid protocol specified.
- */
- INVALID_PROTOCOL,
- /**
- * Attestation was attempted, but failed.
- */
- ATTESTATION_FAILURE,
-
- /**
- * Internal server error
- */
- INTERNAL_ERROR,
-}
diff --git a/src/main/java/com/uid2/core/vertx/CoreVerticle.java b/src/main/java/com/uid2/core/vertx/CoreVerticle.java
index 1f4d2ba..00eccda 100644
--- a/src/main/java/com/uid2/core/vertx/CoreVerticle.java
+++ b/src/main/java/com/uid2/core/vertx/CoreVerticle.java
@@ -49,6 +49,7 @@
import java.security.spec.X509EncodedKeySpec;
import java.time.Instant;
import java.util.*;
+
import com.uid2.shared.store.reader.RotatingS3KeyProvider;
import com.uid2.shared.model.S3Key;
@@ -78,7 +79,6 @@ public class CoreVerticle extends AbstractVerticle {
private final ISaltMetadataProvider saltMetadataProvider;
private final IPartnerMetadataProvider partnerMetadataProvider;
private final OperatorJWTTokenProvider operatorJWTTokenProvider;
- private final JwtService jwtService;
private final RotatingS3KeyProvider s3KeyProvider;
public CoreVerticle(ICloudStorage cloudStorage,
@@ -96,7 +96,6 @@ public CoreVerticle(ICloudStorage cloudStorage,
this.attestationService = attestationService;
this.attestationTokenService = attestationTokenService;
- this.jwtService = jwtService;
this.enclaveIdentifierProvider = enclaveIdentifierProvider;
this.enclaveIdentifierProvider.addListener(this.attestationService);
this.s3KeyProvider = s3KeyProvider;
@@ -108,7 +107,7 @@ public CoreVerticle(ICloudStorage cloudStorage,
enforceJwt = false;
}
- this.attestationMiddleware = new AttestationMiddleware(this.attestationTokenService, this.jwtService, jwtAudience, jwtIssuer, enforceJwt);
+ this.attestationMiddleware = new AttestationMiddleware(this.attestationTokenService, jwtService, jwtAudience, jwtIssuer, enforceJwt);
this.auth = new AuthMiddleware(authProvider);
@@ -225,7 +224,7 @@ private void handleAttestAsync(RoutingContext rc) {
try {
json = rc.body().asJsonObject();
} catch (DecodeException e) {
- setAttestationFailureReason(rc, AttestationFailureReason.REQUEST_BODY_IS_NOT_VALID_JSON);
+ setAttestationFailureReason(rc, AttestationFailure.BAD_PAYLOAD, Collections.singletonMap("cause", AttestationFailure.BAD_PAYLOAD.explain()));
Error("request body is not a valid json", 400, rc, null);
return;
}
@@ -233,7 +232,7 @@ private void handleAttestAsync(RoutingContext rc) {
String request = json == null ? null : json.getString("attestation_request");
if (request == null || request.isEmpty()) {
- setAttestationFailureReason(rc, AttestationFailureReason.NO_ATTESTATION_REQUEST_ATTACHED);
+ setAttestationFailureReason(rc, AttestationFailure.BAD_PAYLOAD, Collections.singletonMap("cause", AttestationFailure.BAD_PAYLOAD.explain()));
Error("no attestation_request attached", 400, rc, null);
return;
}
@@ -243,7 +242,15 @@ private void handleAttestAsync(RoutingContext rc) {
try {
attestationService.attest(protocol, request, clientPublicKey, ar -> {
if (!ar.succeeded()) {
- setAttestationFailureReason(rc, AttestationFailureReason.ATTESTATION_FAILURE, Collections.singletonMap("cause", ar.cause().getMessage()));
+ if (ar.cause() instanceof AttestationClientException ace && ace.IsClientError()) {
+ setAttestationFailureReason(rc, ace.getAttestationFailure(), Collections.singletonMap("reason", ace.getAttestationFailure().explain()));
+ logger.warn("attestation failure: ", ace);
+ Error("attestation failure", 400, rc, ace.getAttestationFailure().explain());
+ return;
+ }
+
+ // 500 is only for unknown errors in the attestation processing
+ setAttestationFailureReason(rc, AttestationFailure.INTERNAL_ERROR, Collections.singletonMap("cause", ar.cause().getMessage()));
logger.warn("attestation failure: ", ar.cause());
Error("attestation failure", 500, rc, null);
return;
@@ -251,14 +258,28 @@ private void handleAttestAsync(RoutingContext rc) {
final AttestationResult attestationResult = ar.result();
if (!attestationResult.isSuccess()) {
- setAttestationFailureReason(rc, AttestationFailureReason.ATTESTATION_FAILURE, Collections.singletonMap("reason", attestationResult.getReason()));
- Error(attestationResult.getReason(), 401, rc, null);
- return;
+ AttestationFailure failure = attestationResult.getFailure();
+ switch (failure) {
+ case AttestationFailure.BAD_FORMAT:
+ case AttestationFailure.INVALID_PROTOCOL:
+ case AttestationFailure.BAD_CERTIFICATE:
+ case AttestationFailure.BAD_PAYLOAD:
+ case AttestationFailure.UNKNOWN_ATTESTATION_URL:
+ case AttestationFailure.FORBIDDEN_ENCLAVE:
+ setAttestationFailureReason(rc, failure, Collections.singletonMap("reason", attestationResult.getReason()));
+ Error(attestationResult.getReason(), 403, rc, failure.explain());
+ return;
+ case AttestationFailure.UNKNOWN:
+ case AttestationFailure.INTERNAL_ERROR:
+ setAttestationFailureReason(rc, failure, Collections.singletonMap("reason", attestationResult.getReason()));
+ Error(attestationResult.getReason(), 500, rc, failure.explain());
+ return;
+ }
}
if (json.containsKey("operator_type") && !operator.getOperatorType().name().equalsIgnoreCase(json.getString("operator_type"))) {
- setAttestationFailureReason(rc, AttestationFailureReason.ATTESTATION_FAILURE);
- Error("attestation failure; invalid operator type", 400, rc, null);
+ setAttestationFailureReason(rc, AttestationFailure.INVALID_TYPE, Collections.singletonMap("reason", AttestationFailure.INVALID_TYPE.explain()));
+ Error("attestation failure; invalid operator type", 403, rc, null);
return;
}
@@ -294,7 +315,7 @@ private void handleAttestAsync(RoutingContext rc) {
}
}
} catch (Exception e) {
- Error("attestation failure", 500, rc, null);
+ Error("attestation failure", 500, rc, AttestationFailure.INTERNAL_ERROR.explain());
return;
}
@@ -302,8 +323,8 @@ private void handleAttestAsync(RoutingContext rc) {
Success(rc, responseObj);
});
} catch (AttestationService.NotFound e) {
- setAttestationFailureReason(rc, AttestationFailureReason.INVALID_PROTOCOL);
- Error("protocol not found", 500, rc, null);
+ setAttestationFailureReason(rc, AttestationFailure.INVALID_PROTOCOL, Collections.singletonMap("cause", AttestationFailure.INVALID_PROTOCOL.explain()));
+ Error("protocol not found", 403, rc, null);
}
}
@@ -316,7 +337,7 @@ private static String encodeAttestationToken(RoutingContext rc, AttestationResul
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(encodedAttestationToken.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
- setAttestationFailureReason(rc, AttestationFailureReason.RESPONSE_ENCRYPTION_EXCEPTION, Collections.singletonMap("exception", e.getMessage()));
+ setAttestationFailureReason(rc, AttestationFailure.RESPONSE_ENCRYPTION_ERROR, Collections.singletonMap("exception", e.getMessage()));
logger.warn("attestation failure: exception while encrypting response", e);
throw e;
}
@@ -333,10 +354,9 @@ private Map.Entry getJWTTokens(RoutingContext rc, IAuthorizable
String optOutJwtToken = this.operatorJWTTokenProvider.getOptOutJWTToken(operator.getKeyHash(), operator.getName(), operator.getRoles(), operator.getSiteId(), enclaveId, operator.getProtocol(), clientVersion, expiresAt);
String coreJwtToken = this.operatorJWTTokenProvider.getCoreJWTToken(operator.getKeyHash(), operator.getName(), operator.getRoles(), operator.getSiteId(), enclaveId, operator.getProtocol(), clientVersion, expiresAt);
- Map.Entry tokens = new AbstractMap.SimpleEntry<>(optOutJwtToken, coreJwtToken);
- return tokens;
+ return new AbstractMap.SimpleEntry<>(optOutJwtToken, coreJwtToken);
} catch (JWTTokenProvider.JwtSigningException e) {
- setAttestationFailureReason(rc, AttestationFailureReason.INTERNAL_ERROR, Collections.singletonMap("exception", e.getMessage()));
+ setAttestationFailureReason(rc, AttestationFailure.INTERNAL_ERROR, Collections.singletonMap("exception", e.getMessage()));
logger.error("OptOut JWT token generation failed", e);
throw e;
}
@@ -346,11 +366,11 @@ private Map.Entry getJWTTokens(RoutingContext rc, IAuthorizable
return null;
}
- private static void setAttestationFailureReason(RoutingContext context, AttestationFailureReason reason) {
+ private static void setAttestationFailureReason(RoutingContext context, AttestationFailure reason) {
setAttestationFailureReason(context, reason, null);
}
- private static void setAttestationFailureReason(RoutingContext context, AttestationFailureReason reason, Map data) {
+ private static void setAttestationFailureReason(RoutingContext context, AttestationFailure reason, Map data) {
context.put(com.uid2.core.Const.RoutingContextData.ATTESTATION_FAILURE_REASON_PROP, reason);
context.put(com.uid2.core.Const.RoutingContextData.ATTESTATION_FAILURE_DATA_PROP, data);
}
@@ -523,14 +543,13 @@ JsonObject make(String name, String failReason) {
}
Object enclavesObj = main.getValue("enclaves");
- if (!(enclavesObj instanceof JsonArray)) {
+ if (!(enclavesObj instanceof JsonArray enclaves)) {
logger.info("enclave register has been called without .enclaves key");
Error("error", 400, rc, ".enclaves needs to be an array");
return;
}
JsonArray res = new JsonArray();
- JsonArray enclaves = (JsonArray) enclavesObj;
for (int i = 0; i < enclaves.size(); i++) {
Result result = new Result();
JsonObject item = enclaves.getJsonObject(i);
@@ -573,7 +592,11 @@ private static String getClientVersionFromHeader(RoutingContext rc, IAuthorizabl
String clientVersion = "unknown client version";
if (rc.request().headers().contains(Const.Http.AppVersionHeader)) {
var client = VertxUtils.parseClientAppVersion(rc.request().headers().get(Const.Http.AppVersionHeader));
- clientVersion = profile.getContact() + "|" + client.getKey() + "|" + client.getValue();
+ if (client != null) {
+ clientVersion = profile.getContact() + "|" + client.getKey() + "|" + client.getValue();
+ } else {
+ clientVersion = profile.getContact() + "|null client key";
+ }
}
return clientVersion;
}
diff --git a/src/test/java/com/uid2/core/vertx/TestCoreVerticle.java b/src/test/java/com/uid2/core/vertx/TestCoreVerticle.java
index 6e7076d..cc1450b 100644
--- a/src/test/java/com/uid2/core/vertx/TestCoreVerticle.java
+++ b/src/test/java/com/uid2/core/vertx/TestCoreVerticle.java
@@ -32,6 +32,7 @@
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -102,10 +103,10 @@ private void fakeAuth(Role... roles) {
}
private void fakeAuth(String attestationProtocol, String operatorType, Role... roles) {
- if(operatorType.isEmpty()) {
+ if (operatorType.isEmpty()) {
operatorType = "PRIVATE";
}
- OperatorKey operatorKey = new OperatorKey("test-key-hash", "test-key-salt", "test-name", "test-contact", attestationProtocol, 0, false, 88, new HashSet<>(Arrays.asList(roles)), OperatorType.valueOf(operatorType.toUpperCase()), "test-key-id");
+ OperatorKey operatorKey = new OperatorKey("test-key-hash", "test-key-salt", "test-name", "test-contact", attestationProtocol, 0, false, 88, new HashSet<>(Arrays.asList(roles)), OperatorType.valueOf(operatorType.toUpperCase()), "test-key-id");
when(authProvider.get(any())).thenReturn(operatorKey);
}
@@ -156,7 +157,7 @@ private void onHandleAttestationRequest(Callable> f) {
private static String makeAttestationRequestJson(String attestationRequest, String publicKey, String operatorType) {
JsonObject json = new JsonObject();
- if(!operatorType.isEmpty()) {
+ if (!operatorType.isEmpty()) {
json.put("operator_type", operatorType);
}
if (attestationRequest != null) {
@@ -220,7 +221,7 @@ void attestUnknownAttestationProtocol(Vertx vertx, VertxTestContext testContext)
post(vertx, "attest", makeAttestationRequestJson("xxx", "yyy"), ar -> {
assertTrue(ar.succeeded());
HttpResponse response = ar.result();
- assertEquals(500, response.statusCode());
+ assertEquals(403, response.statusCode());
testContext.completeNow();
});
}
@@ -240,18 +241,43 @@ void attestFailureWithAnException(Vertx vertx, VertxTestContext testContext) {
});
}
- @Test
- void attestFailureWithResult(Vertx vertx, VertxTestContext testContext) {
+ @ParameterizedTest
+ @EnumSource(value = AttestationFailure.class, names = {"UNKNOWN_ATTESTATION_URL", "FORBIDDEN_ENCLAVE", "BAD_FORMAT", "INVALID_PROTOCOL", "BAD_CERTIFICATE", "BAD_PAYLOAD"})
+ void attestFailureWithResultClientError(AttestationFailure failure, Vertx vertx, VertxTestContext testContext) {
fakeAuth(Role.OPERATOR);
addAttestationProvider(attestationProtocol);
onHandleAttestationRequest(() -> {
- return Future.succeededFuture(new AttestationResult(AttestationFailure.BAD_PAYLOAD));
+ return Future.succeededFuture(new AttestationResult(failure));
});
post(vertx, "attest", makeAttestationRequestJson("xxx", "yyy"), ar -> {
- assertTrue(ar.succeeded());
- HttpResponse response = ar.result();
- assertEquals(401, response.statusCode());
- testContext.completeNow();
+ try {
+ assertTrue(ar.succeeded());
+ HttpResponse response = ar.result();
+ assertEquals(403, response.statusCode());
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
+ });
+ }
+
+ @ParameterizedTest
+ @EnumSource(value = AttestationFailure.class, names = {"UNKNOWN", "INTERNAL_ERROR"})
+ void attestFailureWithResultServerError(AttestationFailure failure, Vertx vertx, VertxTestContext testContext) {
+ fakeAuth(Role.OPERATOR);
+ addAttestationProvider(attestationProtocol);
+ onHandleAttestationRequest(() -> {
+ return Future.succeededFuture(new AttestationResult(failure));
+ });
+ post(vertx, "attest", makeAttestationRequestJson("xxx", "yyy"), ar -> {
+ try {
+ assertTrue(ar.succeeded());
+ HttpResponse response = ar.result();
+ assertEquals(500, response.statusCode());
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
});
}
@@ -267,15 +293,19 @@ void attestSuccessNoEncryption(String operatorType, Vertx vertx, VertxTestContex
EncryptedAttestationToken encryptedAttestationToken = new EncryptedAttestationToken("test-attestation-token", Instant.ofEpochMilli(111));
when(attestationTokenService.createToken(any())).thenReturn(encryptedAttestationToken);
post(vertx, "attest", makeAttestationRequestJson("xxx", "yyy"), ar -> {
- assertTrue(ar.succeeded());
- HttpResponse response = ar.result();
- assertEquals(200, response.statusCode());
- JsonObject json = response.bodyAsJsonObject();
- String attestationToken = json.getJsonObject("body").getString("attestation_token");
- String expiresAt = json.getJsonObject("body").getString("expiresAt");
- assertEquals("test-attestation-token", attestationToken);
- assertEquals("1970-01-01T00:00:00.111Z", expiresAt);
- testContext.completeNow();
+ try {
+ assertTrue(ar.succeeded());
+ HttpResponse response = ar.result();
+ assertEquals(200, response.statusCode());
+ JsonObject json = response.bodyAsJsonObject();
+ String attestationToken = json.getJsonObject("body").getString("attestation_token");
+ String expiresAt = json.getJsonObject("body").getString("expiresAt");
+ assertEquals("test-attestation-token", attestationToken);
+ assertEquals("1970-01-01T00:00:00.111Z", expiresAt);
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
});
}
@@ -291,12 +321,16 @@ void attestOperatorTypeMismatchNoEncryption(String operatorType, Vertx vertx, Ve
EncryptedAttestationToken encryptedAttestationToken = new EncryptedAttestationToken("test-attestation-token", Instant.ofEpochMilli(111));
when(attestationTokenService.createToken(any())).thenReturn(encryptedAttestationToken);
post(vertx, "attest", makeAttestationRequestJson("xxx", "yyy", operatorType.equalsIgnoreCase("public") ? "private" : "public"), ar -> {
- assertTrue(ar.succeeded());
- HttpResponse response = ar.result();
- assertEquals(400, response.statusCode());
- JsonObject json = response.bodyAsJsonObject();
- assertEquals("attestation failure; invalid operator type", json.getString("status"));
- testContext.completeNow();
+ try {
+ assertTrue(ar.succeeded());
+ HttpResponse response = ar.result();
+ assertEquals(403, response.statusCode());
+ JsonObject json = response.bodyAsJsonObject();
+ assertEquals("attestation failure; invalid operator type", json.getString("status"));
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
});
}
@@ -316,24 +350,28 @@ void attestSuccessWithEncryption(String operatorType, Vertx vertx, VertxTestCont
EncryptedAttestationToken encryptedAttestationToken = new EncryptedAttestationToken("test-attestation-token", Instant.ofEpochMilli(111));
when(attestationTokenService.createToken(any())).thenReturn(encryptedAttestationToken);
post(vertx, "attest", makeAttestationRequestJson("xxx", "yyy", operatorType), ar -> {
- assertTrue(ar.succeeded());
- HttpResponse response = ar.result();
- assertEquals(200, response.statusCode());
- JsonObject json = response.bodyAsJsonObject();
- String attestationToken = json.getJsonObject("body").getString("attestation_token");
- assertNotEquals("", attestationToken);
- String expiresAt = json.getJsonObject("body").getString("expiresAt");
- assertEquals("1970-01-01T00:00:00.111Z", expiresAt);
- String[] decryptedAttestationToken = {""};
- assertDoesNotThrow(() -> {
- Cipher cipher = Cipher.getInstance(Const.Name.AsymetricEncryptionCipherClass);
- cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
- decryptedAttestationToken[0] = new String(cipher.doFinal(Base64.getDecoder().decode(attestationToken)));
- });
-
- assertEquals("test-attestation-token", decryptedAttestationToken[0]);
+ try {
+ assertTrue(ar.succeeded());
+ HttpResponse response = ar.result();
+ assertEquals(200, response.statusCode());
+ JsonObject json = response.bodyAsJsonObject();
+ String attestationToken = json.getJsonObject("body").getString("attestation_token");
+ assertNotEquals("", attestationToken);
+ String expiresAt = json.getJsonObject("body").getString("expiresAt");
+ assertEquals("1970-01-01T00:00:00.111Z", expiresAt);
+ String[] decryptedAttestationToken = {""};
+ assertDoesNotThrow(() -> {
+ Cipher cipher = Cipher.getInstance(Const.Name.AsymetricEncryptionCipherClass);
+ cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
+ decryptedAttestationToken[0] = new String(cipher.doFinal(Base64.getDecoder().decode(attestationToken)));
+ });
- testContext.completeNow();
+ assertEquals("test-attestation-token", decryptedAttestationToken[0]);
+
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
});
}
@@ -354,12 +392,16 @@ void attestOperatorTypeMismatchWithEncryption(String operatorType, Vertx vertx,
EncryptedAttestationToken encryptedAttestationToken = new EncryptedAttestationToken("test-attestation-token", Instant.ofEpochMilli(111));
when(attestationTokenService.createToken(any())).thenReturn(encryptedAttestationToken);
post(vertx, "attest", makeAttestationRequestJson("xxx", "yyy", operatorType.equalsIgnoreCase("public") ? "private" : "public"), ar -> {
- assertTrue(ar.succeeded());
- HttpResponse response = ar.result();
- assertEquals(400, response.statusCode());
- JsonObject json = response.bodyAsJsonObject();
- assertEquals("attestation failure; invalid operator type", json.getString("status"));
- testContext.completeNow();
+ try {
+ assertTrue(ar.succeeded());
+ HttpResponse response = ar.result();
+ assertEquals(403, response.statusCode());
+ JsonObject json = response.bodyAsJsonObject();
+ assertEquals("attestation failure; invalid operator type", json.getString("status"));
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
});
}
@@ -378,25 +420,30 @@ void attestSuccessWithEncryptionNoPublicKeyOnRequest(Vertx vertx, VertxTestConte
EncryptedAttestationToken encryptedAttestationToken = new EncryptedAttestationToken("test-attestation-token", Instant.ofEpochMilli(111));
when(attestationTokenService.createToken(any())).thenReturn(encryptedAttestationToken);
post(vertx, "attest", makeAttestationRequestJson("xxx", null), ar -> {
- assertTrue(ar.succeeded());
- HttpResponse response = ar.result();
- assertEquals(200, response.statusCode());
- JsonObject json = response.bodyAsJsonObject();
- String attestationToken = json.getJsonObject("body").getString("attestation_token");
- assertNotEquals("", attestationToken);
- String expiresAt = json.getJsonObject("body").getString("expiresAt");
- assertEquals("1970-01-01T00:00:00.111Z", expiresAt);
-
- String[] decryptedAttestationToken = {""};
- assertDoesNotThrow(() -> {
- Cipher cipher = Cipher.getInstance(Const.Name.AsymetricEncryptionCipherClass);
- cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
- decryptedAttestationToken[0] = new String(cipher.doFinal(Base64.getDecoder().decode(attestationToken)));
- });
-
- assertEquals("test-attestation-token", decryptedAttestationToken[0]);
+ try {
+ assertTrue(ar.succeeded());
- testContext.completeNow();
+ HttpResponse response = ar.result();
+ assertEquals(200, response.statusCode());
+ JsonObject json = response.bodyAsJsonObject();
+ String attestationToken = json.getJsonObject("body").getString("attestation_token");
+ assertNotEquals("", attestationToken);
+ String expiresAt = json.getJsonObject("body").getString("expiresAt");
+ assertEquals("1970-01-01T00:00:00.111Z", expiresAt);
+
+ String[] decryptedAttestationToken = {""};
+ assertDoesNotThrow(() -> {
+ Cipher cipher = Cipher.getInstance(Const.Name.AsymetricEncryptionCipherClass);
+ cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
+ decryptedAttestationToken[0] = new String(cipher.doFinal(Base64.getDecoder().decode(attestationToken)));
+ });
+
+ assertEquals("test-attestation-token", decryptedAttestationToken[0]);
+
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
});
}
@@ -417,22 +464,26 @@ void attestOptOutJWTCalledUnknownClient(Vertx vertx, VertxTestContext testContex
when(operatorJWTTokenProvider.getOptOutJWTToken("test-key-hash", "test-name", Set.of(Role.OPERATOR, Role.OPTOUT), 88, "test-enclaveId", attestationProtocol, "unknown client version", Instant.ofEpochMilli(111))).thenReturn("dummy_token_optout");
when(operatorJWTTokenProvider.getCoreJWTToken("test-key-hash", "test-name", Set.of(Role.OPERATOR, Role.OPTOUT), 88, "test-enclaveId", attestationProtocol, "unknown client version", Instant.ofEpochMilli(111))).thenReturn("dummy_token_core");
post(vertx, "attest", makeAttestationRequestJson("xxx", null), ar -> {
- assertTrue(ar.succeeded());
- HttpResponse response = ar.result();
-
try {
- verify(operatorJWTTokenProvider, times(1)).getCoreJWTToken("test-key-hash", "test-name", Set.of(Role.OPERATOR, Role.OPTOUT), 88, "test-enclaveId", attestationProtocol, "unknown client version", Instant.ofEpochMilli(111));
- verify(operatorJWTTokenProvider, times(1)).getOptOutJWTToken("test-key-hash", "test-name", Set.of(Role.OPERATOR, Role.OPTOUT), 88, "test-enclaveId", attestationProtocol, "unknown client version", Instant.ofEpochMilli(111));
- JsonObject json = response.bodyAsJsonObject();
- String jwtOptout = json.getJsonObject("body").getString("attestation_jwt_optout");
- String jwtCore = json.getJsonObject("body").getString("attestation_jwt_core");
- assertEquals("dummy_token_optout", jwtOptout);
- assertEquals("dummy_token_core", jwtCore);
- } catch (Exception e) {
- testContext.failNow(e);
- }
+ assertTrue(ar.succeeded());
+ HttpResponse response = ar.result();
+
+ try {
+ verify(operatorJWTTokenProvider, times(1)).getCoreJWTToken("test-key-hash", "test-name", Set.of(Role.OPERATOR, Role.OPTOUT), 88, "test-enclaveId", attestationProtocol, "unknown client version", Instant.ofEpochMilli(111));
+ verify(operatorJWTTokenProvider, times(1)).getOptOutJWTToken("test-key-hash", "test-name", Set.of(Role.OPERATOR, Role.OPTOUT), 88, "test-enclaveId", attestationProtocol, "unknown client version", Instant.ofEpochMilli(111));
+ JsonObject json = response.bodyAsJsonObject();
+ String jwtOptout = json.getJsonObject("body").getString("attestation_jwt_optout");
+ String jwtCore = json.getJsonObject("body").getString("attestation_jwt_core");
+ assertEquals("dummy_token_optout", jwtOptout);
+ assertEquals("dummy_token_core", jwtCore);
+ } catch (Exception e) {
+ testContext.failNow(e);
+ }
- testContext.completeNow();
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
});
}
@@ -509,10 +560,14 @@ void multipartRequestWrongMethodForMultipart(Vertx vertx, VertxTestContext testC
form.set("secondValue", "value2");
get(vertx, "/sites/refresh", form, (ar) -> {
- HttpResponse response = ar.result();
- assertEquals(400, response.statusCode());
- assertEquals("Content-Type \"multipart/*\" Not Allowed\"", response.bodyAsString());
- testContext.completeNow();
+ try {
+ HttpResponse response = ar.result();
+ assertEquals(400, response.statusCode());
+ assertEquals("Content-Type \"multipart/*\" Not Allowed\"", response.bodyAsString());
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
});
}
@@ -523,30 +578,42 @@ void multipartRequestWrongMethodForEndpoint(Vertx vertx, VertxTestContext testCo
form.set("secondValue", "value2");
post(vertx, "/sites/refresh", form, (ar) -> {
- HttpResponse response = ar.result();
- assertEquals(405, response.statusCode());
- assertEquals("Method Not Allowed", response.statusMessage());
- testContext.completeNow();
+ try {
+ HttpResponse response = ar.result();
+ assertEquals(405, response.statusCode());
+ assertEquals("Method Not Allowed", response.statusMessage());
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
});
}
@Test
void wrongMethodForEndpoint(Vertx vertx, VertxTestContext testContext) {
post(vertx, "/sites/refresh", makeAttestationRequestJson(null, null), ar -> {
- HttpResponse response = ar.result();
- assertEquals(405, response.statusCode());
- assertEquals("Method Not Allowed", response.statusMessage());
- testContext.completeNow();
+ try {
+ HttpResponse response = ar.result();
+ assertEquals(405, response.statusCode());
+ assertEquals("Method Not Allowed", response.statusMessage());
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
});
}
@Test
void wrongMethodForEndpointS3(Vertx vertx, VertxTestContext testContext) {
post(vertx, "/s3encryption_keys/retrieve", makeAttestationRequestJson(null, null), ar -> {
- HttpResponse response = ar.result();
- assertEquals(405, response.statusCode());
- assertEquals("Method Not Allowed", response.statusMessage());
- testContext.completeNow();
+ try {
+ HttpResponse response = ar.result();
+ assertEquals(405, response.statusCode());
+ assertEquals("Method Not Allowed", response.statusMessage());
+ testContext.completeNow();
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
+ }
});
}
@@ -566,26 +633,30 @@ void s3encryptionKeyRetrieveSuccess(Vertx vertx, VertxTestContext testContext) {
when(s3KeyProvider.getKeys(88)).thenReturn(keys);
get(vertx, "s3encryption_keys/retrieve", ar -> {
- if (ar.succeeded()) {
- HttpResponse response = ar.result();
- assertEquals(200, response.statusCode());
+ try {
+ if (ar.succeeded()) {
+ HttpResponse response = ar.result();
+ assertEquals(200, response.statusCode());
- JsonObject json = response.bodyAsJsonObject();
- JsonArray s3KeysArray = json.getJsonArray("s3Keys");
+ JsonObject json = response.bodyAsJsonObject();
+ JsonArray s3KeysArray = json.getJsonArray("s3Keys");
- assertNotNull(s3KeysArray);
- assertEquals(1, s3KeysArray.size());
+ assertNotNull(s3KeysArray);
+ assertEquals(1, s3KeysArray.size());
- JsonObject s3KeyJson = s3KeysArray.getJsonObject(0);
- assertEquals(1, s3KeyJson.getInteger("id"));
- assertEquals(88, s3KeyJson.getInteger("siteId"));
- assertEquals(1687635529, s3KeyJson.getLong("activates"));
- assertEquals(1687808329, s3KeyJson.getLong("created"));
- assertEquals("newSecret", s3KeyJson.getString("secret"));
+ JsonObject s3KeyJson = s3KeysArray.getJsonObject(0);
+ assertEquals(1, s3KeyJson.getInteger("id"));
+ assertEquals(88, s3KeyJson.getInteger("siteId"));
+ assertEquals(1687635529, s3KeyJson.getLong("activates"));
+ assertEquals(1687808329, s3KeyJson.getLong("created"));
+ assertEquals("newSecret", s3KeyJson.getString("secret"));
- testContext.completeNow();
- } else {
- testContext.failNow(ar.cause());
+ testContext.completeNow();
+ } else {
+ testContext.failNow(ar.cause());
+ }
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
}
});
}
@@ -610,28 +681,32 @@ void s3encryptionKeyRetrieveSuccessWithThreeKeys(Vertx vertx, VertxTestContext t
when(s3KeyProvider.getKeys(88)).thenReturn(keys);
get(vertx, "s3encryption_keys/retrieve", ar -> {
- if (ar.succeeded()) {
- HttpResponse response = ar.result();
- assertEquals(200, response.statusCode());
-
- JsonObject json = response.bodyAsJsonObject();
- JsonArray s3KeysArray = json.getJsonArray("s3Keys");
-
- assertNotNull(s3KeysArray);
- assertEquals(3, s3KeysArray.size());
+ try {
+ if (ar.succeeded()) {
+ HttpResponse response = ar.result();
+ assertEquals(200, response.statusCode());
+
+ JsonObject json = response.bodyAsJsonObject();
+ JsonArray s3KeysArray = json.getJsonArray("s3Keys");
+
+ assertNotNull(s3KeysArray);
+ assertEquals(3, s3KeysArray.size());
+
+ for (int i = 0; i < 3; i++) {
+ JsonObject s3KeyJson = s3KeysArray.getJsonObject(i);
+ assertEquals(i + 1, s3KeyJson.getInteger("id"));
+ assertEquals(88, s3KeyJson.getInteger("siteId"));
+ assertEquals(1687635529 + i, s3KeyJson.getLong("activates"));
+ assertEquals(1687808329 + i, s3KeyJson.getLong("created"));
+ assertEquals("secret" + (i + 1), s3KeyJson.getString("secret"));
+ }
- for (int i = 0; i < 3; i++) {
- JsonObject s3KeyJson = s3KeysArray.getJsonObject(i);
- assertEquals(i + 1, s3KeyJson.getInteger("id"));
- assertEquals(88, s3KeyJson.getInteger("siteId"));
- assertEquals(1687635529 + i, s3KeyJson.getLong("activates"));
- assertEquals(1687808329 + i, s3KeyJson.getLong("created"));
- assertEquals("secret" + (i + 1), s3KeyJson.getString("secret"));
+ testContext.completeNow();
+ } else {
+ testContext.failNow(ar.cause());
}
-
- testContext.completeNow();
- } else {
- testContext.failNow(ar.cause());
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
}
});
}
@@ -650,34 +725,38 @@ void s3encryptionKeyRetrieveNoKeysOrError(Vertx vertx, VertxTestContext testCont
when(s3KeyProvider.getKeys(anyInt())).thenReturn(Collections.emptyList());
get(vertx, "s3encryption_keys/retrieve", ar -> {
- if (ar.succeeded()) {
- HttpResponse response = ar.result();
- assertEquals(500, response.statusCode());
-
- JsonObject json = response.bodyAsJsonObject();
- assertEquals("No S3 keys found", json.getString("status"));
- assertTrue(json.getString("message").contains("No S3 keys found for siteId:"));
-
- // Test case 2: Exception thrown
- when(s3KeyProvider.getKeys(anyInt())).thenThrow(new RuntimeException("Test exception"));
-
- get(vertx, "s3encryption_keys/retrieve", ar2 -> {
- if (ar2.succeeded()) {
- HttpResponse response2 = ar2.result();
- assertEquals(500, response2.statusCode());
-
- JsonObject json2 = response2.bodyAsJsonObject();
- System.out.println(json2);
- assertEquals("error", json2.getString("status"));
- assertEquals("error generating attestation token", json2.getString("message"));
-
- testContext.completeNow();
- } else {
- testContext.failNow(ar2.cause());
- }
- });
- } else {
- testContext.failNow(ar.cause());
+ try {
+ if (ar.succeeded()) {
+ HttpResponse response = ar.result();
+ assertEquals(500, response.statusCode());
+
+ JsonObject json = response.bodyAsJsonObject();
+ assertEquals("No S3 keys found", json.getString("status"));
+ assertTrue(json.getString("message").contains("No S3 keys found for siteId:"));
+
+ // Test case 2: Exception thrown
+ when(s3KeyProvider.getKeys(anyInt())).thenThrow(new RuntimeException("Test exception"));
+
+ get(vertx, "s3encryption_keys/retrieve", ar2 -> {
+ if (ar2.succeeded()) {
+ HttpResponse response2 = ar2.result();
+ assertEquals(500, response2.statusCode());
+
+ JsonObject json2 = response2.bodyAsJsonObject();
+ System.out.println(json2);
+ assertEquals("error", json2.getString("status"));
+ assertEquals("error generating attestation token", json2.getString("message"));
+
+ testContext.completeNow();
+ } else {
+ testContext.failNow(ar2.cause());
+ }
+ });
+ } else {
+ testContext.failNow(ar.cause());
+ }
+ } catch (Throwable ex) {
+ testContext.failNow(ex);
}
});
}