8313904: [macos] All signing tests which verifies unsigned app images are failing

Reviewed-by: asemenyuk
This commit is contained in:
Alexander Matveev 2023-08-11 21:00:52 +00:00
parent 7332502883
commit ec0cc6300a
8 changed files with 94 additions and 36 deletions

View File

@ -715,7 +715,7 @@ public class MacAppImageBuilder extends AbstractAppImageBuilder {
return args;
}
private static void signAppBundle(
static void signAppBundle(
Map<String, ? super Object> params, Path appLocation,
String signingIdentity, String identifierPrefix, Path entitlements)
throws IOException {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2022, 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
@ -188,6 +188,12 @@ public abstract class MacBaseInstallerBundler extends AbstractBundler {
!AppImageFile.load(predefinedImage).isSigned()) {
new PackageFile(APP_NAME.fetchFrom(params)).save(
ApplicationLayout.macAppImage().resolveAt(appDir));
// We need to re-sign app image after adding ".package" to it.
// We only do this if app image was not signed which means it is
// signed with ad-hoc signature. App bundles with ad-hoc
// signature are sealed, but without a signing identity, so we
// need to re-sign it after modification.
MacAppImageBuilder.signAppBundle(params, appDir, "-", null, null);
}
} else {
appDir = appImageBundler.execute(params, appImageRoot);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 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
@ -79,7 +79,7 @@ public class SigningPackageFromTwoStepAppImageTest {
private static void verifyDMG(JPackageCommand cmd) {
// DMG always unsigned, so we will check it
Path outputBundle = cmd.outputBundle();
SigningBase.verifyCodesign(outputBundle, false);
SigningBase.verifyDMG(outputBundle);
}
private static void verifyAppImageInDMG(JPackageCommand cmd) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 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
@ -71,7 +71,7 @@ public class SigningPackageTest {
private static void verifyDMG(JPackageCommand cmd) {
Path outputBundle = cmd.outputBundle();
SigningBase.verifyCodesign(outputBundle, false);
SigningBase.verifyDMG(outputBundle);
}
private static void verifyAppImageInDMG(JPackageCommand cmd) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 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
@ -62,7 +62,7 @@ import jdk.jpackage.test.Annotations.Parameter;
* @build SigningPackageTwoStepTest
* @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=SigningPackageTwoStepTest
*/
public class SigningPackageTwoStepTest {
@ -80,7 +80,7 @@ public class SigningPackageTwoStepTest {
private static void verifyDMG(JPackageCommand cmd) {
// DMG always unsigned, so we will check it
Path outputBundle = cmd.outputBundle();
SigningBase.verifyCodesign(outputBundle, false);
SigningBase.verifyDMG(outputBundle);
}
private static void verifyAppImageInDMG(JPackageCommand cmd) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 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,35 +44,67 @@ public class SigningBase {
KEYCHAIN = (value == null) ? "jpackagerTest.keychain" : value;
}
// Note: It is not clear if we can combine "--verify" and "--display", so
// we testing them separately. Since JDK-8298488 unsigned app images are
// actually signed with adhoc signature and it will pass "--verify", so in
// addition we will check certificate name which was used to sign.
private static enum CodesignCheckType {
VERIFY, // Runs codesign with "--verify" to check signature and 0 exit code
VERIFY_UNSIGNED, // Runs codesign with "--verify" to check signature and 1 exit code
DISPLAY // Runs codesign with "--display --verbose=4" to get info about signature
};
private static void checkString(List<String> result, String lookupString) {
TKit.assertTextStream(lookupString).predicate(
(line, what) -> line.trim().contains(what)).apply(result.stream());
}
private static List<String> codesignResult(Path target, boolean signed) {
int exitCode = signed ? 0 : 1;
List<String> result = new Executor()
.setExecutable("/usr/bin/codesign")
.addArguments("--verify", "--deep", "--strict", "--verbose=2",
target.toString())
.saveOutput()
.execute(exitCode).getOutput();
return result;
private static List<String> codesignResult(Path target, CodesignCheckType type) {
int exitCode = 0;
Executor executor = new Executor().setExecutable("/usr/bin/codesign");
switch (type) {
case CodesignCheckType.VERIFY_UNSIGNED:
exitCode = 1;
case CodesignCheckType.VERIFY:
executor.addArguments("--verify", "--deep", "--strict",
"--verbose=2", target.toString());
break;
case CodesignCheckType.DISPLAY:
executor.addArguments("--display", "--verbose=4", target.toString());
break;
default:
TKit.error("Unknown CodesignCheckType: " + type);
break;
}
return executor.saveOutput().execute(exitCode).getOutput();
}
private static void verifyCodesignResult(List<String> result, Path target,
boolean signed) {
boolean signed, CodesignCheckType type) {
result.stream().forEachOrdered(TKit::trace);
if (signed) {
String lookupString = target.toString() + ": valid on disk";
checkString(result, lookupString);
lookupString = target.toString() + ": satisfies its Designated Requirement";
checkString(result, lookupString);
} else {
String lookupString = target.toString()
+ ": code object is not signed at all";
checkString(result, lookupString);
String lookupString;
switch (type) {
case CodesignCheckType.VERIFY:
lookupString = target.toString() + ": valid on disk";
checkString(result, lookupString);
lookupString = target.toString() + ": satisfies its Designated Requirement";
checkString(result, lookupString);
break;
case CodesignCheckType.VERIFY_UNSIGNED:
lookupString = target.toString() + ": code object is not signed at all";
checkString(result, lookupString);
break;
case CodesignCheckType.DISPLAY:
if (signed) {
lookupString = "Authority=" + APP_CERT;
} else {
lookupString = "Signature=adhoc";
}
checkString(result, lookupString);
break;
default:
TKit.error("Unknown CodesignCheckType: " + type);
break;
}
}
@ -132,8 +164,24 @@ public class SigningBase {
}
public static void verifyCodesign(Path target, boolean signed) {
List<String> result = codesignResult(target, signed);
verifyCodesignResult(result, target, signed);
List<String> result = codesignResult(target, CodesignCheckType.VERIFY);
verifyCodesignResult(result, target, signed, CodesignCheckType.VERIFY);
result = codesignResult(target, CodesignCheckType.DISPLAY);
verifyCodesignResult(result, target, signed, CodesignCheckType.DISPLAY);
}
// Since we no longer have unsigned app image, but we need to check
// DMG which is not adhoc or certificate signed and we cannot use verifyCodesign
// for this. verifyDMG() is introduced to check that DMG is unsigned.
// Should not be used to validated anything else.
public static void verifyDMG(Path target) {
if (!target.toString().toLowerCase().endsWith(".dmg")) {
TKit.error("Unexpected target: " + target);
}
List<String> result = codesignResult(target, CodesignCheckType.VERIFY_UNSIGNED);
verifyCodesignResult(result, target, false, CodesignCheckType.VERIFY_UNSIGNED);
}
public static void verifySpctl(Path target, String type) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 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
@ -99,7 +99,7 @@ public class AppContentTest {
}
})
// On macOS aarch64 we always signing app image and signing will fail, since
// On macOS we always signing app image and signing will fail, since
// test produces invalid app bundle.
.setExpectedExitCode(testPathArgs.contains(TEST_BAD) || TKit.isOSX() ? 1 : 0)
.run();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 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
@ -94,7 +94,11 @@ public class AppImagePackageTest {
if (TKit.isOSX()) {
cmd.addArguments("--mac-package-identifier", name);
}
}).run(Action.CREATE, Action.UNPACK);
})
// On macOS we always signing app image and signing will fail, since
// test produces invalid app bundle.
.setExpectedExitCode(TKit.isOSX() ? 1 : 0)
.run(Action.CREATE, Action.UNPACK);
// default: {CREATE, UNPACK, VERIFY}, but we can't verify foreign image
}