mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-30 04:43:27 +00:00
8370126: Improve jpackage signing testing
Reviewed-by: almatvee
This commit is contained in:
parent
634746a0f1
commit
2aa0efd425
@ -26,14 +26,8 @@
|
||||
package jdk.jpackage.internal;
|
||||
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE_FILE;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.SIGN_BUNDLE;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import jdk.jpackage.internal.model.ConfigException;
|
||||
|
||||
public abstract class MacBaseInstallerBundler extends AbstractBundler {
|
||||
@ -44,26 +38,7 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler {
|
||||
|
||||
protected void validateAppImageAndBundeler(
|
||||
Map<String, ? super Object> params) throws ConfigException {
|
||||
if (PREDEFINED_APP_IMAGE.fetchFrom(params) != null) {
|
||||
Path applicationImage = PREDEFINED_APP_IMAGE.fetchFrom(params);
|
||||
if (new MacAppImageFileExtras(PREDEFINED_APP_IMAGE_FILE.fetchFrom(params)).signed()) {
|
||||
var appLayout = ApplicationLayoutUtils.PLATFORM_APPLICATION_LAYOUT.resolveAt(applicationImage);
|
||||
if (!Files.exists(
|
||||
PackageFile.getPathInAppImage(appLayout))) {
|
||||
Log.info(MessageFormat.format(I18N.getString(
|
||||
"warning.per.user.app.image.signed"),
|
||||
PackageFile.getPathInAppImage(appLayout)));
|
||||
}
|
||||
} else {
|
||||
if (Optional.ofNullable(
|
||||
SIGN_BUNDLE.fetchFrom(params)).orElse(Boolean.FALSE)) {
|
||||
// if signing bundle with app-image, warn user if app-image
|
||||
// is not already signed.
|
||||
Log.info(MessageFormat.format(I18N.getString(
|
||||
"warning.unsigned.app.image"), getID()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (PREDEFINED_APP_IMAGE.fetchFrom(params) == null) {
|
||||
appImageBundler.validate(params);
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,8 +24,10 @@
|
||||
*/
|
||||
package jdk.jpackage.internal;
|
||||
|
||||
import static jdk.jpackage.internal.MacPackagingPipeline.APPLICATION_LAYOUT;
|
||||
import static jdk.jpackage.internal.MacPackagingPipeline.LayoutUtils.packagerLayout;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.util.Objects;
|
||||
import jdk.jpackage.internal.model.ConfigException;
|
||||
import jdk.jpackage.internal.model.MacApplication;
|
||||
@ -57,7 +59,21 @@ final class MacPackageBuilder {
|
||||
.installedPackageLayout(pkg.installedPackageLayout());
|
||||
|
||||
pkg = pkgBuilder.create();
|
||||
return MacPackage.create(pkg, new MacPackageMixin.Stub(pkg.predefinedAppImage().map(v -> predefinedAppImageSigned)));
|
||||
|
||||
var macPkg = MacPackage.create(pkg, new MacPackageMixin.Stub(pkg.predefinedAppImage().map(v -> predefinedAppImageSigned)));
|
||||
validatePredefinedAppImage(macPkg);
|
||||
return macPkg;
|
||||
}
|
||||
|
||||
private static void validatePredefinedAppImage(MacPackage pkg) {
|
||||
if (pkg.predefinedAppImageSigned().orElse(false)) {
|
||||
pkg.predefinedAppImage().ifPresent(predefinedAppImage -> {
|
||||
var thePackageFile = PackageFile.getPathInAppImage(APPLICATION_LAYOUT);
|
||||
if (!Files.exists(predefinedAppImage.resolve(thePackageFile))) {
|
||||
Log.info(I18N.format("warning.per.user.app.image.signed", thePackageFile));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private final PackageBuilder pkgBuilder;
|
||||
|
||||
@ -43,7 +43,9 @@ final class MacPkgPackageBuilder {
|
||||
}
|
||||
|
||||
MacPkgPackage create() throws ConfigException {
|
||||
return MacPkgPackage.create(pkgBuilder.create(), new MacPkgPackageMixin.Stub(createSigningConfig()));
|
||||
var pkg = MacPkgPackage.create(pkgBuilder.create(), new MacPkgPackageMixin.Stub(createSigningConfig()));
|
||||
validatePredefinedAppImage(pkg);
|
||||
return pkg;
|
||||
}
|
||||
|
||||
private Optional<PkgSigningConfig> createSigningConfig() throws ConfigException {
|
||||
@ -56,6 +58,14 @@ final class MacPkgPackageBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private static void validatePredefinedAppImage(MacPkgPackage pkg) {
|
||||
if (!pkg.predefinedAppImageSigned().orElse(false) && pkg.sign()) {
|
||||
pkg.predefinedAppImage().ifPresent(predefinedAppImage -> {
|
||||
Log.info(I18N.format("warning.unsigned.app.image", "pkg"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private final MacPackageBuilder pkgBuilder;
|
||||
private SigningIdentityBuilder signingBuilder;
|
||||
}
|
||||
|
||||
@ -1131,6 +1131,11 @@ public class JPackageCommand extends CommandArguments<JPackageCommand> {
|
||||
MacHelper.verifyBundleStructure(cmd);
|
||||
}
|
||||
}),
|
||||
MAC_BUNDLE_UNSIGNED_SIGNATURE(cmd -> {
|
||||
if (TKit.isOSX() && !MacHelper.appImageSigned(cmd)) {
|
||||
MacHelper.verifyUnsignedBundleSignature(cmd);
|
||||
}
|
||||
}),
|
||||
;
|
||||
|
||||
AppLayoutAssert(Consumer<JPackageCommand> action) {
|
||||
|
||||
@ -52,6 +52,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
@ -66,6 +67,7 @@ import jdk.jpackage.internal.util.PathUtils;
|
||||
import jdk.jpackage.internal.util.XmlUtils;
|
||||
import jdk.jpackage.internal.util.function.ThrowingConsumer;
|
||||
import jdk.jpackage.internal.util.function.ThrowingSupplier;
|
||||
import jdk.jpackage.test.MacSign.CertificateRequest;
|
||||
import jdk.jpackage.test.PackageTest.PackageHandlers;
|
||||
|
||||
public final class MacHelper {
|
||||
@ -229,25 +231,61 @@ public final class MacHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the given jpackage command line is configured to sign
|
||||
* predefined app image in place.
|
||||
* <p>
|
||||
* jpackage will not create a new app image or a native bundle.
|
||||
*
|
||||
* @param cmd the jpackage command to examine
|
||||
* @return {@code true} if the given jpackage command line is configured to sign
|
||||
* predefined app image in place and {@code false} otherwise.
|
||||
*/
|
||||
public static boolean signPredefinedAppImage(JPackageCommand cmd) {
|
||||
Objects.requireNonNull(cmd);
|
||||
if (!TKit.isOSX()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
return cmd.hasArgument("--mac-sign") && cmd.hasArgument("--app-image");
|
||||
return cmd.hasArgument("--mac-sign") && cmd.hasArgument("--app-image") && cmd.isImagePackageType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the given jpackage command line is configured such
|
||||
* that the app image it will produce will be signed.
|
||||
* <p>
|
||||
* If the jpackage command line is bundling a native package, the function
|
||||
* returns {@code true} if the bundled app image will be signed.
|
||||
*
|
||||
* @param cmd the jpackage command to examine
|
||||
* @return {@code true} if the given jpackage command line is configured such
|
||||
* that the app image it will produce will be signed and {@code false}
|
||||
* otherwise.
|
||||
*/
|
||||
public static boolean appImageSigned(JPackageCommand cmd) {
|
||||
Objects.requireNonNull(cmd);
|
||||
if (!TKit.isOSX()) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
if (Optional.ofNullable(cmd.getArgumentValue("--app-image")).map(Path::of).map(AppImageFile::load).map(AppImageFile::macSigned).orElse(false)) {
|
||||
var runtimeImage = Optional.ofNullable(cmd.getArgumentValue("--runtime-image")).map(Path::of);
|
||||
var appImage = Optional.ofNullable(cmd.getArgumentValue("--app-image")).map(Path::of);
|
||||
|
||||
if (cmd.isRuntime() && Files.isDirectory(runtimeImage.orElseThrow().resolve("Contents/_CodeSignature"))) {
|
||||
// If the predefined runtime is a signed bundle, bundled image should be signed too.
|
||||
return true;
|
||||
} else if (appImage.map(AppImageFile::load).map(AppImageFile::macSigned).orElse(false)) {
|
||||
// The external app image is signed, so the app image is signed too.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!cmd.isImagePackageType() && appImage.isPresent()) {
|
||||
// Building a ".pkg" or a ".dmg" bundle from the predefined app image.
|
||||
// The predefined app image is unsigned, so the app image bundled
|
||||
// in the output native package will be unsigned too
|
||||
// (even if the ".pkg" file may be signed itself, and we never sign ".dmg" files).
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!cmd.hasArgument("--mac-sign")) {
|
||||
return false;
|
||||
}
|
||||
@ -332,6 +370,100 @@ public final class MacHelper {
|
||||
}).run();
|
||||
}
|
||||
|
||||
public static JPackageCommand useKeychain(JPackageCommand cmd, MacSign.ResolvedKeychain keychain) {
|
||||
return useKeychain(cmd, keychain.spec().keychain());
|
||||
}
|
||||
|
||||
public static JPackageCommand useKeychain(JPackageCommand cmd, MacSign.Keychain keychain) {
|
||||
return sign(cmd).addArguments("--mac-signing-keychain", keychain.name());
|
||||
}
|
||||
|
||||
public static JPackageCommand sign(JPackageCommand cmd) {
|
||||
if (!cmd.hasArgument("--mac-sign")) {
|
||||
cmd.addArgument("--mac-sign");
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
public record SignKeyOption(Type type, CertificateRequest certRequest) {
|
||||
|
||||
public SignKeyOption {
|
||||
Objects.requireNonNull(type);
|
||||
Objects.requireNonNull(certRequest);
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
SIGN_KEY_USER_NAME,
|
||||
SIGN_KEY_IDENTITY,
|
||||
;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
var sb = new StringBuffer();
|
||||
applyTo((optionName, _) -> {
|
||||
sb.append(String.format("{%s: %s}", optionName, certRequest));
|
||||
});
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public JPackageCommand addTo(JPackageCommand cmd) {
|
||||
applyTo(cmd::addArguments);
|
||||
return sign(cmd);
|
||||
}
|
||||
|
||||
public JPackageCommand setTo(JPackageCommand cmd) {
|
||||
applyTo(cmd::setArgumentValue);
|
||||
return sign(cmd);
|
||||
}
|
||||
|
||||
private void applyTo(BiConsumer<String, String> sink) {
|
||||
switch (certRequest.type()) {
|
||||
case INSTALLER -> {
|
||||
switch (type) {
|
||||
case SIGN_KEY_IDENTITY -> {
|
||||
sink.accept("--mac-installer-sign-identity", certRequest.name());
|
||||
return;
|
||||
}
|
||||
case SIGN_KEY_USER_NAME -> {
|
||||
sink.accept("--mac-signing-key-user-name", certRequest.shortName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
case CODE_SIGN -> {
|
||||
switch (type) {
|
||||
case SIGN_KEY_IDENTITY -> {
|
||||
sink.accept("--mac-app-image-sign-identity", certRequest.name());
|
||||
return;
|
||||
}
|
||||
case SIGN_KEY_USER_NAME -> {
|
||||
sink.accept("--mac-signing-key-user-name", certRequest.shortName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
static void verifyUnsignedBundleSignature(JPackageCommand cmd) {
|
||||
if (!cmd.isImagePackageType()) {
|
||||
MacSignVerify.assertUnsigned(cmd.outputBundle());
|
||||
}
|
||||
|
||||
final Path bundleRoot;
|
||||
if (cmd.isImagePackageType()) {
|
||||
bundleRoot = cmd.outputBundle();
|
||||
} else {
|
||||
bundleRoot = cmd.pathToUnpackedPackageFile(cmd.appInstallationDirectory());
|
||||
}
|
||||
|
||||
MacSignVerify.assertAdhocSigned(bundleRoot);
|
||||
}
|
||||
|
||||
static PackageHandlers createDmgPackageHandlers() {
|
||||
return new PackageHandlers(MacHelper::installDmg, MacHelper::uninstallDmg, MacHelper::unpackDmg);
|
||||
}
|
||||
|
||||
@ -59,6 +59,7 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
import javax.naming.ldap.LdapName;
|
||||
@ -351,6 +352,52 @@ public final class MacSign {
|
||||
private String password;
|
||||
}
|
||||
|
||||
public static final class UsageBuilder {
|
||||
|
||||
UsageBuilder(Collection<Keychain> keychains) {
|
||||
this.keychains = List.copyOf(keychains);
|
||||
}
|
||||
|
||||
public void run(Runnable runnable) {
|
||||
Objects.requireNonNull(runnable);
|
||||
|
||||
final Optional<List<Path>> oldKeychains;
|
||||
if (addToSearchList) {
|
||||
oldKeychains = Optional.ofNullable(activeKeychainFiles());
|
||||
Keychain.addToSearchList(keychains);
|
||||
} else {
|
||||
oldKeychains = Optional.empty();
|
||||
}
|
||||
|
||||
try {
|
||||
// Ensure keychains to be used for signing are unlocked.
|
||||
// When the codesign command operates on a locked keychain in a ssh session
|
||||
// it emits cryptic "errSecInternalComponent" error without other details.
|
||||
keychains.forEach(Keychain::unlock);
|
||||
runnable.run();
|
||||
} finally {
|
||||
oldKeychains.ifPresent(restoreKeychains -> {
|
||||
security("list-keychains", "-d", "user", "-s")
|
||||
.addArguments(restoreKeychains.stream().map(Path::toString).toList())
|
||||
.execute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public UsageBuilder addToSearchList(boolean v) {
|
||||
addToSearchList = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UsageBuilder addToSearchList() {
|
||||
return addToSearchList(true);
|
||||
}
|
||||
|
||||
private final Collection<Keychain> keychains;
|
||||
private boolean addToSearchList;
|
||||
}
|
||||
|
||||
|
||||
Keychain create() {
|
||||
final var exec = createExecutor("create-keychain");
|
||||
final var result = exec.saveOutput().executeWithoutExitCodeCheck();
|
||||
@ -415,24 +462,12 @@ public final class MacSign {
|
||||
return certs;
|
||||
}
|
||||
|
||||
public static void addToSearchList(Collection<Keychain> keychains) {
|
||||
static void addToSearchList(Collection<Keychain> keychains) {
|
||||
security("list-keychains", "-d", "user", "-s", "login.keychain")
|
||||
.addArguments(keychains.stream().map(Keychain::name).toList())
|
||||
.execute();
|
||||
}
|
||||
|
||||
public static void withAddedKeychains(Collection<Keychain> keychains, Runnable runnable) {
|
||||
final var curKeychains = activeKeychainFiles();
|
||||
addToSearchList(keychains);
|
||||
try {
|
||||
runnable.run();
|
||||
} finally {
|
||||
security("list-keychains", "-d", "user", "-s")
|
||||
.addArguments(curKeychains.stream().map(Path::toString).toList())
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Path> activeKeychainFiles() {
|
||||
// $ security list-keychains
|
||||
// "/Users/alexeysemenyuk/Library/Keychains/login.keychain-db"
|
||||
@ -1037,6 +1072,47 @@ public final class MacSign {
|
||||
return !missingKeychain && !missingCertificates && !invalidCertificates;
|
||||
}
|
||||
|
||||
public static Keychain.UsageBuilder withKeychains(KeychainWithCertsSpec... keychains) {
|
||||
return withKeychains(Stream.of(keychains).map(KeychainWithCertsSpec::keychain).toArray(Keychain[]::new));
|
||||
}
|
||||
|
||||
public static Keychain.UsageBuilder withKeychains(Keychain... keychains) {
|
||||
return new Keychain.UsageBuilder(List.of(keychains));
|
||||
}
|
||||
|
||||
public static void withKeychains(Runnable runnable, Consumer<Keychain.UsageBuilder> mutator, Keychain... keychains) {
|
||||
Objects.requireNonNull(runnable);
|
||||
var builder = withKeychains(keychains);
|
||||
mutator.accept(builder);
|
||||
builder.run(runnable);
|
||||
}
|
||||
|
||||
public static void withKeychains(Runnable runnable, Keychain... keychains) {
|
||||
withKeychains(runnable, _ -> {}, keychains);
|
||||
}
|
||||
|
||||
public static void withKeychain(Consumer<Keychain> consumer, Consumer<Keychain.UsageBuilder> mutator, Keychain keychain) {
|
||||
Objects.requireNonNull(consumer);
|
||||
withKeychains(() -> {
|
||||
consumer.accept(keychain);
|
||||
}, mutator, keychain);
|
||||
}
|
||||
|
||||
public static void withKeychain(Consumer<Keychain> consumer, Keychain keychain) {
|
||||
withKeychain(consumer, _ -> {}, keychain);
|
||||
}
|
||||
|
||||
public static void withKeychain(Consumer<ResolvedKeychain> consumer, Consumer<Keychain.UsageBuilder> mutator, ResolvedKeychain keychain) {
|
||||
Objects.requireNonNull(consumer);
|
||||
withKeychains(() -> {
|
||||
consumer.accept(keychain);
|
||||
}, mutator, keychain.spec().keychain());
|
||||
}
|
||||
|
||||
public static void withKeychain(Consumer<ResolvedKeychain> consumer, ResolvedKeychain keychain) {
|
||||
withKeychain(consumer, _ -> {}, keychain);
|
||||
}
|
||||
|
||||
public static final class ResolvedKeychain {
|
||||
public ResolvedKeychain(KeychainWithCertsSpec spec) {
|
||||
this.spec = Objects.requireNonNull(spec);
|
||||
@ -1046,6 +1122,10 @@ public final class MacSign {
|
||||
return spec;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return spec.keychain().name();
|
||||
}
|
||||
|
||||
public Map<CertificateRequest, X509Certificate> mapCertificateRequests() {
|
||||
if (certMap == null) {
|
||||
synchronized (this) {
|
||||
|
||||
@ -44,6 +44,43 @@ import jdk.jpackage.test.MacSign.CertificateRequest;
|
||||
*/
|
||||
public final class MacSignVerify {
|
||||
|
||||
public static void verifyAppImageSigned(
|
||||
JPackageCommand cmd, CertificateRequest certRequest, MacSign.ResolvedKeychain keychain) {
|
||||
|
||||
cmd.verifyIsOfType(PackageType.MAC);
|
||||
Objects.requireNonNull(certRequest);
|
||||
Objects.requireNonNull(keychain);
|
||||
|
||||
final Path bundleRoot;
|
||||
if (cmd.isImagePackageType()) {
|
||||
bundleRoot = cmd.outputBundle();
|
||||
} else {
|
||||
bundleRoot = cmd.pathToUnpackedPackageFile(
|
||||
cmd.appInstallationDirectory());
|
||||
}
|
||||
|
||||
assertSigned(bundleRoot, certRequest);
|
||||
|
||||
if (!cmd.isRuntime()) {
|
||||
cmd.addLauncherNames().stream().map(cmd::appLauncherPath).forEach(launcherPath -> {
|
||||
assertSigned(launcherPath, certRequest);
|
||||
});
|
||||
}
|
||||
|
||||
// Set to "null" if the sign origin is not found, instead of bailing out with an exception.
|
||||
// Let is fail in the following TKit.assertEquals() call with a proper log message.
|
||||
var signOrigin = findSpctlSignOrigin(SpctlType.EXEC, bundleRoot).orElse(null);
|
||||
|
||||
TKit.assertEquals(certRequest.name(), signOrigin,
|
||||
String.format("Check [%s] has sign origin as expected", bundleRoot));
|
||||
}
|
||||
|
||||
public static void verifyPkgSigned(JPackageCommand cmd, CertificateRequest certRequest, MacSign.ResolvedKeychain keychain) {
|
||||
cmd.verifyIsOfType(PackageType.MAC_PKG);
|
||||
assertPkgSigned(cmd.outputBundle(), certRequest,
|
||||
Objects.requireNonNull(keychain.mapCertificateRequests().get(certRequest)));
|
||||
}
|
||||
|
||||
public static void assertSigned(Path path, CertificateRequest certRequest) {
|
||||
assertSigned(path);
|
||||
TKit.assertEquals(certRequest.name(), findCodesignSignOrigin(path).orElse(null),
|
||||
@ -114,8 +151,8 @@ public final class MacSignVerify {
|
||||
}
|
||||
|
||||
public static Optional<String> findCodesignSignOrigin(Path path) {
|
||||
final var exec = Executor.of("/usr/bin/codesign", "--display", "--verbose=4", path.toString()).saveOutput();
|
||||
final var result = exec.executeWithoutExitCodeCheck();
|
||||
final var exec = Executor.of("/usr/bin/codesign", "--display", "--verbose=4", path.toString());
|
||||
final var result = exec.saveOutput().executeWithoutExitCodeCheck();
|
||||
if (result.getExitCode() == 0) {
|
||||
return Optional.of(result.getOutput().stream().map(line -> {
|
||||
if (line.equals("Signature=adhoc")) {
|
||||
@ -144,12 +181,34 @@ public final class MacSignVerify {
|
||||
}
|
||||
|
||||
public static void assertSigned(Path path) {
|
||||
final var verifier = TKit.TextStreamVerifier.group()
|
||||
.add(TKit.assertTextStream(": valid on disk").predicate(String::endsWith))
|
||||
.add(TKit.assertTextStream(": satisfies its Designated Requirement").predicate(String::endsWith))
|
||||
.create();
|
||||
verifier.accept(Executor.of("/usr/bin/codesign", "--verify", "--deep",
|
||||
"--strict", "--verbose=2", path.toString()).executeAndGetOutput().iterator());
|
||||
assertSigned(path, false);
|
||||
}
|
||||
|
||||
private static void assertSigned(Path path, boolean sudo) {
|
||||
final Executor exec;
|
||||
if (sudo) {
|
||||
exec = Executor.of("sudo", "/usr/bin/codesign");
|
||||
} else {
|
||||
exec = Executor.of("/usr/bin/codesign");
|
||||
}
|
||||
exec.addArguments("--verify", "--deep", "--strict", "--verbose=2", path.toString());
|
||||
final var result = exec.saveOutput().executeWithoutExitCodeCheck();
|
||||
if (result.getExitCode() == 0) {
|
||||
TKit.TextStreamVerifier.group()
|
||||
.add(TKit.assertTextStream(": valid on disk").predicate(String::endsWith))
|
||||
.add(TKit.assertTextStream(": satisfies its Designated Requirement").predicate(String::endsWith))
|
||||
.create().accept(result.getOutput().iterator());
|
||||
} else if (!sudo && result.getOutput().stream().findFirst().filter(str -> {
|
||||
// By some reason /usr/bin/codesign command fails for some installed bundles.
|
||||
// It is known to fail for some AppContentTest test cases and all FileAssociationsTest test cases.
|
||||
// Rerunning the command with "sudo" works, though.
|
||||
return str.equals(String.format("%s: Permission denied", path));
|
||||
}).isPresent()) {
|
||||
TKit.trace("Try /usr/bin/codesign again with `sudo`");
|
||||
assertSigned(path, true);
|
||||
} else {
|
||||
reportUnexpectedCommandOutcome(exec.getPrintableCommandLine(), result);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<SignIdentity> getPkgCertificateChain(Path path) {
|
||||
|
||||
@ -70,14 +70,14 @@ public class MacSignTest {
|
||||
final List<CannedFormattedString> expectedStrings = new ArrayList<>();
|
||||
expectedStrings.add(JPackageStringBundle.MAIN.cannedFormattedString("message.codesign.failed.reason.app.content"));
|
||||
|
||||
expectedStrings.add(JPackageStringBundle.MAIN.cannedFormattedString("error.tool.failed.with.output", "codesign"));
|
||||
|
||||
final var xcodeWarning = JPackageStringBundle.MAIN.cannedFormattedString("message.codesign.failed.reason.xcode.tools");
|
||||
if (!MacHelper.isXcodeDevToolsInstalled()) {
|
||||
expectedStrings.add(xcodeWarning);
|
||||
}
|
||||
|
||||
final var keychain = SigningBase.StandardKeychain.EXPIRED.spec().keychain();
|
||||
|
||||
MacSign.Keychain.withAddedKeychains(List.of(keychain), () -> {
|
||||
MacSign.withKeychain(keychain -> {
|
||||
// --app-content and --type app-image
|
||||
// Expect `message.codesign.failed.reason.app.content` message in the log.
|
||||
// This is not a fatal error, just a warning.
|
||||
@ -86,8 +86,6 @@ public class MacSignTest {
|
||||
.ignoreDefaultVerbose(true)
|
||||
.validateOutput(expectedStrings.toArray(CannedFormattedString[]::new))
|
||||
.addArguments("--app-content", appContent)
|
||||
.addArguments("--mac-sign")
|
||||
.addArguments("--mac-signing-keychain", keychain.name())
|
||||
.addArguments("--mac-app-image-sign-identity", SigningBase.StandardCertificateRequest.CODESIGN.spec().name());
|
||||
|
||||
if (MacHelper.isXcodeDevToolsInstalled()) {
|
||||
@ -95,8 +93,36 @@ public class MacSignTest {
|
||||
cmd.validateOutput(TKit.assertTextStream(xcodeWarning.getValue()).negate());
|
||||
}
|
||||
|
||||
cmd.execute(1);
|
||||
});
|
||||
MacHelper.useKeychain(cmd, keychain).execute(1);
|
||||
}, MacSign.Keychain.UsageBuilder::addToSearchList, SigningBase.StandardKeychain.MAIN.keychain());
|
||||
}
|
||||
|
||||
@Test
|
||||
public static void testCodesignUnspecifiedFailure() throws IOException {
|
||||
|
||||
var appImageCmd = JPackageCommand.helloAppImage().setFakeRuntime();
|
||||
|
||||
appImageCmd.executeIgnoreExitCode().assertExitCodeIsZero();
|
||||
|
||||
// This test expects jpackage to respond in a specific way on a codesign failure.
|
||||
// The simplest option to trigger codesign failure is to request the signing of an invalid bundle.
|
||||
// Create app content directory with the name known to fail signing.
|
||||
final var appContent = appImageCmd.appLayout().contentDirectory().resolve("foo.1");
|
||||
Files.createDirectory(appContent);
|
||||
Files.createFile(appContent.resolve("file"));
|
||||
|
||||
final List<CannedFormattedString> expectedStrings = new ArrayList<>();
|
||||
expectedStrings.add(JPackageStringBundle.MAIN.cannedFormattedString("error.tool.failed.with.output", "codesign"));
|
||||
|
||||
MacSign.withKeychain(keychain -> {
|
||||
final var cmd = new JPackageCommand().setPackageType(PackageType.IMAGE)
|
||||
.ignoreDefaultVerbose(true)
|
||||
.validateOutput(expectedStrings.toArray(CannedFormattedString[]::new))
|
||||
.addArguments("--app-image", appImageCmd.outputBundle())
|
||||
.addArguments("--mac-app-image-sign-identity", SigningBase.StandardCertificateRequest.CODESIGN.spec().name());
|
||||
|
||||
MacHelper.useKeychain(cmd, keychain).execute(1);
|
||||
}, MacSign.Keychain.UsageBuilder::addToSearchList, SigningBase.StandardKeychain.MAIN.keychain());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -116,20 +142,16 @@ public class MacSignTest {
|
||||
@Parameter({"MAC_PKG", "EXPIRED_CODESIGN_SIGN_IDENTITY", "GOOD_PKG_SIGN_IDENTITY"})
|
||||
public static void testExpiredCertificate(PackageType type, SignOption... options) {
|
||||
|
||||
final var keychain = SigningBase.StandardKeychain.EXPIRED.spec().keychain();
|
||||
|
||||
MacSign.Keychain.withAddedKeychains(List.of(keychain), () -> {
|
||||
final var cmd = JPackageCommand.helloAppImage()
|
||||
MacSign.withKeychain(keychain -> {
|
||||
final var cmd = MacHelper.useKeychain(JPackageCommand.helloAppImage(), keychain)
|
||||
.ignoreDefaultVerbose(true)
|
||||
.addArguments("--mac-sign")
|
||||
.addArguments("--mac-signing-keychain", keychain.name())
|
||||
.addArguments(Stream.of(options).map(SignOption::args).flatMap(List::stream).toList())
|
||||
.setPackageType(type);
|
||||
|
||||
SignOption.configureOutputValidation(cmd, Stream.of(options).filter(SignOption::expired).toList(), opt -> {
|
||||
return JPackageStringBundle.MAIN.cannedFormattedString("error.certificate.expired", opt.identityName());
|
||||
}).execute(1);
|
||||
});
|
||||
}, MacSign.Keychain.UsageBuilder::addToSearchList, SigningBase.StandardKeychain.EXPIRED.keychain());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -148,39 +170,31 @@ public class MacSignTest {
|
||||
@Parameter({"MAC_PKG", "1", "GOOD_PKG_SIGN_IDENTITY"})
|
||||
public static void testMultipleCertificates(PackageType type, int jpackageExitCode, SignOption... options) {
|
||||
|
||||
final var keychain = SigningBase.StandardKeychain.DUPLICATE.spec().keychain();
|
||||
|
||||
MacSign.Keychain.withAddedKeychains(List.of(keychain), () -> {
|
||||
final var cmd = JPackageCommand.helloAppImage()
|
||||
MacSign.withKeychain(keychain -> {
|
||||
final var cmd = MacHelper.useKeychain(JPackageCommand.helloAppImage(), keychain)
|
||||
.ignoreDefaultVerbose(true)
|
||||
.addArguments("--mac-sign")
|
||||
.addArguments("--mac-signing-keychain", keychain.name())
|
||||
.addArguments(Stream.of(options).map(SignOption::args).flatMap(List::stream).toList())
|
||||
.setPackageType(type);
|
||||
|
||||
SignOption.configureOutputValidation(cmd, List.of(options), opt -> {
|
||||
return JPackageStringBundle.MAIN.cannedFormattedString("error.multiple.certs.found", opt.identityName(), keychain.name());
|
||||
}).execute(jpackageExitCode);
|
||||
});
|
||||
}, MacSign.Keychain.UsageBuilder::addToSearchList, SigningBase.StandardKeychain.DUPLICATE.keychain());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ParameterSupplier
|
||||
public static void testSelectSigningIdentity(String signingKeyUserName, CertificateRequest certRequest) {
|
||||
|
||||
final var keychain = SigningBase.StandardKeychain.MAIN.spec().keychain();
|
||||
|
||||
MacSign.Keychain.withAddedKeychains(List.of(keychain), () -> {
|
||||
final var cmd = JPackageCommand.helloAppImage()
|
||||
MacSign.withKeychain(keychain -> {
|
||||
final var cmd = MacHelper.useKeychain(JPackageCommand.helloAppImage(), keychain)
|
||||
.setFakeRuntime()
|
||||
.addArguments("--mac-sign")
|
||||
.addArguments("--mac-signing-keychain", keychain.name())
|
||||
.addArguments("--mac-signing-key-user-name", signingKeyUserName);
|
||||
|
||||
cmd.executeAndAssertHelloAppImageCreated();
|
||||
|
||||
MacSignVerify.assertSigned(cmd.outputBundle(), certRequest);
|
||||
});
|
||||
}, MacSign.Keychain.UsageBuilder::addToSearchList, SigningBase.StandardKeychain.MAIN.keychain());
|
||||
}
|
||||
|
||||
public static Collection<Object[]> testSelectSigningIdentity() {
|
||||
|
||||
@ -21,12 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer;
|
||||
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
import java.nio.file.Path;
|
||||
import jdk.jpackage.test.AdditionalLauncher;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.MacSign;
|
||||
|
||||
/**
|
||||
* Tests generation of app image with --mac-sign and related arguments. Test will
|
||||
@ -68,13 +70,19 @@ public class SigningAppImageTest {
|
||||
// Unsigned
|
||||
@Parameter({"false", "true", "INVALID_INDEX"})
|
||||
public void test(boolean doSign, boolean signingKey, SigningBase.CertIndex certEnum) throws Exception {
|
||||
MacSign.withKeychain(toConsumer(keychain -> {
|
||||
test(keychain, doSign, signingKey, certEnum);
|
||||
}), SigningBase.StandardKeychain.MAIN.keychain());
|
||||
}
|
||||
|
||||
private void test(MacSign.ResolvedKeychain keychain, boolean doSign, boolean signingKey, SigningBase.CertIndex certEnum) throws Exception {
|
||||
final var certIndex = certEnum.value();
|
||||
|
||||
JPackageCommand cmd = JPackageCommand.helloAppImage();
|
||||
if (doSign) {
|
||||
cmd.addArguments("--mac-sign",
|
||||
"--mac-signing-keychain",
|
||||
SigningBase.getKeyChain());
|
||||
keychain.name());
|
||||
if (signingKey) {
|
||||
cmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(certIndex));
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,14 +21,16 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer;
|
||||
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.TKit;
|
||||
import jdk.jpackage.test.PackageType;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
import java.nio.file.Path;
|
||||
import jdk.jpackage.test.AdditionalLauncher;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.MacSign;
|
||||
import jdk.jpackage.test.PackageType;
|
||||
import jdk.jpackage.test.TKit;
|
||||
|
||||
/**
|
||||
* Tests generation of app image and then signs generated app image with --mac-sign
|
||||
@ -67,6 +69,12 @@ public class SigningAppImageTwoStepsTest {
|
||||
// Unsigned
|
||||
@Parameter({"false", "true"})
|
||||
public void test(boolean signAppImage, boolean signingKey) throws Exception {
|
||||
MacSign.withKeychain(toConsumer(keychain -> {
|
||||
test(keychain, signAppImage, signingKey);
|
||||
}), SigningBase.StandardKeychain.MAIN.keychain());
|
||||
}
|
||||
|
||||
private static void test(MacSign.ResolvedKeychain keychain, boolean signAppImage, boolean signingKey) throws Exception {
|
||||
|
||||
Path appimageOutput = TKit.createTempDirectory("appimage");
|
||||
|
||||
@ -78,7 +86,7 @@ public class SigningAppImageTwoStepsTest {
|
||||
if (signAppImage) {
|
||||
appImageCmd.addArguments("--mac-sign",
|
||||
"--mac-signing-keychain",
|
||||
SigningBase.getKeyChain());
|
||||
keychain.name());
|
||||
if (signingKey) {
|
||||
appImageCmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX));
|
||||
@ -103,7 +111,7 @@ public class SigningAppImageTwoStepsTest {
|
||||
cmd.setPackageType(PackageType.IMAGE)
|
||||
.addArguments("--app-image", appImageCmd.outputBundle().toAbsolutePath())
|
||||
.addArguments("--mac-sign")
|
||||
.addArguments("--mac-signing-keychain", SigningBase.getKeyChain());
|
||||
.addArguments("--mac-signing-keychain", keychain.name());
|
||||
if (signingKey) {
|
||||
cmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX));
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,15 +21,18 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.ApplicationLayout;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.TKit;
|
||||
import jdk.jpackage.test.MacHelper;
|
||||
import jdk.jpackage.test.MacSign;
|
||||
import jdk.jpackage.test.PackageTest;
|
||||
import jdk.jpackage.test.PackageType;
|
||||
import jdk.jpackage.test.MacHelper;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
import jdk.jpackage.test.TKit;
|
||||
|
||||
/**
|
||||
* Tests generation of dmg and pkg from signed predefined app image which was
|
||||
@ -102,6 +105,12 @@ public class SigningPackageFromTwoStepAppImageTest {
|
||||
// Unsigned
|
||||
@Parameter({"false", "true"})
|
||||
public void test(boolean signAppImage, boolean signingKey) throws Exception {
|
||||
MacSign.withKeychain(toConsumer(keychain -> {
|
||||
test(keychain, signAppImage, signingKey);
|
||||
}), SigningBase.StandardKeychain.MAIN.keychain());
|
||||
}
|
||||
|
||||
private void test(MacSign.ResolvedKeychain keychain, boolean signAppImage, boolean signingKey) throws Exception {
|
||||
|
||||
Path appimageOutput = TKit.createTempDirectory("appimage");
|
||||
|
||||
@ -112,7 +121,7 @@ public class SigningPackageFromTwoStepAppImageTest {
|
||||
.setArgumentValue("--dest", appimageOutput);
|
||||
if (signAppImage) {
|
||||
appImageCmd.addArguments("--mac-sign",
|
||||
"--mac-signing-keychain", SigningBase.getKeyChain());
|
||||
"--mac-signing-keychain", keychain.name());
|
||||
if (signingKey) {
|
||||
appImageCmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX));
|
||||
@ -133,7 +142,7 @@ public class SigningPackageFromTwoStepAppImageTest {
|
||||
appImageSignedCmd.setPackageType(PackageType.IMAGE)
|
||||
.addArguments("--app-image", appImageCmd.outputBundle().toAbsolutePath())
|
||||
.addArguments("--mac-sign")
|
||||
.addArguments("--mac-signing-keychain", SigningBase.getKeyChain());
|
||||
.addArguments("--mac-signing-keychain", keychain.name());
|
||||
if (signingKey) {
|
||||
appImageSignedCmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX));
|
||||
@ -154,7 +163,7 @@ public class SigningPackageFromTwoStepAppImageTest {
|
||||
if (signAppImage) {
|
||||
cmd.addArguments("--mac-sign",
|
||||
"--mac-signing-keychain",
|
||||
SigningBase.getKeyChain());
|
||||
keychain.name());
|
||||
if (signingKey) {
|
||||
cmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX));
|
||||
|
||||
@ -21,14 +21,17 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.ApplicationLayout;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.MacHelper;
|
||||
import jdk.jpackage.test.MacSign;
|
||||
import jdk.jpackage.test.PackageTest;
|
||||
import jdk.jpackage.test.PackageType;
|
||||
import jdk.jpackage.test.MacHelper;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
|
||||
/**
|
||||
* Tests generation of dmg and pkg with --mac-sign and related arguments.
|
||||
@ -144,6 +147,12 @@ public class SigningPackageTest {
|
||||
// Signing-indentity, but sign pkg only and UNICODE certificate
|
||||
@Parameter({"false", "false", "true", "UNICODE_INDEX"})
|
||||
public static void test(boolean signingKey, boolean signAppImage, boolean signPKG, SigningBase.CertIndex certEnum) throws Exception {
|
||||
MacSign.withKeychain(toConsumer(keychain -> {
|
||||
test(keychain, signingKey, signAppImage, signPKG, certEnum);
|
||||
}), SigningBase.StandardKeychain.MAIN.keychain());
|
||||
}
|
||||
|
||||
private static void test(MacSign.ResolvedKeychain keychain, boolean signingKey, boolean signAppImage, boolean signPKG, SigningBase.CertIndex certEnum) throws Exception {
|
||||
final var certIndex = certEnum.value();
|
||||
|
||||
new PackageTest()
|
||||
@ -151,7 +160,7 @@ public class SigningPackageTest {
|
||||
.forTypes(PackageType.MAC)
|
||||
.addInitializer(cmd -> {
|
||||
cmd.addArguments("--mac-sign",
|
||||
"--mac-signing-keychain", SigningBase.getKeyChain());
|
||||
"--mac-signing-keychain", keychain.name());
|
||||
if (signingKey) {
|
||||
cmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(certIndex));
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,31 +21,39 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import jdk.jpackage.test.ApplicationLayout;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.jpackage.test.Annotations.ParameterSupplier;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.TKit;
|
||||
import jdk.jpackage.test.JPackageStringBundle;
|
||||
import jdk.jpackage.test.MacHelper;
|
||||
import jdk.jpackage.test.MacHelper.SignKeyOption;
|
||||
import jdk.jpackage.test.MacSign;
|
||||
import jdk.jpackage.test.MacSignVerify;
|
||||
import jdk.jpackage.test.PackageFile;
|
||||
import jdk.jpackage.test.PackageTest;
|
||||
import jdk.jpackage.test.PackageType;
|
||||
import jdk.jpackage.test.MacHelper;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
import jdk.jpackage.test.TKit;
|
||||
|
||||
/**
|
||||
* Note: Testing unsgined app image is done to verify support for per-user
|
||||
* configuration by checking for PackageFile.
|
||||
* Tests generation of dmg and pkg from signed or unsigned predefined app image.
|
||||
* Test will generate pkg and verifies its signature. It verifies that dmg
|
||||
* is not signed, but app image inside dmg is signed or unsigned. This test
|
||||
* requires that the machine is configured with test certificate for
|
||||
* "Developer ID Installer: jpackage.openjdk.java.net" in
|
||||
* jpackagerTest keychain with
|
||||
* always allowed access to this keychain for user which runs test.
|
||||
* note:
|
||||
* "jpackage.openjdk.java.net" can be over-ridden by system property
|
||||
* "jpackage.mac.signing.key.user.name", and
|
||||
* "jpackagerTest" can be over-ridden by system property
|
||||
* "jpackage.mac.signing.keychain"
|
||||
* Tests packaging of a signed/unsigned predefined app image into a
|
||||
* signed/unsigned .pkg or .dmg package.
|
||||
*
|
||||
* <p>
|
||||
* Prerequisites: A keychain with self-signed certificates as specified in
|
||||
* {@link SigningBase.StandardKeychain#MAIN}.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -64,100 +72,180 @@ import jdk.jpackage.test.Annotations.Parameter;
|
||||
*/
|
||||
public class SigningPackageTwoStepTest {
|
||||
|
||||
private static void verifyPKG(JPackageCommand cmd) {
|
||||
if (!cmd.hasArgument("--mac-sign")) {
|
||||
return; // Nothing to check if not signed
|
||||
}
|
||||
|
||||
Path outputBundle = cmd.outputBundle();
|
||||
SigningBase.verifyPkgutil(outputBundle, true, SigningBase.DEFAULT_INDEX);
|
||||
SigningBase.verifySpctl(outputBundle, "install", SigningBase.DEFAULT_INDEX);
|
||||
}
|
||||
|
||||
private static void verifyDMG(JPackageCommand cmd) {
|
||||
// DMG always unsigned, so we will check it
|
||||
Path outputBundle = cmd.outputBundle();
|
||||
SigningBase.verifyDMG(outputBundle);
|
||||
}
|
||||
|
||||
private static void verifyAppImageInDMG(JPackageCommand cmd) {
|
||||
MacHelper.withExplodedDmg(cmd, dmgImage -> {
|
||||
// We will be called with all folders in DMG since JDK-8263155, but
|
||||
// we only need to verify app.
|
||||
if (dmgImage.endsWith(cmd.name() + ".app")) {
|
||||
boolean isSigned = cmd.hasArgument("--mac-sign");
|
||||
Path launcherPath = ApplicationLayout.platformAppImage()
|
||||
.resolveAt(dmgImage).launchersDirectory().resolve(cmd.name());
|
||||
SigningBase.verifyCodesign(launcherPath, isSigned, SigningBase.DEFAULT_INDEX);
|
||||
SigningBase.verifyCodesign(dmgImage, isSigned, SigningBase.DEFAULT_INDEX);
|
||||
if (isSigned) {
|
||||
SigningBase.verifySpctl(dmgImage, "exec", SigningBase.DEFAULT_INDEX);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
// (Signed, "signing-key or sign-identity"})
|
||||
// Signed and signing-key
|
||||
@Parameter({"true", "true"})
|
||||
// Signed and signing-identity
|
||||
@Parameter({"true", "false"})
|
||||
// Unsigned
|
||||
@Parameter({"false", "true"})
|
||||
public static void test(boolean signAppImage, boolean signingKey) throws Exception {
|
||||
Path appimageOutput = TKit.createTempDirectory("appimage");
|
||||
@ParameterSupplier
|
||||
public static void test(TestSpec spec) {
|
||||
MacSign.withKeychain(toConsumer(keychain -> {
|
||||
spec.test(keychain);
|
||||
}), SigningBase.StandardKeychain.MAIN.keychain());
|
||||
}
|
||||
|
||||
JPackageCommand appImageCmd = JPackageCommand.helloAppImage()
|
||||
.setArgumentValue("--dest", appimageOutput);
|
||||
if (signAppImage) {
|
||||
appImageCmd.addArguments("--mac-sign")
|
||||
.addArguments("--mac-signing-keychain",
|
||||
SigningBase.getKeyChain());
|
||||
if (signingKey) {
|
||||
appImageCmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX));
|
||||
} else {
|
||||
appImageCmd.addArguments("--mac-app-image-sign-identity",
|
||||
SigningBase.getAppCert(SigningBase.DEFAULT_INDEX));
|
||||
public record TestSpec(Optional<SignKeyOption> signAppImage, Map<PackageType, SignKeyOption> signPackage) {
|
||||
|
||||
public TestSpec {
|
||||
Objects.requireNonNull(signAppImage);
|
||||
Objects.requireNonNull(signPackage);
|
||||
|
||||
if ((signAppImage.isEmpty() && signPackage.isEmpty()) || !PackageType.MAC.containsAll(signPackage.keySet())) {
|
||||
// Unexpected package types.
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
// Ensure stable result of toString() call.
|
||||
if (!SortedMap.class.isInstance(signPackage)) {
|
||||
signPackage = new TreeMap<>(signPackage);
|
||||
}
|
||||
}
|
||||
|
||||
new PackageTest()
|
||||
.addRunOnceInitializer(() -> appImageCmd.execute())
|
||||
.forTypes(PackageType.MAC)
|
||||
.addInitializer(cmd -> {
|
||||
cmd.addArguments("--app-image", appImageCmd.outputBundle());
|
||||
cmd.removeArgumentWithValue("--input");
|
||||
if (signAppImage) {
|
||||
cmd.addArguments("--mac-sign",
|
||||
"--mac-signing-keychain",
|
||||
SigningBase.getKeyChain());
|
||||
if (signingKey) {
|
||||
cmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX));
|
||||
} else {
|
||||
cmd.addArguments("--mac-installer-sign-identity",
|
||||
SigningBase.getInstallerCert(SigningBase.DEFAULT_INDEX));
|
||||
}
|
||||
}
|
||||
})
|
||||
.forTypes(PackageType.MAC_PKG)
|
||||
.addBundleVerifier(SigningPackageTwoStepTest::verifyPKG)
|
||||
.forTypes(PackageType.MAC_DMG)
|
||||
.addInitializer(cmd -> {
|
||||
if (signAppImage && !signingKey) {
|
||||
// jpackage throws expected error with
|
||||
// --mac-installer-sign-identity and DMG type
|
||||
cmd.removeArgumentWithValue("--mac-installer-sign-identity");
|
||||
// It will do nothing, but it signals test that app
|
||||
// image itself is signed for verification.
|
||||
cmd.addArguments("--mac-app-image-sign-identity",
|
||||
SigningBase.getAppCert(SigningBase.DEFAULT_INDEX));
|
||||
}
|
||||
})
|
||||
.addBundleVerifier(SigningPackageTwoStepTest::verifyDMG)
|
||||
.addBundleVerifier(SigningPackageTwoStepTest::verifyAppImageInDMG)
|
||||
.run();
|
||||
@Override
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
|
||||
signAppImage.ifPresent(signOption -> {
|
||||
sb.append(String.format("app-image=%s", signOption));
|
||||
});
|
||||
|
||||
if (!sb.isEmpty() && !signPackage.isEmpty()) {
|
||||
sb.append("; ");
|
||||
}
|
||||
|
||||
if (!signPackage.isEmpty()) {
|
||||
sb.append(signPackage);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
boolean signNativeBundle() {
|
||||
return signPackage.isEmpty();
|
||||
}
|
||||
|
||||
static Builder build() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
static class Builder {
|
||||
|
||||
TestSpec create() {
|
||||
return new TestSpec(Optional.ofNullable(signAppImage), signPackage);
|
||||
}
|
||||
|
||||
Builder certRequest(SigningBase.StandardCertificateRequest v) {
|
||||
return certRequest(v.spec());
|
||||
}
|
||||
|
||||
Builder certRequest(MacSign.CertificateRequest v) {
|
||||
certRequest = Objects.requireNonNull(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder signIdentityType(SignKeyOption.Type v) {
|
||||
signIdentityType = Objects.requireNonNull(v);
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder signAppImage() {
|
||||
signAppImage = createSignKeyOption();
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder signPackage(PackageType type) {
|
||||
Objects.requireNonNull(type);
|
||||
signPackage.put(type, createSignKeyOption());
|
||||
return this;
|
||||
}
|
||||
|
||||
Builder signPackage() {
|
||||
PackageType.MAC.forEach(this::signPackage);
|
||||
return this;
|
||||
}
|
||||
|
||||
private SignKeyOption createSignKeyOption() {
|
||||
return new SignKeyOption(signIdentityType, certRequest);
|
||||
}
|
||||
|
||||
private MacSign.CertificateRequest certRequest = SigningBase.StandardCertificateRequest.CODESIGN.spec();
|
||||
private SignKeyOption.Type signIdentityType = SignKeyOption.Type.SIGN_KEY_IDENTITY;
|
||||
|
||||
private SignKeyOption signAppImage;
|
||||
private Map<PackageType, SignKeyOption> signPackage = new HashMap<>();
|
||||
}
|
||||
|
||||
void test(MacSign.ResolvedKeychain keychain) {
|
||||
|
||||
var appImageCmd = JPackageCommand.helloAppImage().setFakeRuntime();
|
||||
MacHelper.useKeychain(appImageCmd, keychain);
|
||||
signAppImage.ifPresent(signOption -> {
|
||||
signOption.setTo(appImageCmd);
|
||||
});
|
||||
|
||||
var test = new PackageTest();
|
||||
|
||||
signAppImage.map(SignKeyOption::certRequest).ifPresent(certRequest -> {
|
||||
// The predefined app image is signed, verify bundled app image is signed too.
|
||||
test.addInstallVerifier(cmd -> {
|
||||
MacSignVerify.verifyAppImageSigned(cmd, certRequest, keychain);
|
||||
});
|
||||
});
|
||||
|
||||
Optional.ofNullable(signPackage.get(PackageType.MAC_PKG)).map(SignKeyOption::certRequest).ifPresent(certRequest -> {
|
||||
test.forTypes(PackageType.MAC_PKG, () -> {
|
||||
test.addBundleVerifier(cmd -> {
|
||||
MacSignVerify.verifyPkgSigned(cmd, certRequest, keychain);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.forTypes(signPackage.keySet()).addRunOnceInitializer(() -> {
|
||||
appImageCmd.setArgumentValue("--dest", TKit.createTempDirectory("appimage")).execute(0);
|
||||
}).addInitializer(cmd -> {
|
||||
MacHelper.useKeychain(cmd, keychain);
|
||||
cmd.addArguments("--app-image", appImageCmd.outputBundle());
|
||||
cmd.removeArgumentWithValue("--input");
|
||||
Optional.ofNullable(signPackage.get(cmd.packageType())).ifPresent(signOption -> {
|
||||
signOption.setTo(cmd);
|
||||
});
|
||||
|
||||
if (signAppImage.isPresent()) {
|
||||
// Predefined app image is signed. Expect a warning.
|
||||
cmd.validateOutput(JPackageStringBundle.MAIN.cannedFormattedString(
|
||||
"warning.per.user.app.image.signed",
|
||||
PackageFile.getPathInAppImage(Path.of(""))));
|
||||
} else if (cmd.packageType() == PackageType.MAC_PKG && signPackage.containsKey(cmd.packageType())) {
|
||||
// Create signed ".pkg" bundle from the unsigned predefined app image. Expect a warning.
|
||||
cmd.validateOutput(JPackageStringBundle.MAIN.cannedFormattedString("warning.unsigned.app.image", "pkg"));
|
||||
}
|
||||
})
|
||||
.run();
|
||||
}
|
||||
}
|
||||
|
||||
public static Collection<Object[]> test() {
|
||||
|
||||
List<TestSpec.Builder> data = new ArrayList<>();
|
||||
|
||||
Stream.of(SignKeyOption.Type.values()).flatMap(signIdentityType -> {
|
||||
return Stream.of(
|
||||
// Sign both predefined app image and native package.
|
||||
TestSpec.build().signIdentityType(signIdentityType)
|
||||
.signAppImage()
|
||||
.signPackage()
|
||||
.certRequest(SigningBase.StandardCertificateRequest.PKG)
|
||||
.signPackage(PackageType.MAC_PKG),
|
||||
|
||||
// Don't sign predefined app image, sign native package.
|
||||
TestSpec.build().signIdentityType(signIdentityType)
|
||||
.signPackage()
|
||||
.certRequest(SigningBase.StandardCertificateRequest.PKG)
|
||||
.signPackage(PackageType.MAC_PKG),
|
||||
|
||||
// Sign predefined app image, don't sign native package.
|
||||
TestSpec.build().signIdentityType(signIdentityType).signAppImage()
|
||||
);
|
||||
}).forEach(data::add);
|
||||
|
||||
return data.stream().map(TestSpec.Builder::create).map(v -> {
|
||||
return new Object[] {v};
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,51 +21,53 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.jpackage.test.Annotations.Parameter;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.Executor;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.MacHelper;
|
||||
import jdk.jpackage.test.MacSign;
|
||||
import jdk.jpackage.test.PackageTest;
|
||||
import jdk.jpackage.test.PackageType;
|
||||
import jdk.jpackage.test.TKit;
|
||||
|
||||
/**
|
||||
* Tests generation of dmg and pkg with --mac-sign and related arguments.
|
||||
* Test will generate pkg and verifies its signature. It verifies that dmg
|
||||
* is not signed, but runtime image inside dmg is signed.
|
||||
* Tests generation of dmg and pkg with --mac-sign and related arguments. Test
|
||||
* will generate pkg and verifies its signature. It verifies that dmg is not
|
||||
* signed, but runtime image inside dmg is signed.
|
||||
*
|
||||
* Note: Specific UNICODE signing is not tested, since it is shared code
|
||||
* with app image signing and it will be covered by SigningPackageTest.
|
||||
* <p>
|
||||
* Note: Specific UNICODE signing is not tested, since it is shared code with
|
||||
* app image signing and it will be covered by SigningPackageTest.
|
||||
*
|
||||
* <p>
|
||||
* Following combinations are tested:
|
||||
* 1) "--runtime-image" points to unsigned JDK bundle and --mac-sign is not
|
||||
* <ol>
|
||||
* <li>"--runtime-image" points to unsigned JDK bundle and --mac-sign is not
|
||||
* provided. Expected result: runtime image ad-hoc signed.
|
||||
* 2) "--runtime-image" points to unsigned JDK bundle and --mac-sign is
|
||||
* <li>"--runtime-image" points to unsigned JDK bundle and --mac-sign is
|
||||
* provided. Expected result: Everything is signed with provided certificate.
|
||||
* 3) "--runtime-image" points to signed JDK bundle and --mac-sign is not
|
||||
* <li>"--runtime-image" points to signed JDK bundle and --mac-sign is not
|
||||
* provided. Expected result: runtime image is signed with original certificate.
|
||||
* 4) "--runtime-image" points to signed JDK bundle and --mac-sign is provided.
|
||||
* <li>"--runtime-image" points to signed JDK bundle and --mac-sign is provided.
|
||||
* Expected result: runtime image is signed with provided certificate.
|
||||
* 5) "--runtime-image" points to JDK image and --mac-sign is not provided.
|
||||
* <li>"--runtime-image" points to JDK image and --mac-sign is not provided.
|
||||
* Expected result: runtime image ad-hoc signed.
|
||||
* 6) "--runtime-image" points to JDK image and --mac-sign is provided.
|
||||
* <li>"--runtime-image" points to JDK image and --mac-sign is provided.
|
||||
* Expected result: Everything is signed with provided certificate.
|
||||
* </ol>
|
||||
*
|
||||
* This test requires that the machine is configured with test certificate for
|
||||
* "Developer ID Installer: jpackage.openjdk.java.net" in
|
||||
* jpackagerTest keychain with
|
||||
* always allowed access to this keychain for user which runs test.
|
||||
* note:
|
||||
* "Developer ID Installer: jpackage.openjdk.java.net" in jpackagerTest keychain
|
||||
* with always allowed access to this keychain for user which runs test. note:
|
||||
* "jpackage.openjdk.java.net" can be over-ridden by system property
|
||||
* "jpackage.mac.signing.key.user.name", and
|
||||
* "jpackagerTest" can be over-ridden by system property
|
||||
* "jpackage.mac.signing.keychain"
|
||||
* "jpackage.mac.signing.key.user.name"
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -84,17 +86,17 @@ import jdk.jpackage.test.TKit;
|
||||
*/
|
||||
public class SigningRuntimeImagePackageTest {
|
||||
|
||||
private static JPackageCommand addSignOptions(JPackageCommand cmd, int certIndex) {
|
||||
private static JPackageCommand addSignOptions(JPackageCommand cmd, MacSign.ResolvedKeychain keychain, int certIndex) {
|
||||
if (certIndex != SigningBase.CertIndex.INVALID_INDEX.value()) {
|
||||
cmd.addArguments(
|
||||
"--mac-sign",
|
||||
"--mac-signing-keychain", SigningBase.getKeyChain(),
|
||||
"--mac-signing-keychain", keychain.name(),
|
||||
"--mac-signing-key-user-name", SigningBase.getDevName(certIndex));
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
private static Path createInputRuntimeBundle(int certIndex) throws IOException {
|
||||
private static Path createInputRuntimeBundle(MacSign.ResolvedKeychain keychain, int certIndex) throws IOException {
|
||||
|
||||
final var runtimeImage = JPackageCommand.createInputRuntimeImage();
|
||||
|
||||
@ -111,7 +113,7 @@ public class SigningRuntimeImagePackageTest {
|
||||
.addArguments("--runtime-image", runtimeImage)
|
||||
.addArguments("--dest", runtimeBundleWorkDir);
|
||||
|
||||
addSignOptions(cmd, certIndex);
|
||||
addSignOptions(cmd, keychain, certIndex);
|
||||
|
||||
cmd.execute();
|
||||
|
||||
@ -147,13 +149,21 @@ public class SigningRuntimeImagePackageTest {
|
||||
public static void test(boolean useJDKBundle,
|
||||
SigningBase.CertIndex jdkBundleCert,
|
||||
SigningBase.CertIndex signCert) throws Exception {
|
||||
MacSign.withKeychain(toConsumer(keychain -> {
|
||||
test(keychain, useJDKBundle, jdkBundleCert, signCert);
|
||||
}), SigningBase.StandardKeychain.MAIN.keychain());
|
||||
}
|
||||
|
||||
private static void test(MacSign.ResolvedKeychain keychain, boolean useJDKBundle,
|
||||
SigningBase.CertIndex jdkBundleCert,
|
||||
SigningBase.CertIndex signCert) throws Exception {
|
||||
|
||||
final Path inputRuntime[] = new Path[1];
|
||||
|
||||
new PackageTest()
|
||||
.addRunOnceInitializer(() -> {
|
||||
if (useJDKBundle) {
|
||||
inputRuntime[0] = createInputRuntimeBundle(jdkBundleCert.value());
|
||||
inputRuntime[0] = createInputRuntimeBundle(keychain, jdkBundleCert.value());
|
||||
} else {
|
||||
inputRuntime[0] = JPackageCommand.createInputRuntimeImage();
|
||||
}
|
||||
@ -164,7 +174,7 @@ public class SigningRuntimeImagePackageTest {
|
||||
// create input directory in the test and jpackage fails
|
||||
// if --input references non existent directory.
|
||||
cmd.removeArgumentWithValue("--input");
|
||||
addSignOptions(cmd, signCert.value());
|
||||
addSignOptions(cmd, keychain, signCert.value());
|
||||
})
|
||||
.addInstallVerifier(cmd -> {
|
||||
final var certIndex = Stream.of(signCert, jdkBundleCert)
|
||||
|
||||
@ -90,17 +90,29 @@ public class SigningBase {
|
||||
private final CertificateRequest spec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard keychains used in signing tests.
|
||||
*/
|
||||
public enum StandardKeychain {
|
||||
MAIN(DEFAULT_KEYCHAIN,
|
||||
/**
|
||||
* The primary keychain with good certificates.
|
||||
*/
|
||||
MAIN("jpackagerTest.keychain",
|
||||
StandardCertificateRequest.CODESIGN,
|
||||
StandardCertificateRequest.PKG,
|
||||
StandardCertificateRequest.CODESIGN_UNICODE,
|
||||
StandardCertificateRequest.PKG_UNICODE),
|
||||
/**
|
||||
* A keychain with some good and some expired certificates.
|
||||
*/
|
||||
EXPIRED("jpackagerTest-expired.keychain",
|
||||
StandardCertificateRequest.CODESIGN,
|
||||
StandardCertificateRequest.PKG,
|
||||
StandardCertificateRequest.CODESIGN_EXPIRED,
|
||||
StandardCertificateRequest.PKG_EXPIRED),
|
||||
/**
|
||||
* A keychain with duplicated certificates.
|
||||
*/
|
||||
DUPLICATE("jpackagerTest-duplicate.keychain",
|
||||
StandardCertificateRequest.CODESIGN,
|
||||
StandardCertificateRequest.PKG,
|
||||
@ -114,30 +126,26 @@ public class SigningBase {
|
||||
StandardKeychain(String keychainName, CertificateRequest cert, CertificateRequest... otherCerts) {
|
||||
final var builder = keychain(keychainName).addCert(cert);
|
||||
List.of(otherCerts).forEach(builder::addCert);
|
||||
this.spec = new ResolvedKeychain(builder.create());
|
||||
this.keychain = new ResolvedKeychain(builder.create());
|
||||
}
|
||||
|
||||
public KeychainWithCertsSpec spec() {
|
||||
return spec.spec();
|
||||
public ResolvedKeychain keychain() {
|
||||
return keychain;
|
||||
}
|
||||
|
||||
public X509Certificate mapCertificateRequest(CertificateRequest certRequest) {
|
||||
return Objects.requireNonNull(spec.mapCertificateRequests().get(certRequest));
|
||||
return Objects.requireNonNull(keychain.mapCertificateRequests().get(certRequest));
|
||||
}
|
||||
|
||||
private static KeychainWithCertsSpec.Builder keychain(String name) {
|
||||
return new KeychainWithCertsSpec.Builder().name(name);
|
||||
}
|
||||
|
||||
private static CertificateRequest.Builder cert() {
|
||||
return new CertificateRequest.Builder();
|
||||
}
|
||||
|
||||
private static List<KeychainWithCertsSpec> signingEnv() {
|
||||
return Stream.of(values()).map(StandardKeychain::spec).toList();
|
||||
return Stream.of(values()).map(StandardKeychain::keychain).map(ResolvedKeychain::spec).toList();
|
||||
}
|
||||
|
||||
private final ResolvedKeychain spec;
|
||||
private final ResolvedKeychain keychain;
|
||||
}
|
||||
|
||||
public static void setUp() {
|
||||
@ -179,7 +187,6 @@ public class SigningBase {
|
||||
"jpackage.openjdk.java.net",
|
||||
"jpackage.openjdk.java.net (ö)",
|
||||
};
|
||||
private static String DEFAULT_KEYCHAIN = "jpackagerTest.keychain";
|
||||
|
||||
public static String getDevName(int certIndex) {
|
||||
// Always use values from system properties if set
|
||||
@ -195,16 +202,6 @@ public class SigningBase {
|
||||
return Arrays.binarySearch(DEV_NAMES, devName);
|
||||
}
|
||||
|
||||
// Returns 'true' if dev name from DEV_NAMES
|
||||
public static boolean isDevNameDefault() {
|
||||
String value = System.getProperty("jpackage.mac.signing.key.user.name");
|
||||
if (value != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static String getAppCert(int certIndex) {
|
||||
return "Developer ID Application: " + getDevName(certIndex);
|
||||
}
|
||||
@ -213,16 +210,6 @@ public class SigningBase {
|
||||
return "Developer ID Installer: " + getDevName(certIndex);
|
||||
}
|
||||
|
||||
public static String getKeyChain() {
|
||||
// Always use values from system properties if set
|
||||
String value = System.getProperty("jpackage.mac.signing.keychain");
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return DEFAULT_KEYCHAIN;
|
||||
}
|
||||
|
||||
public static void verifyCodesign(Path target, boolean signed, int certIndex) {
|
||||
if (signed) {
|
||||
final var certRequest = getCertRequest(certIndex);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user