Skip to content

Commit

Permalink
Support alternative DigiCert ONE hosts
Browse files Browse the repository at this point in the history
  • Loading branch information
ebourg committed Jun 11, 2024
1 parent daf0594 commit de919fb
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ See https://ebourg.github.io/jsign for more information.
* The log4j configuration warning displayed when signing a MSI file has been fixed (contributed by Pascal Davoust)
* The value of the `storetype` parameter is now case insensitive
* The Azure Key Vault account no longer needs the permission to list the keys when signing with jarsigner
* The DigiCert ONE host can now be specified with the --keystore parameter
* On Windows the YubiKey library path is automatically added to the PATH of the command line tool
* Signing more than one file with the `YUBIKEY` storetype no longer triggers a `CKR_USER_NOT_LOGGED_IN` error
* API changes:
Expand Down
3 changes: 2 additions & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,8 @@ <h4 id="example-digicertone">Signing with DigiCert ONE</h4>

<p>Certificates and keys stored in the <a href="https://one.digicert.com">DigiCert ONE</a> Secure Software Manager
can be used directly without installing the DigiCert client tools. It requires an API key and a PKCS#12 keystore holding
a client certificate for the authentication.</p>
a client certificate for the authentication. The US DigiCert ONE host is used by default (https://clientauth.one.digicert.com)
but a different host can be specified with the <code>--keystore</code> parameter.</p>

<pre>
jsign --storetype DIGICERTONE \
Expand Down
2 changes: 1 addition & 1 deletion jsign-crypto/src/main/java/net/jsign/KeyStoreType.java
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ void validate(KeyStoreBuilder params) {
@Override
Provider getProvider(KeyStoreBuilder params) {
String[] elements = params.storepass().split("\\|");
return new SigningServiceJcaProvider(new DigiCertOneSigningService(elements[0], params.createFile(elements[1]), elements[2]));
return new SigningServiceJcaProvider(new DigiCertOneSigningService(params.keystore(), elements[0], params.createFile(elements[1]), elements[2]));
}
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,32 @@ public DigiCertOneSigningService(String apiKey, File keystore, String storepass)
this(apiKey, (X509KeyManager) getKeyManager(keystore, storepass));
}

/**
* Creates a new DigiCert ONE signing service.
*
* @param endpoint the URL of the DigiCert ONE host
* @param apiKey the DigiCert ONE API access token
* @param keystore the keystore holding the client certificate to authenticate with the server
* @param storepass the password of the keystore
*/
public DigiCertOneSigningService(String endpoint, String apiKey, File keystore, String storepass) {
this(endpoint, apiKey, (X509KeyManager) getKeyManager(keystore, storepass));
}

/**
* Creates a new DigiCert ONE signing service.
*
* @param apiKey the DigiCert ONE API access token
* @param keyManager the key manager to authenticate the client with the server
*/
public DigiCertOneSigningService(String apiKey, X509KeyManager keyManager) {
this("https://clientauth.one.digicert.com", apiKey, keyManager);
this(null, apiKey, keyManager);
}

DigiCertOneSigningService(String endpoint, String apiKey, X509KeyManager keyManager) {
if (endpoint == null) {
endpoint = "https://clientauth.one.digicert.com";
}
this.client = new RESTClient(endpoint + "/signingmanager/api/v1/")
.authentication(conn -> {
conn.setRequestProperty("x-api-key", apiKey);
Expand All @@ -95,7 +110,7 @@ public DigiCertOneSigningService(String apiKey, X509KeyManager keyManager) {
})
.errorHandler(response -> {
Map error = (Map) response.get("error");
return error.get("status") + ": " + error.get("message");
return error != null ? error.get("status") + ": " + error.get("message") : JsonWriter.format(response);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ public void testBuildDigiCertONE() throws Exception {
assertEquals("message", "Failed to load the client certificate for DigiCert ONE", e.getMessage());
}

builder.keystore("https://clientauth.demo.one.digicert.com");
builder.storepass("APIKEY|target/test-classes/keystores/keystore.p12|password");

KeyStore keystore = builder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,25 @@ public void testGetCertificateChainWithError() {
}
}

@Test
public void testGetCertificateChainWithInvalidEndpoint() {
onRequest()
.havingMethodEqualTo("GET")
.respond()
.withStatus(404)
.withContentType("application/json")
.withBody("{\"errors\":[{\"code\":\"INTERNAL_SERVER_ERROR\",\"message\":\"Path not found\"}]}");

SigningService service = getTestService();
try {
service.getCertificateChain("jsign-1995-cert");
fail("Exception not thrown");
} catch (KeyStoreException e) {
assertEquals("message", "Unable to retrieve DigiCert ONE certificate 'jsign-1995-cert'", e.getMessage());
assertEquals("message", "{\"errors\":[{\"code\":\"INTERNAL_SERVER_ERROR\",\"message\":\"Path not found\"}]}", e.getCause().getMessage());
}
}

@Test
public void testGetPrivateKey() throws Exception {
onRequest()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public void testDigiCertProvider() throws Exception {
KeyStore keystore = KeyStore.getInstance("DIGICERTONE", provider);
keystore.load(null, "".toCharArray());

testCustomProvider(provider, keystore, "0a50eb72-68d0-4730-96cb-fe648d2c2fd2", "");
testCustomProvider(provider, keystore, "353d4f18-5325-4b78-b17c-f92375cf40ec", "");
}

@Test
Expand Down
3 changes: 2 additions & 1 deletion jsign/src/deb/data/usr/share/man/man1/jsign.1
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,8 @@ Signing with DigiCert ONE:

Certificates and keys stored in the DigiCert ONE Secure Software Manager can be used directly without installing
the DigiCert client tools. It requires an API key and a PKCS#12 keystore holding a client certificate for the
authentication.
authentication. The US DigiCert ONE host is used by default (https://clientauth.one.digicert.com) but a different
host can be specified with the --keystore parameter.

jsign --storetype DIGICERTONE \\
--storepass "<api-key>|/path/to/Certificate_pkcs12.p12|<password>" \\
Expand Down

0 comments on commit de919fb

Please sign in to comment.