Skip to content

Commit

Permalink
The Azure Key Vault account no longer needs the permission to list th…
Browse files Browse the repository at this point in the history
…e keys when signing with jarsigner (Fixes #219)
  • Loading branch information
ebourg committed May 6, 2024
1 parent d42df81 commit 08d1297
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ See https://ebourg.github.io/jsign for more information.
* The error message displayed when the password of a PKCS#12 keystore is missing has been fixed
* 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
* API changes:
* The PEFile class has been refactored to keep only the methods related to signing
* Switched to BouncyCastle LTS 2.73.5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,28 @@ public List<String> aliases() throws KeyStoreException {
aliases.add(id.substring(id.lastIndexOf('/') + 1));
}
} catch (IOException e) {
throw new KeyStoreException("Unable to retrieve Azure Key Vault certificate aliases", e);
// return an empty list when called from the jarsigner JDK tool, because jarsigner fetches the aliases
// even if unnecessary for signing and this requires extra permissions on the Azure account (see #219)
if (!isCalledByJarSigner(e.getStackTrace())) {
throw new KeyStoreException("Unable to retrieve Azure Key Vault certificate aliases", e);
}
}

return aliases;
}

/**
* Checks the stacktrace and tells if the calling class is the jarsigner tool.
*/
private boolean isCalledByJarSigner(StackTraceElement[] trace) {
for (StackTraceElement element : trace) {
if (element.getClassName().contains("jarsigner")) {
return true;
}
}
return false;
}

@Override
public Certificate[] getCertificateChain(String alias) throws KeyStoreException {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;

import org.junit.After;
import org.junit.Before;
Expand Down Expand Up @@ -76,6 +78,34 @@ public void testGetAliasesError() {
}
}

@Test
public void testGetAliasesFromJarSigner() throws Exception {
onRequest()
.havingMethodEqualTo("GET")
.havingPathEqualTo("/certificates")
.havingQueryStringEqualTo("api-version=7.2")
.havingHeaderEqualTo("Authorization", "Bearer token")
.respond()
.withStatus(403)
.withContentType("application/json")
.withBody(new FileReader("target/test-classes/services/azure-certificates-error.json"));

SigningService service = new AzureKeyVaultSigningService("http://localhost:" + port(), "token");
List<String> aliases = new jarsigner().apply(service);

assertEquals("aliases", Collections.emptyList(), aliases);
}

private static final class jarsigner implements Function<SigningService, List<String>> {
public List<String> apply(SigningService service) {
try {
return service.aliases();
} catch (KeyStoreException e) {
throw new RuntimeException(e);
}
}
}

@Test
public void testGetCertificateChain() throws Exception {
onRequest()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"error": {
"code": "Forbidden",
"message": "The user, group or application 'appid={applicationId};iss=https://sts.windows.net/{tenantId}/' does not have certificates list permission on key vault 'jsigntestkeyvault'. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125287",
"innererror": {
"code": "ForbiddenByPolicy"
}
}
}

0 comments on commit 08d1297

Please sign in to comment.