Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2022, 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
Expand Down Expand Up @@ -329,7 +329,8 @@ public void prepareApplicationFiles(Map<String, ? super Object> params)
}

copyRuntimeFiles(params);
sign(params);

doSigning(params);
}

private void copyRuntimeFiles(Map<String, ? super Object> params)
Expand All @@ -355,7 +356,9 @@ private void copyRuntimeFiles(Map<String, ? super Object> params)
}
}

private void sign(Map<String, ? super Object> params) throws IOException {
private void doSigning(Map<String, ? super Object> params)
throws IOException {

if (Optional.ofNullable(
SIGN_BUNDLE.fetchFrom(params)).orElse(Boolean.TRUE)) {
try {
Expand All @@ -371,6 +374,12 @@ private void sign(Map<String, ? super Object> params) throws IOException {
ENTITLEMENTS.fetchFrom(params));
}
restoreKeychainList(params);
} else if (Platform.isArmMac()) {
signAppBundle(params, root, "-", null, null);
} else {
// Calling signAppBundle() without signingIdentity will result in
// unsigning app bundle
signAppBundle(params, root, null, null, null);
}
}

Expand Down Expand Up @@ -648,7 +657,40 @@ public static void restoreKeychainList(Map<String, ? super Object> params)
IOUtils.exec(pb);
}

static void signAppBundle(
private static List<String> getCodesignArgs(
boolean force, Path path, String signingIdentity,
String identifierPrefix, Path entitlements, String keyChain) {
List<String> args = new ArrayList<>();
args.addAll(Arrays.asList("/usr/bin/codesign",
"-s", signingIdentity,
"-vvvv"));

if (!signingIdentity.equals("-")) {
args.addAll(Arrays.asList("--timestamp",
"--options", "runtime",
"--prefix", identifierPrefix));
if (keyChain != null && !keyChain.isEmpty()) {
args.add("--keychain");
args.add(keyChain);
}
if (Files.isExecutable(path)) {
if (entitlements != null) {
args.add("--entitlements");
args.add(entitlements.toString());
}
}
}

if (force) {
args.add("--force");
}

args.add(path.toString());

return args;
}

private static void signAppBundle(
Map<String, ? super Object> params, Path appLocation,
String signingIdentity, String identifierPrefix, Path entitlements)
throws IOException {
Expand All @@ -660,8 +702,8 @@ static void signAppBundle(
try (Stream<Path> stream = Files.walk(appLocation)) {
stream.peek(path -> { // fix permissions
try {
Set<PosixFilePermission> pfp =
Files.getPosixFilePermissions(path);
Set<PosixFilePermission> pfp
= Files.getPosixFilePermissions(path);
if (!pfp.contains(PosixFilePermission.OWNER_WRITE)) {
pfp = EnumSet.copyOf(pfp);
pfp.add(PosixFilePermission.OWNER_WRITE);
Expand All @@ -670,13 +712,15 @@ static void signAppBundle(
} catch (IOException e) {
Log.verbose(e);
}
}).filter(p -> Files.isRegularFile(p) &&
(Files.isExecutable(p) || p.toString().endsWith(".dylib"))
&& !(p.toString().contains("dylib.dSYM/Contents"))
&& !(p.toString().endsWith(appExecutable))
).forEach(p -> {
}).filter(p -> Files.isRegularFile(p)
&& (Files.isExecutable(p) || p.toString().endsWith(".dylib"))
&& !(p.toString().contains("dylib.dSYM/Contents"))
&& !(p.toString().endsWith(appExecutable))
).forEach(p -> {
// noinspection ThrowableResultOfMethodCallIgnored
if (toThrow.get() != null) return;
if (toThrow.get() != null) {
return;
}

// If p is a symlink then skip the signing process.
if (Files.isSymbolicLink(p)) {
Expand All @@ -695,42 +739,30 @@ static void signAppBundle(
// run quietly
IOUtils.exec(pb, false, null, false,
Executor.INFINITE_TIMEOUT, true);
Files.setPosixFilePermissions(p,oldPermissions);
Files.setPosixFilePermissions(p, oldPermissions);
} catch (IOException ioe) {
Log.verbose(ioe);
toThrow.set(ioe);
return;
}
args = new ArrayList<>();
args.addAll(Arrays.asList("/usr/bin/codesign",
"--timestamp",
"--options", "runtime",
"-s", signingIdentity,
"--prefix", identifierPrefix,
"-vvvv"));
if (keyChain != null && !keyChain.isEmpty()) {
args.add("--keychain");
args.add(keyChain);
}
if (Files.isExecutable(p)) {
if (entitlements != null) {
args.add("--entitlements");
args.add(entitlements.toString());

// Sign only if we have identity
if (signingIdentity != null) {
args = getCodesignArgs(false, p, signingIdentity,
identifierPrefix, entitlements, keyChain);
try {
Set<PosixFilePermission> oldPermissions
= Files.getPosixFilePermissions(p);
p.toFile().setWritable(true, true);
ProcessBuilder pb = new ProcessBuilder(args);
// run quietly
IOUtils.exec(pb, false, null, false,
Executor.INFINITE_TIMEOUT, true);
Files.setPosixFilePermissions(p, oldPermissions);
} catch (IOException ioe) {
toThrow.set(ioe);
}
}
args.add(p.toString());
try {
Set<PosixFilePermission> oldPermissions =
Files.getPosixFilePermissions(p);
p.toFile().setWritable(true, true);
ProcessBuilder pb = new ProcessBuilder(args);
// run quietly
IOUtils.exec(pb, false, null, false,
Executor.INFINITE_TIMEOUT, true);
Files.setPosixFilePermissions(p, oldPermissions);
} catch (IOException ioe) {
toThrow.set(ioe);
}
}
});
}
Expand All @@ -739,31 +771,19 @@ static void signAppBundle(
throw ioe;
}

// We cannot continue signing without identity
if (signingIdentity == null) {
return;
}

// sign all runtime and frameworks
Consumer<? super Path> signIdentifiedByPList = path -> {
//noinspection ThrowableResultOfMethodCallIgnored
if (toThrow.get() != null) return;

try {
List<String> args = new ArrayList<>();
args.addAll(Arrays.asList("/usr/bin/codesign",
"--timestamp",
"--options", "runtime",
"--force",
"-s", signingIdentity, // sign with this key
"--prefix", identifierPrefix,
// use the identifier as a prefix
"-vvvv"));

if (keyChain != null && !keyChain.isEmpty()) {
args.add("--keychain");
args.add(keyChain);
}
if (entitlements != null) {
args.add("--entitlements");
args.add(entitlements.toString());
}
args.add(path.toString());
List<String> args = getCodesignArgs(true, path, signingIdentity,
identifierPrefix, entitlements, keyChain);
ProcessBuilder pb = new ProcessBuilder(args);

IOUtils.exec(pb);
Expand Down Expand Up @@ -794,29 +814,10 @@ static void signAppBundle(
}

// sign the app itself
List<String> args = new ArrayList<>();
args.addAll(Arrays.asList("/usr/bin/codesign",
"--timestamp",
"--options", "runtime",
"--force",
"-s", signingIdentity,
"--prefix", identifierPrefix,
"-vvvv"));

if (keyChain != null && !keyChain.isEmpty()) {
args.add("--keychain");
args.add(keyChain);
}

if (entitlements != null) {
args.add("--entitlements");
args.add(entitlements.toString());
}

args.add(appLocation.toString());

ProcessBuilder pb =
new ProcessBuilder(args.toArray(new String[args.size()]));
List<String> args = getCodesignArgs(true, appLocation, signingIdentity,
identifierPrefix, entitlements, keyChain);
ProcessBuilder pb
= new ProcessBuilder(args.toArray(new String[args.size()]));

IOUtils.exec(pb);
}
Expand Down
4 changes: 4 additions & 0 deletions test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ public static boolean isOSX() {
return (OS.contains("mac"));
}

public static boolean isArmMac() {
return (isOSX() && "aarch64".equals(System.getProperty("os.arch")));
}

public static boolean isLinux() {
return ((OS.contains("nix") || OS.contains("nux")));
}
Expand Down
28 changes: 18 additions & 10 deletions test/jdk/tools/jpackage/macosx/SigningAppImageTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2022, 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
Expand All @@ -22,8 +22,11 @@
*/

import java.nio.file.Path;
import java.util.List;

import jdk.jpackage.test.JPackageCommand;
import jdk.jpackage.test.Annotations.Test;
import jdk.jpackage.test.Annotations.Parameter;
import jdk.jpackage.test.AdditionalLauncher;

/**
Expand Down Expand Up @@ -59,26 +62,31 @@
public class SigningAppImageTest {

@Test
public static void test() throws Exception {
@Parameter("true")
@Parameter("false")
public void test(boolean doSign) throws Exception {
SigningCheck.checkCertificates();

JPackageCommand cmd = JPackageCommand.helloAppImage();
cmd.addArguments("--mac-sign", "--mac-signing-key-user-name",
SigningBase.DEV_NAME, "--mac-signing-keychain",
SigningBase.KEYCHAIN);

if (doSign) {
cmd.addArguments("--mac-sign", "--mac-signing-key-user-name",
SigningBase.DEV_NAME, "--mac-signing-keychain",
SigningBase.KEYCHAIN);
}
AdditionalLauncher testAL = new AdditionalLauncher("testAL");
testAL.applyTo(cmd);
cmd.executeAndAssertHelloAppImageCreated();

Path launcherPath = cmd.appLauncherPath();
SigningBase.verifyCodesign(launcherPath, true);
SigningBase.verifyCodesign(launcherPath, doSign);

Path testALPath = launcherPath.getParent().resolve("testAL");
SigningBase.verifyCodesign(testALPath, true);
SigningBase.verifyCodesign(testALPath, doSign);

Path appImage = cmd.outputBundle();
SigningBase.verifyCodesign(appImage, true);
SigningBase.verifySpctl(appImage, "exec");
SigningBase.verifyCodesign(appImage, doSign);
if (doSign) {
SigningBase.verifySpctl(appImage, "exec");
}
}
}