From 2acd8776f26686a93708eb9fc408ff4e2bbe287c Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Thu, 20 Nov 2025 01:29:49 +0000 Subject: [PATCH] 8371440: jpackage should exit with an error if it finds multiple matching signing certificates Reviewed-by: almatvee --- .../internal/SigningIdentityBuilder.java | 7 ++-- .../resources/MacResources.properties | 2 +- .../tools/jpackage/macosx/MacSignTest.java | 40 +++++++++++-------- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/SigningIdentityBuilder.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/SigningIdentityBuilder.java index bf8f1519fe1..f90e76bb23d 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/SigningIdentityBuilder.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/SigningIdentityBuilder.java @@ -156,9 +156,10 @@ final class SigningIdentityBuilder { return certs.getFirst(); } default -> { - Log.error(I18N.format("error.multiple.certs.found", certificateSelector.signingIdentities().getFirst(), - keychain.map(Keychain::name).orElse(""))); - return certs.getFirst(); + throw I18N.buildConfigException("error.multiple.certs.found", + certificateSelector.signingIdentities().getFirst(), + keychain.map(Keychain::name).orElse("") + ).create(); } } } diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties index 58c3bbbc025..afa71d84d5c 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties @@ -36,7 +36,7 @@ error.must-sign-app-store=Mac App Store apps must be signed, and signing has bee error.must-sign-app-store.advice=Use --mac-sign option with appropriate user-name and keychain error.certificate.expired=Error: Certificate expired {0} error.cert.not.found=No certificate found matching [{0}] using keychain [{1}] -error.multiple.certs.found=WARNING: Multiple certificates found matching [{0}] using keychain [{1}], using first one +error.multiple.certs.found=Multiple certificates matching name [{0}] found in keychain [{1}] error.app-image.mac-sign.required=Error: --mac-sign option is required with predefined application image and with type [app-image] error.tool.failed.with.output=Error: "{0}" failed with following output: error.invalid-runtime-image-missing-file=Runtime image "{0}" is missing "{1}" file diff --git a/test/jdk/tools/jpackage/macosx/MacSignTest.java b/test/jdk/tools/jpackage/macosx/MacSignTest.java index 014fbc84548..af7cf448bdc 100644 --- a/test/jdk/tools/jpackage/macosx/MacSignTest.java +++ b/test/jdk/tools/jpackage/macosx/MacSignTest.java @@ -39,6 +39,7 @@ import jdk.jpackage.test.JPackageStringBundle; import jdk.jpackage.test.MacHelper; import jdk.jpackage.test.MacSign; import jdk.jpackage.test.MacSign.CertificateRequest; +import jdk.jpackage.test.MacSign.CertificateType; import jdk.jpackage.test.MacSignVerify; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.TKit; @@ -155,20 +156,13 @@ public class MacSignTest { } @Test - // Case "--mac-signing-key-user-name": jpackage selects first certificate - // found with warning message. Certificate hash is pass to "codesign" in this - // case. - @Parameter({"IMAGE", "0", "GOOD_SIGNING_KEY_USER_NAME"}) - @Parameter({"MAC_DMG", "0", "GOOD_SIGNING_KEY_USER_NAME"}) - @Parameter({"MAC_PKG", "0", "GOOD_SIGNING_KEY_USER_NAME_PKG", "GOOD_SIGNING_KEY_USER_NAME"}) - - // Case "--mac-app-image-sign-identity": sign identity will be pass to - // "codesign" and "codesign" should fail due to multiple certificates with - // same common name found. - @Parameter({"IMAGE", "1", "GOOD_CODESIGN_SIGN_IDENTITY"}) - @Parameter({"MAC_PKG", "1", "GOOD_CODESIGN_SIGN_IDENTITY", "GOOD_PKG_SIGN_IDENTITY"}) - @Parameter({"MAC_PKG", "1", "GOOD_PKG_SIGN_IDENTITY"}) - public static void testMultipleCertificates(PackageType type, int jpackageExitCode, SignOption... options) { + @Parameter({"IMAGE", "GOOD_SIGNING_KEY_USER_NAME"}) + @Parameter({"MAC_DMG", "GOOD_SIGNING_KEY_USER_NAME"}) + @Parameter({"MAC_PKG", "GOOD_SIGNING_KEY_USER_NAME_PKG", "GOOD_SIGNING_KEY_USER_NAME"}) + @Parameter({"IMAGE", "GOOD_CODESIGN_SIGN_IDENTITY"}) + @Parameter({"MAC_PKG", "GOOD_CODESIGN_SIGN_IDENTITY", "GOOD_PKG_SIGN_IDENTITY"}) + @Parameter({"MAC_PKG", "GOOD_PKG_SIGN_IDENTITY"}) + public static void testMultipleCertificates(PackageType type, SignOption... options) { MacSign.withKeychain(keychain -> { final var cmd = MacHelper.useKeychain(JPackageCommand.helloAppImage(), keychain) @@ -176,9 +170,19 @@ public class MacSignTest { .addArguments(Stream.of(options).map(SignOption::args).flatMap(List::stream).toList()) .setPackageType(type); - SignOption.configureOutputValidation(cmd, List.of(options), opt -> { + Predicate filter = opt -> { + if (type == PackageType.MAC_PKG && options.length > 1) { + // Only the first error will be reported and it should always be + // for the app image signing, not for the PKG signing. + return opt.identityType() == CertificateType.CODE_SIGN; + } else { + return true; + } + }; + + SignOption.configureOutputValidation(cmd, Stream.of(options).filter(filter).toList(), opt -> { return JPackageStringBundle.MAIN.cannedFormattedString("error.multiple.certs.found", opt.identityName(), keychain.name()); - }).execute(jpackageExitCode); + }).execute(1); }, MacSign.Keychain.UsageBuilder::addToSearchList, SigningBase.StandardKeychain.DUPLICATE.keychain()); } @@ -244,6 +248,10 @@ public class MacSignTest { return cert.name(); } + CertificateType identityType() { + return cert.type(); + } + List args() { return List.of(option, shortName ? cert.shortName() : cert.name()); }