Skip to content

Commit

Permalink
Handle the REST error messages in the signing services instead of RES…
Browse files Browse the repository at this point in the history
…TClient
  • Loading branch information
ebourg committed May 23, 2024
1 parent 1891685 commit b1e40c4
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ public AmazonSigningService(String region, AmazonCredentials credentials, Functi

AmazonSigningService(Supplier<AmazonCredentials> credentials, Function<String, Certificate[]> certificateStore, String endpoint) {
this.certificateStore = certificateStore;
this.client = new RESTClient(endpoint).authentication((conn, data) -> sign(conn, credentials.get(), data, null));
this.client = new RESTClient(endpoint)
.authentication((conn, data) -> sign(conn, credentials.get(), data, null))
.errorHandler(response -> response.get("__type") + ": " + response.get("message"));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ public AzureKeyVaultSigningService(String vault, String token) {
if (!vault.startsWith("http")) {
vault = "https://" + vault + ".vault.azure.net";
}
this.client = new RESTClient(vault).authentication(conn -> conn.setRequestProperty("Authorization", "Bearer " + token));
this.client = new RESTClient(vault)
.authentication(conn -> conn.setRequestProperty("Authorization", "Bearer " + token))
.errorHandler(response -> {
Map error = (Map) response.get("error");
return error.get("code") + ": " + error.get("message");
});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ public AzureTrustedSigningService(String endpoint, String token) {
if (!endpoint.startsWith("http")) {
endpoint = "https://" + endpoint;
}
client = new RESTClient(endpoint).authentication(conn -> conn.setRequestProperty("Authorization", "Bearer " + token));
client = new RESTClient(endpoint)
.authentication(conn -> conn.setRequestProperty("Authorization", "Bearer " + token))
.errorHandler(response -> {
String errors = JsonWriter.objectToJson(response.get("errors"));
return response.get("status") + " - " + response.get("title") + ": " + errors;
});
}

void setTimeout(int timeout) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ public DigiCertOneSigningService(String apiKey, X509KeyManager keyManager) {
} catch (GeneralSecurityException e) {
throw new RuntimeException("Unable to load the DigiCert ONE client certificate", e);
}
})
.errorHandler(response -> {
Map error = (Map) response.get("error");
return error.get("status") + ": " + error.get("message");
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ public ESignerSigningService(String endpoint, String username, String password)
}

public ESignerSigningService(String endpoint, String accessToken) {
client = new RESTClient(endpoint).authentication(conn -> conn.setRequestProperty("Authorization", "Bearer " + accessToken));
client = new RESTClient(endpoint).debug(true)
.authentication(conn -> conn.setRequestProperty("Authorization", "Bearer " + accessToken))
.errorHandler(response -> response.get("error") + ": " + response.get("error_description"));
}

private static String getAccessToken(String endpoint, String clientId, String username, String password) throws IOException {
Expand All @@ -77,7 +79,7 @@ private static String getAccessToken(String endpoint, String clientId, String us
Map<String, Object> args = new HashMap<>();
args.put(JsonWriter.TYPE, "false");

RESTClient client = new RESTClient(endpoint);
RESTClient client = new RESTClient(endpoint).errorHandler(response -> response.get("error") + ": " + response.get("error_description"));
Map<String, ?> response = client.post("/oauth2/token", JsonWriter.objectToJson(request, args));
return (String) response.get("access_token");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,30 @@ public GoogleCloudSigningService(String keyring, String token, Function<String,
GoogleCloudSigningService(String endpoint, String keyring, String token, Function<String, Certificate[]> certificateStore) {
this.keyring = keyring;
this.certificateStore = certificateStore;
this.client = new RESTClient(endpoint).authentication(conn -> conn.setRequestProperty("Authorization", "Bearer " + token));
this.client = new RESTClient(endpoint)
.authentication(conn -> conn.setRequestProperty("Authorization", "Bearer " + token))
.errorHandler(response -> {
StringBuilder message = new StringBuilder();
if (response.get("error") instanceof Map) {
Map error = (Map) response.get("error");
if (error.get("code") != null) {
message.append(error.get("code"));
}
if (error.get("status") != null) {
if (message.length() > 0) {
message.append(" - ");
}
message.append(error.get("status"));
}
if (error.get("message") != null) {
if (message.length() > 0) {
message.append(": ");
}
message.append(error.get("message"));
}
}
return message.toString();
});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,14 @@ public List<String> aliases() throws KeyStoreException {

try {
// VaultSummary/ListVaults (https://docs.oracle.com/en-us/iaas/api/#/en/key/release/VaultSummary/ListVaults)
RESTClient kmsClient = new RESTClient(getVaultEndpoint()).authentication(this::sign);
RESTClient kmsClient = new RESTClient(getVaultEndpoint()).authentication(this::sign).errorHandler(this::error);
Map<String, ?> result = kmsClient.get("/20180608/vaults?compartmentId=" + credentials.getTenancy());
Object[] vaults = (Object[]) result.get("result");
for (Object v : vaults) {
Map<String, ?> vault = (Map<String, ?>) v;
if ("ACTIVE".equals(vault.get("lifecycleState"))) {
String endpoint = (String) vault.get("managementEndpoint");
RESTClient managementClient = new RESTClient(endpoint).authentication(this::sign);
RESTClient managementClient = new RESTClient(endpoint).authentication(this::sign).errorHandler(this::error);

// KeySummary/ListKeys (https://docs.oracle.com/en-us/iaas/api/#/en/key/release/KeySummary/ListKeys)
result = managementClient.get("/20180608/keys?compartmentId=" + credentials.getTenancy());
Expand Down Expand Up @@ -157,7 +157,7 @@ public byte[] sign(SigningServicePrivateKey privateKey, String algorithm, byte[]
args.put(JsonWriter.TYPE, "false");

try {
RESTClient client = new RESTClient(getKeyEndpoint(privateKey.getId())).authentication(this::sign);
RESTClient client = new RESTClient(getKeyEndpoint(privateKey.getId())).authentication(this::sign).errorHandler(this::error);
Map<String, ?> response = client.post("/20180608/sign", JsonWriter.objectToJson(request, args));
String signature = (String) response.get("signature");
return Base64.getDecoder().decode(signature);
Expand Down Expand Up @@ -253,4 +253,8 @@ private byte[] rsa256sign(PrivateKey privateKey, String message) {
throw new RuntimeException(e);
}
}

private String error(Map<String, ?> response) {
return response.get("code") + ": " + response.get("message");
}
}
53 changes: 10 additions & 43 deletions jsign-core/src/main/java/net/jsign/jca/RESTClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;

import com.cedarsoftware.util.io.JsonReader;
import com.cedarsoftware.util.io.JsonWriter;
import org.apache.commons.io.IOUtils;

class RESTClient {
Expand All @@ -38,6 +38,9 @@ class RESTClient {
/** Callback setting the authentication headers for the request */
private BiConsumer<HttpURLConnection, byte[]> authenticationHandler;

/** Callback building an error message from the JSON formatted error response */
private Function<Map<String, ?>, String> errorHandler;

private boolean debug;

public RESTClient(String endpoint) {
Expand All @@ -59,6 +62,11 @@ public RESTClient debug(boolean debug) {
return this;
}

public RESTClient errorHandler(Function<Map<String, ?>, String> errorHandler) {
this.errorHandler = errorHandler;
return this;
}

public Map<String, ?> get(String resource) throws IOException {
return query("GET", resource, null, null);
}
Expand Down Expand Up @@ -145,51 +153,10 @@ public RESTClient debug(boolean debug) {
System.out.println("Error:\n" + error);
}
if (contentType != null && (contentType.startsWith("application/json") || contentType.startsWith("application/x-amz-json-1.1"))) {
throw new IOException(getErrorMessage(JsonReader.jsonToMaps(error)));
throw new IOException(errorHandler != null ? errorHandler.apply(JsonReader.jsonToMaps(error)) : error);
} else {
throw new IOException("HTTP Error " + responseCode + (conn.getResponseMessage() != null ? " - " + conn.getResponseMessage() : "") + " (" + url + ")");
}
}
}

private String getErrorMessage(Map<String, ?> response) {
StringBuilder message = new StringBuilder();

if (response.get("error") instanceof Map) {
Map error = (Map) response.get("error");
if (error.get("code") != null) {
message.append(error.get("code"));
}
if (error.get("status") != null) {
if (message.length() > 0) {
message.append(" - ");
}
message.append(error.get("status"));
}
if (error.get("message") != null) {
if (message.length() > 0) {
message.append(": ");
}
message.append(error.get("message"));
}
} else if (response.containsKey("__type")) {
// error from the AWS API
String error = (String) response.get("__type");
String description = (String) response.get("message");
message.append(error).append(": ").append(description);
} else if (response.containsKey("title") && response.containsKey("errors")) {
// error from Azure Code Signing API
String errors = JsonWriter.objectToJson(response.get("errors"));
message.append(response.get("status")).append(" - ").append(response.get("title")).append(": ").append(errors);
} else if (response.containsKey("code") && response.containsKey("message")) {
// error from OCI API
message.append(response.get("code")).append(": ").append(response.get("message"));
} else {
// error message from the CSC API
String error = (String) response.get("error");
String description = (String) response.get("error_description");
message.append(error).append(": ").append(description);
}
return message.toString();
}
}

0 comments on commit b1e40c4

Please sign in to comment.