8311877: [macos] Add CLI options to provide signing identity directly to codesign and productbuild
Reviewed-by: asemenyuk
This commit is contained in:
parent
9c819fd3b7
commit
f1dfdc1a79
@ -85,6 +85,13 @@ public class MacAppBundler extends AppImageBundler {
|
||||
},
|
||||
(s, p) -> s);
|
||||
|
||||
public static final BundlerParamInfo<String> APP_IMAGE_SIGN_IDENTITY =
|
||||
new StandardBundlerParam<>(
|
||||
Arguments.CLIOptions.MAC_APP_IMAGE_SIGN_IDENTITY.getId(),
|
||||
String.class,
|
||||
params -> "",
|
||||
null);
|
||||
|
||||
public static final BundlerParamInfo<String> BUNDLE_ID_SIGNING_PREFIX =
|
||||
new StandardBundlerParam<>(
|
||||
Arguments.CLIOptions.MAC_BUNDLE_SIGNING_PREFIX.getId(),
|
||||
@ -127,6 +134,9 @@ public class MacAppBundler extends AppImageBundler {
|
||||
// reject explicitly set sign to true and no valid signature key
|
||||
if (Optional.ofNullable(
|
||||
SIGN_BUNDLE.fetchFrom(params)).orElse(Boolean.FALSE)) {
|
||||
// Validate DEVELOPER_ID_APP_SIGNING_KEY only if user provided
|
||||
// SIGNING_KEY_USER.
|
||||
if (!SIGNING_KEY_USER.getIsDefaultValue(params)) { // --mac-signing-key-user-name
|
||||
String signingIdentity =
|
||||
DEVELOPER_ID_APP_SIGNING_KEY.fetchFrom(params);
|
||||
if (signingIdentity == null) {
|
||||
@ -134,6 +144,10 @@ public class MacAppBundler extends AppImageBundler {
|
||||
I18N.getString("error.explicit-sign-no-cert"),
|
||||
I18N.getString("error.explicit-sign-no-cert.advice"));
|
||||
}
|
||||
}
|
||||
|
||||
// No need to validate --mac-app-image-sign-identity, since it is
|
||||
// pass through option.
|
||||
|
||||
// Signing will not work without Xcode with command line developer tools
|
||||
try {
|
||||
|
@ -25,8 +25,10 @@
|
||||
|
||||
package jdk.jpackage.internal;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -53,7 +55,10 @@ import jdk.internal.util.OperatingSystem;
|
||||
import jdk.internal.util.OSVersion;
|
||||
import static jdk.jpackage.internal.MacAppBundler.BUNDLE_ID_SIGNING_PREFIX;
|
||||
import static jdk.jpackage.internal.MacAppBundler.DEVELOPER_ID_APP_SIGNING_KEY;
|
||||
import static jdk.jpackage.internal.MacAppBundler.APP_IMAGE_SIGN_IDENTITY;
|
||||
import static jdk.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEYCHAIN;
|
||||
import static jdk.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEY_USER;
|
||||
import static jdk.jpackage.internal.MacBaseInstallerBundler.INSTALLER_SIGN_IDENTITY;
|
||||
import static jdk.jpackage.internal.OverridableResource.createResource;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.CONFIG_ROOT;
|
||||
@ -395,12 +400,25 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
||||
} catch (InterruptedException e) {
|
||||
Log.error(e.getMessage());
|
||||
}
|
||||
String signingIdentity =
|
||||
DEVELOPER_ID_APP_SIGNING_KEY.fetchFrom(params);
|
||||
String signingIdentity = null;
|
||||
// Try --mac-app-image-sign-identity first if set
|
||||
if (!APP_IMAGE_SIGN_IDENTITY.getIsDefaultValue(params)) {
|
||||
signingIdentity = APP_IMAGE_SIGN_IDENTITY.fetchFrom(params);
|
||||
} else {
|
||||
// Check if INSTALLER_SIGN_IDENTITY is set and if it is set
|
||||
// then do not sign app image, otherwise use --mac-signing-key-user-name
|
||||
if (INSTALLER_SIGN_IDENTITY.getIsDefaultValue(params)) {
|
||||
// --mac-sign and/or --mac-signing-key-user-name case
|
||||
signingIdentity = DEVELOPER_ID_APP_SIGNING_KEY.fetchFrom(params);
|
||||
}
|
||||
}
|
||||
if (signingIdentity != null) {
|
||||
signAppBundle(params, root, signingIdentity,
|
||||
BUNDLE_ID_SIGNING_PREFIX.fetchFrom(params),
|
||||
ENTITLEMENTS.fetchFrom(params));
|
||||
} else {
|
||||
// Case when user requested to sign installer only
|
||||
signAppBundle(params, root, "-", null, null);
|
||||
}
|
||||
restoreKeychainList(params);
|
||||
} else if (OperatingSystem.isMacOS()) {
|
||||
@ -715,6 +733,25 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
||||
return args;
|
||||
}
|
||||
|
||||
private static void runCodesign(ProcessBuilder pb, boolean quiet)
|
||||
throws IOException {
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PrintStream ps = new PrintStream(baos)) {
|
||||
try {
|
||||
IOUtils.exec(pb, false, ps, false,
|
||||
Executor.INFINITE_TIMEOUT, quiet);
|
||||
} catch (IOException ioe) {
|
||||
// Log output of "codesign" in case of
|
||||
// error. It should help user to diagnose
|
||||
// issue when using --mac-app-image-sign-identity
|
||||
Log.info(MessageFormat.format(I18N.getString(
|
||||
"error.tool.failed.with.output"), "codesign"));
|
||||
Log.info(baos.toString().strip());
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void signAppBundle(
|
||||
Map<String, ? super Object> params, Path appLocation,
|
||||
String signingIdentity, String identifierPrefix, Path entitlements)
|
||||
@ -781,8 +818,7 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
||||
p.toFile().setWritable(true, true);
|
||||
ProcessBuilder pb = new ProcessBuilder(args);
|
||||
// run quietly
|
||||
IOUtils.exec(pb, false, null, false,
|
||||
Executor.INFINITE_TIMEOUT, true);
|
||||
runCodesign(pb, true);
|
||||
Files.setPosixFilePermissions(p, oldPermissions);
|
||||
} catch (IOException ioe) {
|
||||
toThrow.set(ioe);
|
||||
@ -810,8 +846,7 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
||||
List<String> args = getCodesignArgs(true, path, signingIdentity,
|
||||
identifierPrefix, entitlements, keyChain);
|
||||
ProcessBuilder pb = new ProcessBuilder(args);
|
||||
|
||||
IOUtils.exec(pb);
|
||||
runCodesign(pb, false);
|
||||
} catch (IOException e) {
|
||||
toThrow.set(e);
|
||||
}
|
||||
@ -842,8 +877,7 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
|
||||
List<String> args = getCodesignArgs(true, appLocation, signingIdentity,
|
||||
identifierPrefix, entitlements, keyChain);
|
||||
ProcessBuilder pb = new ProcessBuilder(args);
|
||||
|
||||
IOUtils.exec(pb);
|
||||
runCodesign(pb, false);
|
||||
}
|
||||
|
||||
private static String extractBundleIdentifier(Map<String, Object> params) {
|
||||
|
@ -79,6 +79,13 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler {
|
||||
params -> "",
|
||||
null);
|
||||
|
||||
public static final BundlerParamInfo<String> INSTALLER_SIGN_IDENTITY =
|
||||
new StandardBundlerParam<>(
|
||||
Arguments.CLIOptions.MAC_INSTALLER_SIGN_IDENTITY.getId(),
|
||||
String.class,
|
||||
params -> "",
|
||||
null);
|
||||
|
||||
public static final BundlerParamInfo<String> MAC_INSTALLER_NAME =
|
||||
new StandardBundlerParam<> (
|
||||
"mac.installerName",
|
||||
|
@ -28,7 +28,9 @@ package jdk.jpackage.internal;
|
||||
import jdk.internal.util.Architecture;
|
||||
import jdk.internal.util.OSVersion;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
@ -54,6 +56,8 @@ import static jdk.jpackage.internal.StandardBundlerParam.VERSION;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.SIGN_BUNDLE;
|
||||
import static jdk.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEYCHAIN;
|
||||
import static jdk.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEY_USER;
|
||||
import static jdk.jpackage.internal.MacBaseInstallerBundler.INSTALLER_SIGN_IDENTITY;
|
||||
import static jdk.jpackage.internal.MacAppBundler.APP_IMAGE_SIGN_IDENTITY;
|
||||
import static jdk.jpackage.internal.StandardBundlerParam.APP_STORE;
|
||||
import static jdk.jpackage.internal.MacAppImageBuilder.MAC_CF_BUNDLE_IDENTIFIER;
|
||||
import static jdk.jpackage.internal.OverridableResource.createResource;
|
||||
@ -605,8 +609,19 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
|
||||
Log.verbose(I18N.getString("message.signing.pkg"));
|
||||
}
|
||||
|
||||
String signingIdentity =
|
||||
DEVELOPER_ID_INSTALLER_SIGNING_KEY.fetchFrom(params);
|
||||
String signingIdentity = null;
|
||||
// --mac-installer-sign-identity
|
||||
if (!INSTALLER_SIGN_IDENTITY.getIsDefaultValue(params)) {
|
||||
signingIdentity = INSTALLER_SIGN_IDENTITY.fetchFrom(params);
|
||||
} else {
|
||||
// Use --mac-signing-key-user-name if user did not request
|
||||
// to sign just app image using --mac-app-image-sign-identity
|
||||
if (APP_IMAGE_SIGN_IDENTITY.getIsDefaultValue(params)) {
|
||||
// --mac-signing-key-user-name
|
||||
signingIdentity = DEVELOPER_ID_INSTALLER_SIGNING_KEY.fetchFrom(params);
|
||||
}
|
||||
}
|
||||
|
||||
if (signingIdentity != null) {
|
||||
commandLine.add("--sign");
|
||||
commandLine.add(signingIdentity);
|
||||
@ -638,7 +653,21 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
|
||||
commandLine.add(finalPKG.toAbsolutePath().toString());
|
||||
|
||||
pb = new ProcessBuilder(commandLine);
|
||||
IOUtils.exec(pb, false, null, true, Executor.INFINITE_TIMEOUT);
|
||||
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PrintStream ps = new PrintStream(baos)) {
|
||||
try {
|
||||
IOUtils.exec(pb, false, ps, true, Executor.INFINITE_TIMEOUT);
|
||||
} catch (IOException ioe) {
|
||||
// Log output of "productbuild" in case of
|
||||
// error. It should help user to diagnose
|
||||
// issue when using --mac-installer-sign-identity
|
||||
Log.info(MessageFormat.format(I18N.getString(
|
||||
"error.tool.failed.with.output"), "productbuild"));
|
||||
Log.info(baos.toString().strip());
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
return finalPKG;
|
||||
} catch (Exception ignored) {
|
||||
@ -702,6 +731,7 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
|
||||
// reject explicitly set sign to true and no valid signature key
|
||||
if (Optional.ofNullable(
|
||||
SIGN_BUNDLE.fetchFrom(params)).orElse(Boolean.FALSE)) {
|
||||
if (!SIGNING_KEY_USER.getIsDefaultValue(params)) {
|
||||
String signingIdentity =
|
||||
DEVELOPER_ID_INSTALLER_SIGNING_KEY.fetchFrom(params);
|
||||
if (signingIdentity == null) {
|
||||
@ -712,6 +742,10 @@ public class MacPkgBundler extends MacBaseInstallerBundler {
|
||||
}
|
||||
}
|
||||
|
||||
// No need to validate --mac-installer-sign-identity, since it is
|
||||
// pass through option.
|
||||
}
|
||||
|
||||
// hdiutil is always available so there's no need
|
||||
// to test for availability.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2017, 2023, 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
|
||||
@ -44,6 +44,7 @@ error.no.xcode.signing.advice=Install Xcode with command line developer tools.
|
||||
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.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:
|
||||
resource.bundle-config-file=Bundle config file
|
||||
resource.app-info-plist=Application Info.plist
|
||||
resource.runtime-info-plist=Java Runtime Info.plist
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2017, 2023, 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
|
||||
@ -44,6 +44,7 @@ error.no.xcode.signing.advice=Installieren Sie Xcode mit Befehlszeilen-Entwickle
|
||||
error.cert.not.found=Kein Zertifikat gefunden, das [{0}] mit Schlüsselbund [{1}] entspricht
|
||||
error.multiple.certs.found=WARNUNG: Mehrere Zertifikate gefunden, die [{0}] mit Schlüsselbund [{1}] entsprechen. Es wird das erste Zertifikat verwendet
|
||||
error.app-image.mac-sign.required=Fehler: Die Option "--mac-sign" ist mit einem vordefinierten Anwendungsimage und Typ [app-image] erforderlich
|
||||
error.tool.failed.with.output=Error: "{0}" failed with following output:
|
||||
resource.bundle-config-file=Bundle-Konfigurationsdatei
|
||||
resource.app-info-plist=Info.plist der Anwendung
|
||||
resource.runtime-info-plist=Info.plist von Java Runtime
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2017, 2023, 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
|
||||
@ -44,6 +44,7 @@ error.no.xcode.signing.advice=Xcodeとコマンドライン・デベロッパ・
|
||||
error.cert.not.found=キーチェーン[{1}]を使用する[{0}]と一致する証明書が見つかりません
|
||||
error.multiple.certs.found=警告: キーチェーン[{1}]を使用する[{0}]と一致する複数の証明書が見つかりました。最初のものを使用します
|
||||
error.app-image.mac-sign.required=エラー: --mac-signオプションは、事前定義済アプリケーション・イメージおよびタイプ[app-image]で必要です
|
||||
error.tool.failed.with.output=Error: "{0}" failed with following output:
|
||||
resource.bundle-config-file=バンドル構成ファイル
|
||||
resource.app-info-plist=アプリケーションのInfo.plist
|
||||
resource.runtime-info-plist=JavaランタイムのInfo.plist
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2017, 2023, 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
|
||||
@ -44,6 +44,7 @@ error.no.xcode.signing.advice=安装带命令行开发人员工具的 Xcode。
|
||||
error.cert.not.found=使用密钥链 [{1}] 找不到与 [{0}] 匹配的证书
|
||||
error.multiple.certs.found=警告:使用密钥链 [{1}] 找到多个与 [{0}] 匹配的证书,将使用第一个证书
|
||||
error.app-image.mac-sign.required=错误:预定义的应用程序映像和类型 [app image] 需要 --mac-sign 选项
|
||||
error.tool.failed.with.output=Error: "{0}" failed with following output:
|
||||
resource.bundle-config-file=包配置文件
|
||||
resource.app-info-plist=应用程序 Info.plist
|
||||
resource.runtime-info-plist=Java 运行时 Info.plist
|
||||
|
@ -338,6 +338,12 @@ public class Arguments {
|
||||
MAC_SIGNING_KEY_NAME ("mac-signing-key-user-name",
|
||||
OptionCategories.PLATFORM_MAC),
|
||||
|
||||
MAC_APP_IMAGE_SIGN_IDENTITY ("mac-app-image-sign-identity",
|
||||
OptionCategories.PLATFORM_MAC),
|
||||
|
||||
MAC_INSTALLER_SIGN_IDENTITY ("mac-installer-sign-identity",
|
||||
OptionCategories.PLATFORM_MAC),
|
||||
|
||||
MAC_SIGNING_KEYCHAIN ("mac-signing-keychain",
|
||||
OptionCategories.PLATFORM_MAC),
|
||||
|
||||
@ -631,6 +637,24 @@ public class Arguments {
|
||||
CLIOptions.JLINK_OPTIONS.getIdWithPrefix());
|
||||
}
|
||||
}
|
||||
if (allOptions.contains(CLIOptions.MAC_SIGNING_KEY_NAME) &&
|
||||
allOptions.contains(CLIOptions.MAC_APP_IMAGE_SIGN_IDENTITY)) {
|
||||
throw new PackagerException("ERR_MutuallyExclusiveOptions",
|
||||
CLIOptions.MAC_SIGNING_KEY_NAME.getIdWithPrefix(),
|
||||
CLIOptions.MAC_APP_IMAGE_SIGN_IDENTITY.getIdWithPrefix());
|
||||
}
|
||||
if (allOptions.contains(CLIOptions.MAC_SIGNING_KEY_NAME) &&
|
||||
allOptions.contains(CLIOptions.MAC_INSTALLER_SIGN_IDENTITY)) {
|
||||
throw new PackagerException("ERR_MutuallyExclusiveOptions",
|
||||
CLIOptions.MAC_SIGNING_KEY_NAME.getIdWithPrefix(),
|
||||
CLIOptions.MAC_INSTALLER_SIGN_IDENTITY.getIdWithPrefix());
|
||||
}
|
||||
if (isMac && (imageOnly || "dmg".equals(type)) &&
|
||||
allOptions.contains(CLIOptions.MAC_INSTALLER_SIGN_IDENTITY)) {
|
||||
throw new PackagerException("ERR_InvalidTypeOption",
|
||||
CLIOptions.MAC_INSTALLER_SIGN_IDENTITY.getIdWithPrefix(),
|
||||
type);
|
||||
}
|
||||
if (allOptions.contains(CLIOptions.DMG_CONTENT)
|
||||
&& !("dmg".equals(type))) {
|
||||
throw new PackagerException("ERR_InvalidTypeOption",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2023, 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
|
||||
@ -46,11 +46,6 @@ class BundlerParamInfo<T> {
|
||||
*/
|
||||
Class<T> valueType;
|
||||
|
||||
/**
|
||||
* Indicates if value was set using default value function
|
||||
*/
|
||||
boolean isDefaultValue;
|
||||
|
||||
/**
|
||||
* If the value is not set, and no fallback value is found,
|
||||
* the parameter uses the value returned by the producer.
|
||||
@ -70,8 +65,24 @@ class BundlerParamInfo<T> {
|
||||
return valueType;
|
||||
}
|
||||
|
||||
boolean getIsDefaultValue() {
|
||||
return isDefaultValue;
|
||||
/**
|
||||
* Returns true if value was not provided on command line for this
|
||||
* parameter.
|
||||
*
|
||||
* @param params - params from which value will be fetch
|
||||
* @return true if value was not provided on command line, false otherwise
|
||||
*/
|
||||
boolean getIsDefaultValue(Map<String, ? super Object> params) {
|
||||
Object o = params.get(getID());
|
||||
if (o != null) {
|
||||
return false; // We have user provided value
|
||||
}
|
||||
|
||||
if (params.containsKey(getID())) {
|
||||
return false; // explicit nulls are allowed for provided value
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Function<Map<String, ? super Object>, T> getDefaultValueFunction() {
|
||||
@ -114,7 +125,6 @@ class BundlerParamInfo<T> {
|
||||
T result = getDefaultValueFunction().apply(params);
|
||||
if (result != null) {
|
||||
params.put(getID(), result);
|
||||
isDefaultValue = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ package jdk.jpackage.internal;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
|
||||
import jdk.internal.util.OperatingSystem;
|
||||
import jdk.jpackage.internal.Arguments.CLIOptions;
|
||||
|
||||
@ -62,7 +63,6 @@ class ValidOptions {
|
||||
|
||||
private static final HashMap<String, EnumSet<USE>> options = new HashMap<>();
|
||||
|
||||
|
||||
// initializing list of mandatory arguments
|
||||
static {
|
||||
put(CLIOptions.NAME.getId(), USE.ALL);
|
||||
@ -130,6 +130,10 @@ class ValidOptions {
|
||||
EnumSet.of(USE.ALL, USE.SIGN));
|
||||
put(CLIOptions.MAC_SIGNING_KEY_NAME.getId(),
|
||||
EnumSet.of(USE.ALL, USE.SIGN));
|
||||
put(CLIOptions.MAC_APP_IMAGE_SIGN_IDENTITY.getId(),
|
||||
EnumSet.of(USE.ALL, USE.SIGN));
|
||||
put(CLIOptions.MAC_INSTALLER_SIGN_IDENTITY.getId(),
|
||||
EnumSet.of(USE.INSTALL, USE.SIGN));
|
||||
put(CLIOptions.MAC_SIGNING_KEYCHAIN.getId(),
|
||||
EnumSet.of(USE.ALL, USE.SIGN));
|
||||
put(CLIOptions.MAC_APP_STORE.getId(), USE.ALL);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2017, 2023, 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
|
||||
@ -265,7 +265,19 @@ MSG_Help_mac_launcher=\
|
||||
\ Name of the keychain to search for the signing identity\n\
|
||||
\ If not specified, the standard keychains are used.\n\
|
||||
\ --mac-signing-key-user-name <team name>\n\
|
||||
\ Team or user name portion of Apple signing identities.\n\
|
||||
\ Team or user name portion of Apple signing identities. For direct\n\
|
||||
\ control of the signing identity used to sign application images or\n\
|
||||
\ installers use --mac-app-image-sign-identity and/or\n\
|
||||
\ --mac-installer-sign-identity. This option cannot be combined with\n\
|
||||
\ --mac-app-image-sign-identity or --mac-installer-sign-identity.\n\
|
||||
\ --mac-app-image-sign-identity <identity>\n\
|
||||
\ Identity used to sign application image. This value will be passed\n\
|
||||
\ directly to --sign option of "codesign" tool. This option cannot\n\
|
||||
\ be combined with --mac-signing-key-user-name.\n\
|
||||
\ --mac-installer-sign-identity <identity>\n\
|
||||
\ Identity used to sign "pkg" installer. This value will be passed\n\
|
||||
\ directly to --sign option of "productbuild" tool. This option\n\
|
||||
\ cannot be combined with --mac-signing-key-user-name.\n\
|
||||
\ --mac-app-store\n\
|
||||
\ Indicates that the jpackage output is intended for the\n\
|
||||
\ Mac App Store.\n\
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2017, 2023, 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
|
||||
@ -92,10 +92,11 @@ ERR_NoMainClass=Error: Main application class is missing
|
||||
ERR_UnsupportedOption=Error: Option [{0}] is not valid on this platform
|
||||
ERR_InvalidTypeOption=Error: Option [{0}] is not valid with type [{1}]
|
||||
ERR_NoInstallerEntryPoint=Error: Option [{0}] is not valid without --module or --main-jar entry point option
|
||||
ERR_MutuallyExclusiveOptions="Error: Mutually exclusive options [{0}] and [{1}]
|
||||
ERR_MutuallyExclusiveOptions=Error: Mutually exclusive options [{0}] and [{1}]
|
||||
ERR_InvalidOptionWithAppImageSigning=Error: Option [{0}] is not valid when signing application image
|
||||
|
||||
ERR_MissingArgument=Error: Missing argument: {0}
|
||||
ERR_MissingRequiredArgument=Error: {0} argument requires at least one of [{1}] argument(s)
|
||||
ERR_MissingAppResources=Error: No application jars found
|
||||
ERR_AppImageNotExist=Error: App image directory "{0}" does not exist
|
||||
ERR_NoAddLauncherName=Error: --add-launcher option requires a name and a file path (--add-launcher <name>=<file path>)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2017, 2023, 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
|
||||
@ -95,6 +95,7 @@ ERR_MutuallyExclusiveOptions="Fehler: Optionen [{0}] und [{1}] schließen sich g
|
||||
ERR_InvalidOptionWithAppImageSigning=Fehler: Option [{0}] ist nicht gültig beim Signieren eines Anwendungsimages
|
||||
|
||||
ERR_MissingArgument=Fehler: Fehlendes Argument: {0}
|
||||
ERR_MissingRequiredArgument=Error: {0} argument requires at least one of [{1}] argument(s)
|
||||
ERR_MissingAppResources=Fehler: Keine Anwendungs-JAR-Dateien gefunden
|
||||
ERR_AppImageNotExist=Fehler: Anwendungsimageverzeichnis "{0}" ist nicht vorhanden
|
||||
ERR_NoAddLauncherName=Fehler: Für Option --add-launcher müssen ein Name und ein Dateipfad angegeben werden (--add-launcher <Name>=<Dateipfad>)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2017, 2023, 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
|
||||
@ -95,6 +95,7 @@ ERR_MutuallyExclusiveOptions="エラー: 相互排他的なオプション[{0}]
|
||||
ERR_InvalidOptionWithAppImageSigning=エラー: アプリケーション・イメージへの署名時にオプション[{0}]が有効ではありません
|
||||
|
||||
ERR_MissingArgument=エラー: 引数がありません: {0}
|
||||
ERR_MissingRequiredArgument=Error: {0} argument requires at least one of [{1}] argument(s)
|
||||
ERR_MissingAppResources=エラー: アプリケーションjarが見つかりませんでした
|
||||
ERR_AppImageNotExist=エラー: アプリケーション・イメージ・ディレクトリ"{0}"は存在しません
|
||||
ERR_NoAddLauncherName=エラー: --add-launcherオプションには名前およびファイル・パスが必要です(--add-launcher <name>=<file path>)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2017, 2023, 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
|
||||
@ -95,6 +95,7 @@ ERR_MutuallyExclusiveOptions="错误:选项 [{0}] 和 [{1}] 相互排斥
|
||||
ERR_InvalidOptionWithAppImageSigning=错误:对应用程序映像签名时,选项 [{0}] 无效
|
||||
|
||||
ERR_MissingArgument=错误: 缺少参数: {0}
|
||||
ERR_MissingRequiredArgument=Error: {0} argument requires at least one of [{1}] argument(s)
|
||||
ERR_MissingAppResources=错误: 找不到应用程序 jar
|
||||
ERR_AppImageNotExist=错误:应用程序映像目录 "{0}" 不存在
|
||||
ERR_NoAddLauncherName=错误:--add-launcher 选项需要一个名称和一个文件路径 (--add-launcher <name>=<file path>)
|
||||
|
@ -55,28 +55,40 @@ import jdk.jpackage.test.AdditionalLauncher;
|
||||
* @build SigningAppImageTest
|
||||
* @modules jdk.jpackage/jdk.jpackage.internal
|
||||
* @requires (os.family == "mac")
|
||||
* @run main/othervm -Xmx512m jdk.jpackage.test.Main
|
||||
* @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main
|
||||
* --jpt-run=SigningAppImageTest
|
||||
*/
|
||||
public class SigningAppImageTest {
|
||||
|
||||
@Test
|
||||
@Parameter({"true", "0"}) // ({"sign or not", "certificate index"})
|
||||
@Parameter({"true", "1"})
|
||||
@Parameter({"false", "-1"})
|
||||
// ({"sign or not", "signing-key or sign-identity", "certificate index"})
|
||||
// Sign, signing-key and ASCII certificate
|
||||
@Parameter({"true", "true", SigningBase.ASCII_INDEX})
|
||||
// Sign, signing-key and UNICODE certificate
|
||||
@Parameter({"true", "true", SigningBase.UNICODE_INDEX})
|
||||
// Sign, signing-indentity and UNICODE certificate
|
||||
@Parameter({"true", "false", SigningBase.UNICODE_INDEX})
|
||||
// Unsigned
|
||||
@Parameter({"false", "true", "-1"})
|
||||
public void test(String... testArgs) throws Exception {
|
||||
boolean doSign = Boolean.parseBoolean(testArgs[0]);
|
||||
int certIndex = Integer.parseInt(testArgs[1]);
|
||||
boolean signingKey = Boolean.parseBoolean(testArgs[1]);
|
||||
int certIndex = Integer.parseInt(testArgs[2]);
|
||||
|
||||
SigningCheck.checkCertificates(certIndex);
|
||||
|
||||
JPackageCommand cmd = JPackageCommand.helloAppImage();
|
||||
if (doSign) {
|
||||
cmd.addArguments("--mac-sign",
|
||||
"--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(certIndex),
|
||||
"--mac-signing-keychain",
|
||||
SigningBase.getKeyChain());
|
||||
if (signingKey) {
|
||||
cmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(certIndex));
|
||||
} else {
|
||||
cmd.addArguments("--mac-app-image-sign-identity",
|
||||
SigningBase.getAppCert(certIndex));
|
||||
}
|
||||
}
|
||||
AdditionalLauncher testAL = new AdditionalLauncher("testAL");
|
||||
testAL.applyTo(cmd);
|
||||
|
@ -56,15 +56,23 @@ import jdk.jpackage.test.AdditionalLauncher;
|
||||
* @build SigningAppImageTwoStepsTest
|
||||
* @modules jdk.jpackage/jdk.jpackage.internal
|
||||
* @requires (os.family == "mac")
|
||||
* @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
|
||||
* @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main
|
||||
* --jpt-run=SigningAppImageTwoStepsTest
|
||||
*/
|
||||
public class SigningAppImageTwoStepsTest {
|
||||
|
||||
@Test
|
||||
@Parameter("true")
|
||||
@Parameter("false")
|
||||
public void test(boolean signAppImage) throws Exception {
|
||||
// ({"sign or not", "signing-key or sign-identity"})
|
||||
// Sign and signing-key
|
||||
@Parameter({"true", "true"})
|
||||
// Sign and sign-identity
|
||||
@Parameter({"true", "false"})
|
||||
// Unsigned
|
||||
@Parameter({"false", "true"})
|
||||
public void test(String... testArgs) throws Exception {
|
||||
boolean signAppImage = Boolean.parseBoolean(testArgs[0]);
|
||||
boolean signingKey = Boolean.parseBoolean(testArgs[1]);
|
||||
|
||||
SigningCheck.checkCertificates(SigningBase.DEFAULT_INDEX);
|
||||
|
||||
Path appimageOutput = TKit.createTempDirectory("appimage");
|
||||
@ -76,10 +84,15 @@ public class SigningAppImageTwoStepsTest {
|
||||
.setArgumentValue("--dest", appimageOutput);
|
||||
if (signAppImage) {
|
||||
appImageCmd.addArguments("--mac-sign",
|
||||
"--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX),
|
||||
"--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));
|
||||
}
|
||||
}
|
||||
|
||||
// Add addtional launcher
|
||||
@ -97,9 +110,14 @@ public class SigningAppImageTwoStepsTest {
|
||||
cmd.setPackageType(PackageType.IMAGE)
|
||||
.addArguments("--app-image", appImageCmd.outputBundle().toAbsolutePath())
|
||||
.addArguments("--mac-sign")
|
||||
.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX))
|
||||
.addArguments("--mac-signing-keychain", SigningBase.getKeyChain());
|
||||
if (signingKey) {
|
||||
cmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX));
|
||||
} else {
|
||||
cmd.addArguments("--mac-app-image-sign-identity",
|
||||
SigningBase.getAppCert(SigningBase.DEFAULT_INDEX));
|
||||
}
|
||||
cmd.executeAndAssertImageCreated();
|
||||
|
||||
// Should be signed app image
|
||||
|
115
test/jdk/tools/jpackage/macosx/SigningOptionsTest.java
Normal file
115
test/jdk/tools/jpackage/macosx/SigningOptionsTest.java
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import jdk.jpackage.test.Annotations.Parameters;
|
||||
import jdk.jpackage.test.Annotations.Test;
|
||||
import jdk.jpackage.test.JPackageCommand;
|
||||
import jdk.jpackage.test.TKit;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test jpackage signing options errors
|
||||
* @library ../helpers
|
||||
* @build SigningOptionsTest
|
||||
* @modules jdk.jpackage/jdk.jpackage.internal
|
||||
* @requires (os.family == "mac")
|
||||
* @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
|
||||
* --jpt-run=SigningOptionsTest
|
||||
* --jpt-before-run=jdk.jpackage.test.JPackageCommand.useExecutableByDefault
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test jpackage signing options errors
|
||||
* @library ../helpers
|
||||
* @build SigningOptionsTest
|
||||
* @modules jdk.jpackage/jdk.jpackage.internal
|
||||
* @requires (os.family == "mac")
|
||||
* @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
|
||||
* --jpt-run=SigningOptionsTest
|
||||
* --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault
|
||||
*/
|
||||
|
||||
public final class SigningOptionsTest {
|
||||
|
||||
private final String expectedError;
|
||||
private final JPackageCommand cmd;
|
||||
|
||||
@Parameters
|
||||
public static Collection input() {
|
||||
return List.of(new Object[][]{
|
||||
// --mac-signing-key-user-name and --mac-app-image-sign-identity
|
||||
{"Hello",
|
||||
new String[]{"--mac-sign",
|
||||
"--mac-signing-key-user-name", "test-key",
|
||||
"--mac-app-image-sign-identity", "test-identity"},
|
||||
null,
|
||||
"Mutually exclusive options"},
|
||||
// --mac-signing-key-user-name and --mac-installer-sign-identity
|
||||
{"Hello",
|
||||
new String[]{"--mac-sign",
|
||||
"--mac-signing-key-user-name", "test-key",
|
||||
"--mac-installer-sign-identity", "test-identity"},
|
||||
null,
|
||||
"Mutually exclusive options"},
|
||||
// --mac-installer-sign-identity and --type app-image
|
||||
{"Hello",
|
||||
new String[]{"--mac-sign",
|
||||
"--mac-installer-sign-identity", "test-identity"},
|
||||
null,
|
||||
"Option [--mac-installer-sign-identity] is not valid with type"},
|
||||
// --mac-installer-sign-identity and --type dmg
|
||||
{"Hello",
|
||||
new String[]{"--type", "dmg",
|
||||
"--mac-sign",
|
||||
"--mac-installer-sign-identity", "test-identity"},
|
||||
new String[]{"--type"},
|
||||
"Option [--mac-installer-sign-identity] is not valid with type"},
|
||||
});
|
||||
}
|
||||
|
||||
public SigningOptionsTest(String javaAppDesc, String[] jpackageArgs,
|
||||
String[] removeArgs, String expectedError) {
|
||||
this.expectedError = expectedError;
|
||||
|
||||
cmd = JPackageCommand.helloAppImage(javaAppDesc)
|
||||
.saveConsoleOutput(true).dumpOutput(true);
|
||||
if (jpackageArgs != null) {
|
||||
cmd.addArguments(jpackageArgs);
|
||||
} if (removeArgs != null) {
|
||||
for (String arg : removeArgs) {
|
||||
cmd.removeArgumentWithValue(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
List<String> output = cmd.execute(1).getOutput();
|
||||
TKit.assertNotNull(output, "output is null");
|
||||
TKit.assertTextStream(expectedError).apply(output.stream());
|
||||
}
|
||||
|
||||
}
|
@ -72,7 +72,7 @@ public class SigningPackageFromTwoStepAppImageTest {
|
||||
}
|
||||
|
||||
Path outputBundle = cmd.outputBundle();
|
||||
SigningBase.verifyPkgutil(outputBundle, SigningBase.DEFAULT_INDEX);
|
||||
SigningBase.verifyPkgutil(outputBundle, true, SigningBase.DEFAULT_INDEX);
|
||||
SigningBase.verifySpctl(outputBundle, "install", SigningBase.DEFAULT_INDEX);
|
||||
}
|
||||
|
||||
@ -97,9 +97,17 @@ public class SigningPackageFromTwoStepAppImageTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Parameter("true")
|
||||
@Parameter("false")
|
||||
public static void test(boolean signAppImage) throws Exception {
|
||||
// ({"sign or not", "signing-key or sign-identity"})
|
||||
// Sign and signing-key
|
||||
@Parameter({"true", "true"})
|
||||
// Sign and sign-identity
|
||||
@Parameter({"true", "false"})
|
||||
// Unsigned
|
||||
@Parameter({"false", "true"})
|
||||
public void test(String... testArgs) throws Exception {
|
||||
boolean signAppImage = Boolean.parseBoolean(testArgs[0]);
|
||||
boolean signingKey = Boolean.parseBoolean(testArgs[1]);
|
||||
|
||||
SigningCheck.checkCertificates(SigningBase.DEFAULT_INDEX);
|
||||
|
||||
Path appimageOutput = TKit.createTempDirectory("appimage");
|
||||
@ -110,9 +118,15 @@ public class SigningPackageFromTwoStepAppImageTest {
|
||||
JPackageCommand appImageCmd = JPackageCommand.helloAppImage()
|
||||
.setArgumentValue("--dest", appimageOutput);
|
||||
if (signAppImage) {
|
||||
appImageCmd.addArguments("--mac-sign", "--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX),
|
||||
appImageCmd.addArguments("--mac-sign",
|
||||
"--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));
|
||||
}
|
||||
}
|
||||
|
||||
// Generate app image
|
||||
@ -126,9 +140,14 @@ public class SigningPackageFromTwoStepAppImageTest {
|
||||
appImageSignedCmd.setPackageType(PackageType.IMAGE)
|
||||
.addArguments("--app-image", appImageCmd.outputBundle().toAbsolutePath())
|
||||
.addArguments("--mac-sign")
|
||||
.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX))
|
||||
.addArguments("--mac-signing-keychain", SigningBase.getKeyChain());
|
||||
if (signingKey) {
|
||||
appImageSignedCmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX));
|
||||
} else {
|
||||
appImageSignedCmd.addArguments("--mac-app-image-sign-identity",
|
||||
SigningBase.getAppCert(SigningBase.DEFAULT_INDEX));
|
||||
}
|
||||
appImageSignedCmd.executeAndAssertImageCreated();
|
||||
|
||||
// Should be signed app image
|
||||
@ -141,16 +160,30 @@ public class SigningPackageFromTwoStepAppImageTest {
|
||||
cmd.removeArgumentWithValue("--input");
|
||||
if (signAppImage) {
|
||||
cmd.addArguments("--mac-sign",
|
||||
"--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(SigningBase.DEFAULT_INDEX),
|
||||
"--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(
|
||||
SigningPackageFromTwoStepAppImageTest::verifyPKG)
|
||||
.forTypes(PackageType.MAC_DMG)
|
||||
.addInitializer(cmd -> {
|
||||
if (signAppImage && !signingKey) {
|
||||
// jpackage throws expected error with
|
||||
// --mac-installer-sign-identity and DMG type
|
||||
cmd.removeArgument("--mac-sign");
|
||||
cmd.removeArgumentWithValue("--mac-signing-keychain");
|
||||
cmd.removeArgumentWithValue("--mac-installer-sign-identity");
|
||||
}
|
||||
})
|
||||
.addBundleVerifier(
|
||||
SigningPackageFromTwoStepAppImageTest::verifyDMG)
|
||||
.addBundleVerifier(
|
||||
|
@ -59,16 +59,28 @@ import jdk.jpackage.test.Annotations.Parameter;
|
||||
* @build SigningPackageTest
|
||||
* @modules jdk.jpackage/jdk.jpackage.internal
|
||||
* @requires (os.family == "mac")
|
||||
* @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main
|
||||
* @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main
|
||||
* --jpt-run=SigningPackageTest
|
||||
*/
|
||||
public class SigningPackageTest {
|
||||
|
||||
private static boolean isAppImageSigned(JPackageCommand cmd) {
|
||||
return cmd.hasArgument("--mac-signing-key-user-name") ||
|
||||
cmd.hasArgument("--mac-app-image-sign-identity");
|
||||
}
|
||||
|
||||
private static boolean isPKGSigned(JPackageCommand cmd) {
|
||||
return cmd.hasArgument("--mac-signing-key-user-name") ||
|
||||
cmd.hasArgument("--mac-installer-sign-identity");
|
||||
}
|
||||
|
||||
private static void verifyPKG(JPackageCommand cmd) {
|
||||
Path outputBundle = cmd.outputBundle();
|
||||
SigningBase.verifyPkgutil(outputBundle, getCertIndex(cmd));
|
||||
SigningBase.verifyPkgutil(outputBundle, isPKGSigned(cmd), getCertIndex(cmd));
|
||||
if (isPKGSigned(cmd)) {
|
||||
SigningBase.verifySpctl(outputBundle, "install", getCertIndex(cmd));
|
||||
}
|
||||
}
|
||||
|
||||
private static void verifyDMG(JPackageCommand cmd) {
|
||||
Path outputBundle = cmd.outputBundle();
|
||||
@ -82,22 +94,45 @@ public class SigningPackageTest {
|
||||
// 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")) {
|
||||
SigningBase.verifyCodesign(launcherPath, true, getCertIndex(cmd));
|
||||
SigningBase.verifyCodesign(dmgImage, true, getCertIndex(cmd));
|
||||
SigningBase.verifyCodesign(launcherPath, isAppImageSigned(cmd),
|
||||
getCertIndex(cmd));
|
||||
SigningBase.verifyCodesign(dmgImage, isAppImageSigned(cmd),
|
||||
getCertIndex(cmd));
|
||||
if (isAppImageSigned(cmd)) {
|
||||
SigningBase.verifySpctl(dmgImage, "exec", getCertIndex(cmd));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static int getCertIndex(JPackageCommand cmd) {
|
||||
if (cmd.hasArgument("--mac-signing-key-user-name")) {
|
||||
String devName = cmd.getArgumentValue("--mac-signing-key-user-name");
|
||||
return SigningBase.getDevNameIndex(devName);
|
||||
} else {
|
||||
// Signing-indentity
|
||||
return Integer.valueOf(SigningBase.UNICODE_INDEX);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Parameter("0")
|
||||
@Parameter("1")
|
||||
public static void test(int certIndex) throws Exception {
|
||||
// ("signing-key or sign-identity", "sign app-image", "sign pkg", "certificate index"})
|
||||
// Signing-key and ASCII certificate
|
||||
@Parameter({"true", "true", "true", SigningBase.ASCII_INDEX})
|
||||
// Signing-key and UNICODE certificate
|
||||
@Parameter({"true", "true", "true", SigningBase.UNICODE_INDEX})
|
||||
// Signing-indentity and UNICODE certificate
|
||||
@Parameter({"false", "true", "true", SigningBase.UNICODE_INDEX})
|
||||
// Signing-indentity, but sign app-image only and UNICODE certificate
|
||||
@Parameter({"false", "true", "false", SigningBase.UNICODE_INDEX})
|
||||
// Signing-indentity, but sign pkg only and UNICODE certificate
|
||||
@Parameter({"false", "false", "true", SigningBase.UNICODE_INDEX})
|
||||
public static void test(String... testArgs) throws Exception {
|
||||
boolean signingKey = Boolean.parseBoolean(testArgs[0]);
|
||||
boolean signAppImage = Boolean.parseBoolean(testArgs[1]);
|
||||
boolean signPKG = Boolean.parseBoolean(testArgs[2]);
|
||||
int certIndex = Integer.parseInt(testArgs[3]);
|
||||
|
||||
SigningCheck.checkCertificates(certIndex);
|
||||
|
||||
new PackageTest()
|
||||
@ -105,12 +140,39 @@ public class SigningPackageTest {
|
||||
.forTypes(PackageType.MAC)
|
||||
.addInitializer(cmd -> {
|
||||
cmd.addArguments("--mac-sign",
|
||||
"--mac-signing-key-user-name", SigningBase.getDevName(certIndex),
|
||||
"--mac-signing-keychain", SigningBase.getKeyChain());
|
||||
if (signingKey) {
|
||||
cmd.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(certIndex));
|
||||
} else {
|
||||
if (signAppImage) {
|
||||
cmd.addArguments("--mac-app-image-sign-identity",
|
||||
SigningBase.getAppCert(certIndex));
|
||||
}
|
||||
if (signPKG) {
|
||||
cmd.addArguments("--mac-installer-sign-identity",
|
||||
SigningBase.getInstallerCert(certIndex));
|
||||
}
|
||||
}
|
||||
})
|
||||
.forTypes(PackageType.MAC_PKG)
|
||||
.addBundleVerifier(SigningPackageTest::verifyPKG)
|
||||
.forTypes(PackageType.MAC_DMG)
|
||||
.addInitializer(cmd -> {
|
||||
if (!signingKey) {
|
||||
// jpackage throws expected error with
|
||||
// --mac-installer-sign-identity and DMG type
|
||||
cmd.removeArgumentWithValue("--mac-installer-sign-identity");
|
||||
// In case of not signing app image and DMG we need to
|
||||
// remove signing completely, otherwise we will default
|
||||
// to --mac-signing-key-user-name once
|
||||
// --mac-installer-sign-identity is removed.
|
||||
if (!signAppImage) {
|
||||
cmd.removeArgumentWithValue("--mac-signing-keychain");
|
||||
cmd.removeArgument("--mac-sign");
|
||||
}
|
||||
}
|
||||
})
|
||||
.addBundleVerifier(SigningPackageTest::verifyDMG)
|
||||
.addBundleVerifier(SigningPackageTest::verifyAppImageInDMG)
|
||||
.run();
|
||||
|
@ -73,7 +73,7 @@ public class SigningPackageTwoStepTest {
|
||||
}
|
||||
|
||||
Path outputBundle = cmd.outputBundle();
|
||||
SigningBase.verifyPkgutil(outputBundle, SigningBase.DEFAULT_INDEX);
|
||||
SigningBase.verifyPkgutil(outputBundle, true, SigningBase.DEFAULT_INDEX);
|
||||
SigningBase.verifySpctl(outputBundle, "install", SigningBase.DEFAULT_INDEX);
|
||||
}
|
||||
|
||||
@ -101,10 +101,18 @@ public class SigningPackageTwoStepTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Parameter("true")
|
||||
@Parameter("false")
|
||||
public static void test(boolean signAppImage) throws Exception {
|
||||
SigningCheck.checkCertificates(0);
|
||||
// (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(String... testArgs) throws Exception {
|
||||
boolean signAppImage = Boolean.parseBoolean(testArgs[0]);
|
||||
boolean signingKey = Boolean.parseBoolean(testArgs[1]);
|
||||
|
||||
SigningCheck.checkCertificates(SigningBase.DEFAULT_INDEX);
|
||||
|
||||
Path appimageOutput = TKit.createTempDirectory("appimage");
|
||||
|
||||
@ -112,10 +120,15 @@ public class SigningPackageTwoStepTest {
|
||||
.setArgumentValue("--dest", appimageOutput);
|
||||
if (signAppImage) {
|
||||
appImageCmd.addArguments("--mac-sign")
|
||||
.addArguments("--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(0))
|
||||
.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));
|
||||
}
|
||||
}
|
||||
|
||||
new PackageTest()
|
||||
@ -126,15 +139,31 @@ public class SigningPackageTwoStepTest {
|
||||
cmd.removeArgumentWithValue("--input");
|
||||
if (signAppImage) {
|
||||
cmd.addArguments("--mac-sign",
|
||||
"--mac-signing-key-user-name",
|
||||
SigningBase.getDevName(0),
|
||||
"--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();
|
||||
|
@ -33,6 +33,8 @@ import jdk.jpackage.test.Executor.Result;
|
||||
public class SigningBase {
|
||||
|
||||
public static int DEFAULT_INDEX = 0;
|
||||
public static final String ASCII_INDEX = "0";
|
||||
public static final String UNICODE_INDEX = "0";
|
||||
private static String [] DEV_NAMES = {
|
||||
"jpackage.openjdk.java.net",
|
||||
"jpackage.openjdk.java.net (ö)",
|
||||
@ -182,22 +184,30 @@ public class SigningBase {
|
||||
checkString(output, lookupString);
|
||||
}
|
||||
|
||||
private static List<String> pkgutilResult(Path target) {
|
||||
private static List<String> pkgutilResult(Path target, boolean signed) {
|
||||
List<String> result = new Executor()
|
||||
.setExecutable("/usr/sbin/pkgutil")
|
||||
.addArguments("--check-signature",
|
||||
target.toString())
|
||||
.executeAndGetOutput();
|
||||
.saveOutput()
|
||||
.execute(signed ? 0 : 1)
|
||||
.getOutput();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void verifyPkgutilResult(List<String> result, int certIndex) {
|
||||
private static void verifyPkgutilResult(List<String> result, boolean signed,
|
||||
int certIndex) {
|
||||
result.stream().forEachOrdered(TKit::trace);
|
||||
if (signed) {
|
||||
String lookupString = "Status: signed by";
|
||||
checkString(result, lookupString);
|
||||
lookupString = "1. " + getInstallerCert(certIndex);
|
||||
checkString(result, lookupString);
|
||||
} else {
|
||||
String lookupString = "Status: no signature";
|
||||
checkString(result, lookupString);
|
||||
}
|
||||
}
|
||||
|
||||
public static void verifyCodesign(Path target, boolean signed, int certIndex) {
|
||||
@ -228,9 +238,9 @@ public class SigningBase {
|
||||
verifySpctlResult(output, target, type, result.getExitCode(), certIndex);
|
||||
}
|
||||
|
||||
public static void verifyPkgutil(Path target, int certIndex) {
|
||||
List<String> result = pkgutilResult(target);
|
||||
verifyPkgutilResult(result, certIndex);
|
||||
public static void verifyPkgutil(Path target, boolean signed, int certIndex) {
|
||||
List<String> result = pkgutilResult(target, signed);
|
||||
verifyPkgutilResult(result, signed, certIndex);
|
||||
}
|
||||
|
||||
public static void verifyAppImageSignature(JPackageCommand appImageCmd,
|
||||
@ -247,7 +257,7 @@ public class SigningBase {
|
||||
Path appImage = appImageCmd.outputBundle();
|
||||
SigningBase.verifyCodesign(appImage, isSigned, SigningBase.DEFAULT_INDEX);
|
||||
if (isSigned) {
|
||||
SigningBase.verifySpctl(appImage, "exec", 0);
|
||||
SigningBase.verifySpctl(appImage, "exec", SigningBase.DEFAULT_INDEX);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ public final class PredefinedAppImageErrorTest {
|
||||
},
|
||||
// --mac-app-store is required
|
||||
{"Hello",
|
||||
new String[]{"--mac-sign", "--mac-app-store"},
|
||||
new String[]{"--mac-sign", "--mac-app-store", "--mac-app-image-sign-identity", "test"},
|
||||
new String[]{"--input", "--dest", "--name", "--main-jar", "--main-class"},
|
||||
TKit.isOSX() ?
|
||||
"Option [--mac-app-store] is not valid" :
|
||||
|
Loading…
x
Reference in New Issue
Block a user