8266182: Automate manual steps listed in the test jdk/sun/security/pkcs12/ParamsTest.java
Reviewed-by: hchao, ssahoo, xuelei, weijun
This commit is contained in:
parent
0e3fde6c3c
commit
ed57cf1cf3
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,16 +23,28 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8076190 8242151 8153005
|
* @bug 8076190 8242151 8153005 8266182
|
||||||
* @library /test/lib
|
* @summary This is java keytool <-> openssl interop test. This test generates
|
||||||
|
* some openssl keystores on the fly, java operates on it and
|
||||||
|
* vice versa.
|
||||||
|
*
|
||||||
|
* Note: This test executes some openssl command, so need to set
|
||||||
|
* openssl path using system property "test.openssl.path" or it should
|
||||||
|
* be available in /usr/bin or /usr/local/bin
|
||||||
|
* Required OpenSSL version : OpenSSL 1.1.*
|
||||||
|
*
|
||||||
* @modules java.base/sun.security.pkcs
|
* @modules java.base/sun.security.pkcs
|
||||||
* java.base/sun.security.util
|
* java.base/sun.security.util
|
||||||
* @summary Customizing the generation of a PKCS12 keystore
|
* @library /test/lib
|
||||||
|
* @library /sun/security/pkcs11/
|
||||||
|
* @run main/othervm/timeout=600 KeytoolOpensslInteropTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import jdk.test.lib.Asserts;
|
import jdk.test.lib.Asserts;
|
||||||
import jdk.test.lib.SecurityTools;
|
import jdk.test.lib.SecurityTools;
|
||||||
|
import jdk.test.lib.process.ProcessTools;
|
||||||
import jdk.test.lib.process.OutputAnalyzer;
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
import jdk.test.lib.artifacts.OpensslArtifactFetcher;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -52,28 +64,79 @@ import static jdk.test.lib.security.DerUtils.*;
|
|||||||
import static sun.security.util.KnownOIDs.*;
|
import static sun.security.util.KnownOIDs.*;
|
||||||
import static sun.security.pkcs.ContentInfo.*;
|
import static sun.security.pkcs.ContentInfo.*;
|
||||||
|
|
||||||
public class ParamsTest {
|
public class KeytoolOpensslInteropTest {
|
||||||
|
|
||||||
public static void main(String[] args) throws Throwable {
|
public static void main(String[] args) throws Throwable {
|
||||||
|
String opensslPath = OpensslArtifactFetcher.getOpenssl1dot1dotStar();
|
||||||
// De-BASE64 textual files in ./params to `pwd`
|
if (opensslPath != null) {
|
||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(
|
// if preferred version of openssl is available perform all
|
||||||
Path.of(System.getProperty("test.src"), "params"),
|
// keytool <-> openssl interop tests
|
||||||
p -> !p.getFileName().toString().equals("README"))) {
|
generateInitialKeystores(opensslPath);
|
||||||
stream.forEach(p -> {
|
testWithJavaCommands();
|
||||||
try (InputStream is = Files.newInputStream(p);
|
testWithOpensslCommands(opensslPath);
|
||||||
OutputStream os = Files.newOutputStream(p.getFileName())) {
|
} else {
|
||||||
Base64.getMimeDecoder().wrap(is).transferTo(os);
|
// since preferred version of openssl is not available skip all
|
||||||
} catch (IOException e) {
|
// openssl command dependent tests with a warning
|
||||||
throw new UncheckedIOException(e);
|
System.out.println("\n\u001B[31mWarning: Can't find openssl "
|
||||||
}
|
+ "(version 1.1.*) binary on this machine, please install"
|
||||||
});
|
+ " and set openssl path with property "
|
||||||
|
+ "'test.openssl.path'. Now running only half portion of "
|
||||||
|
+ "the test, skipping all tests which depends on openssl "
|
||||||
|
+ "commands.\u001B[0m\n");
|
||||||
|
// De-BASE64 textual files in ./params to `pwd`
|
||||||
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(
|
||||||
|
Path.of(System.getProperty("test.src"), "params"),
|
||||||
|
p -> !p.getFileName().toString().equals("README"))) {
|
||||||
|
stream.forEach(p -> {
|
||||||
|
try (InputStream is = Files.newInputStream(p);
|
||||||
|
OutputStream os = Files.newOutputStream(
|
||||||
|
p.getFileName())) {
|
||||||
|
Base64.getMimeDecoder().wrap(is).transferTo(os);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UncheckedIOException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
testWithJavaCommands();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void generateInitialKeystores(String opensslPath)
|
||||||
|
throws Throwable {
|
||||||
|
keytool("-keystore ks -keyalg ec -genkeypair -storepass"
|
||||||
|
+ " changeit -alias a -dname CN=A").shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
ProcessTools.executeCommand(opensslPath, "pkcs12", "-in", "ks",
|
||||||
|
"-nodes", "-out", "kandc", "-passin", "pass:changeit")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
ProcessTools.executeCommand(opensslPath, "pkcs12", "-export", "-in",
|
||||||
|
"kandc", "-out", "os2", "-name", "a", "-passout",
|
||||||
|
"pass:changeit", "-certpbe", "NONE", "-nomac")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
ProcessTools.executeCommand(opensslPath, "pkcs12", "-export", "-in",
|
||||||
|
"kandc", "-out", "os3", "-name", "a", "-passout",
|
||||||
|
"pass:changeit", "-certpbe", "NONE")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
ProcessTools.executeCommand(opensslPath, "pkcs12", "-export", "-in",
|
||||||
|
"kandc", "-out", "os4", "-name", "a", "-passout",
|
||||||
|
"pass:changeit", "-certpbe", "PBE-SHA1-RC4-128", "-keypbe",
|
||||||
|
"PBE-SHA1-RC4-128", "-macalg", "SHA224")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
ProcessTools.executeCommand(opensslPath, "pkcs12", "-export", "-in",
|
||||||
|
"kandc", "-out", "os5", "-name", "a", "-passout",
|
||||||
|
"pass:changeit", "-certpbe", "AES-256-CBC", "-keypbe",
|
||||||
|
"AES-256-CBC", "-macalg", "SHA512")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testWithJavaCommands() throws Throwable {
|
||||||
byte[] data;
|
byte[] data;
|
||||||
|
|
||||||
// openssl -> keytool interop check
|
// openssl -> keytool interop check
|
||||||
|
|
||||||
// os2. no cert pbe, no mac.
|
// os2. no cert pbe, no mac.
|
||||||
check("os2", "a", null, "changeit", true, true, true);
|
check("os2", "a", null, "changeit", true, true, true);
|
||||||
check("os2", "a", "changeit", "changeit", true, true, true);
|
check("os2", "a", "changeit", "changeit", true, true, true);
|
||||||
@ -392,6 +455,74 @@ public class ParamsTest {
|
|||||||
.shouldHaveExitValue(0);
|
.shouldHaveExitValue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void testWithOpensslCommands(String opensslPath)
|
||||||
|
throws Throwable {
|
||||||
|
|
||||||
|
OutputAnalyzer output1 = ProcessTools.executeCommand(opensslPath,
|
||||||
|
"pkcs12", "-in", "ksnormal", "-passin", "pass:changeit",
|
||||||
|
"-info", "-nokeys", "-nocerts");
|
||||||
|
output1.shouldHaveExitValue(0)
|
||||||
|
.shouldContain("MAC: sha256, Iteration 10000")
|
||||||
|
.shouldContain("Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC,"
|
||||||
|
+ " Iteration 10000, PRF hmacWithSHA256")
|
||||||
|
.shouldContain("PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC,"
|
||||||
|
+ " Iteration 10000, PRF hmacWithSHA256");
|
||||||
|
|
||||||
|
OutputAnalyzer output2 = ProcessTools.executeCommand(opensslPath,
|
||||||
|
"pkcs12", "-in", "ksnormaldup", "-passin", "pass:changeit",
|
||||||
|
"-info", "-nokeys", "-nocerts");
|
||||||
|
output2.shouldHaveExitValue(0);
|
||||||
|
if(!output1.getStderr().equals(output2.getStderr())) {
|
||||||
|
throw new RuntimeException("Duplicate pkcs12 keystores"
|
||||||
|
+ " ksnormal & ksnormaldup show different info");
|
||||||
|
}
|
||||||
|
|
||||||
|
output1 = ProcessTools.executeCommand(opensslPath, "pkcs12", "-in",
|
||||||
|
"ksnopass", "-passin", "pass:changeit", "-info", "-nokeys",
|
||||||
|
"-nocerts");
|
||||||
|
output1.shouldNotHaveExitValue(0);
|
||||||
|
|
||||||
|
output1 = ProcessTools.executeCommand(opensslPath, "pkcs12", "-in",
|
||||||
|
"ksnopass", "-passin", "pass:changeit", "-info", "-nokeys",
|
||||||
|
"-nocerts", "-nomacver");
|
||||||
|
output1.shouldHaveExitValue(0)
|
||||||
|
.shouldNotContain("PKCS7 Encrypted data:")
|
||||||
|
.shouldContain("Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC,"
|
||||||
|
+ " Iteration 10000, PRF hmacWithSHA256")
|
||||||
|
.shouldContain("Shrouded Keybag: pbeWithSHA1And128BitRC4,"
|
||||||
|
+ " Iteration 10000");
|
||||||
|
|
||||||
|
output2 = ProcessTools.executeCommand(opensslPath, "pkcs12", "-in",
|
||||||
|
"ksnopassdup", "-passin", "pass:changeit", "-info", "-nokeys",
|
||||||
|
"-nocerts", "-nomacver");
|
||||||
|
output2.shouldHaveExitValue(0);
|
||||||
|
if(!output1.getStderr().equals(output2.getStderr())) {
|
||||||
|
throw new RuntimeException("Duplicate pkcs12 keystores"
|
||||||
|
+ " ksnopass & ksnopassdup show different info");
|
||||||
|
}
|
||||||
|
|
||||||
|
output1 = ProcessTools.executeCommand(opensslPath, "pkcs12", "-in",
|
||||||
|
"ksnewic", "-passin", "pass:changeit", "-info", "-nokeys",
|
||||||
|
"-nocerts");
|
||||||
|
output1.shouldHaveExitValue(0)
|
||||||
|
.shouldContain("MAC: sha256, Iteration 5555")
|
||||||
|
.shouldContain("Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC,"
|
||||||
|
+ " Iteration 7777, PRF hmacWithSHA256")
|
||||||
|
.shouldContain("Shrouded Keybag: pbeWithSHA1And128BitRC4,"
|
||||||
|
+ " Iteration 10000")
|
||||||
|
.shouldContain("PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC,"
|
||||||
|
+ " Iteration 6666, PRF hmacWithSHA256");
|
||||||
|
|
||||||
|
output2 = ProcessTools.executeCommand(opensslPath, "pkcs12", "-in",
|
||||||
|
"ksnewicdup", "-passin", "pass:changeit", "-info", "-nokeys",
|
||||||
|
"-nocerts");
|
||||||
|
output2.shouldHaveExitValue(0);
|
||||||
|
if(!output1.getStderr().equals(output2.getStderr())) {
|
||||||
|
throw new RuntimeException("Duplicate pkcs12 keystores"
|
||||||
|
+ " ksnewic & ksnewicdup show different info");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check keystore loading and key/cert reading.
|
* Check keystore loading and key/cert reading.
|
||||||
*
|
*
|
||||||
@ -447,7 +578,7 @@ public class ParamsTest {
|
|||||||
Asserts.assertEQ(expectedKey, actualKey, label + "-key");
|
Asserts.assertEQ(expectedKey, actualKey, label + "-key");
|
||||||
}
|
}
|
||||||
|
|
||||||
static OutputAnalyzer keytool(String s) throws Throwable {
|
private static OutputAnalyzer keytool(String s) throws Throwable {
|
||||||
return SecurityTools.keytool(s);
|
return SecurityTools.keytool(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
147
test/lib/jdk/test/lib/artifacts/OpensslArtifactFetcher.java
Normal file
147
test/lib/jdk/test/lib/artifacts/OpensslArtifactFetcher.java
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package jdk.test.lib.artifacts;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import jdk.test.lib.Platform;
|
||||||
|
import jdk.test.lib.process.ProcessTools;
|
||||||
|
import jdk.test.lib.artifacts.Artifact;
|
||||||
|
import jdk.test.lib.artifacts.ArtifactResolver;
|
||||||
|
import jdk.test.lib.artifacts.ArtifactResolverException;
|
||||||
|
|
||||||
|
public class OpensslArtifactFetcher {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the openssl binary path of version 1.1.*
|
||||||
|
*
|
||||||
|
* Openssl selection flow:
|
||||||
|
1. Check whether property test.openssl.path is set and it's the
|
||||||
|
preferred version(1.1.*) of openssl, then return that path.
|
||||||
|
2. Else look for already installed openssl (version 1.1.*) in system
|
||||||
|
path /usr/bin/openssl or /usr/local/bin/openssl, then return that
|
||||||
|
path.
|
||||||
|
3. Else try to download openssl (version 1.1.*) from the artifactory
|
||||||
|
and return that path, if download fails then return null.
|
||||||
|
*
|
||||||
|
* @return openssl binary path of version 1.1.*
|
||||||
|
*/
|
||||||
|
public static String getOpenssl1dot1dotStar() {
|
||||||
|
String version = "1.1.";
|
||||||
|
String path = getOpensslFromSystemProp(version);
|
||||||
|
if (path != null) {
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
path = getDefaultSystemOpensslPath(version);
|
||||||
|
if (path != null) {
|
||||||
|
return path;
|
||||||
|
} else if (Platform.is64bit()) {
|
||||||
|
if (Platform.isLinux()) {
|
||||||
|
path = fetchOpenssl(LINUX_X64.class);
|
||||||
|
} else if (Platform.isOSX()) {
|
||||||
|
path = fetchOpenssl(MACOSX_X64.class);
|
||||||
|
} else if (Platform.isWindows()) {
|
||||||
|
path = fetchOpenssl(WINDOWS_X64.class);
|
||||||
|
}
|
||||||
|
if (verifyOpensslVersion(path, version)) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getOpensslFromSystemProp(String version) {
|
||||||
|
String path = System.getProperty("test.openssl.path");
|
||||||
|
System.out.println("System Property - test.openssl.path: " + path);
|
||||||
|
if (!verifyOpensslVersion(path, version)) {
|
||||||
|
path = null;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getDefaultSystemOpensslPath(String version) {
|
||||||
|
if (verifyOpensslVersion("/usr/bin/openssl", version)) {
|
||||||
|
return "/usr/bin/openssl";
|
||||||
|
} else if (verifyOpensslVersion("/usr/local/bin/openssl", version)) {
|
||||||
|
return "/usr/local/bin/openssl";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean verifyOpensslVersion(String path, String version) {
|
||||||
|
if (path != null) {
|
||||||
|
try {
|
||||||
|
ProcessTools.executeCommand(path, "version")
|
||||||
|
.shouldHaveExitValue(0)
|
||||||
|
.shouldContain(version);
|
||||||
|
return true;
|
||||||
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String fetchOpenssl(Class<?> clazz) {
|
||||||
|
String path = null;
|
||||||
|
try {
|
||||||
|
path = ArtifactResolver.resolve(clazz).entrySet().stream()
|
||||||
|
.findAny().get().getValue() + File.separator + "openssl"
|
||||||
|
+ File.separator + "bin" + File.separator + "openssl";
|
||||||
|
System.out.println("path: " + path);
|
||||||
|
} catch (ArtifactResolverException e) {
|
||||||
|
Throwable cause = e.getCause();
|
||||||
|
if (cause == null) {
|
||||||
|
System.out.println("Cannot resolve artifact, "
|
||||||
|
+ "please check if JIB jar is present in classpath.");
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Fetch artifact failed: " + clazz
|
||||||
|
+ "\nPlease make sure the artifact is available.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Artifact(
|
||||||
|
organization = "jpg.tests.jdk.openssl",
|
||||||
|
name = "openssl-linux_x64",
|
||||||
|
revision = "1.1.1g",
|
||||||
|
extension = "zip")
|
||||||
|
private static class LINUX_X64 { }
|
||||||
|
|
||||||
|
@Artifact(
|
||||||
|
organization = "jpg.tests.jdk.openssl",
|
||||||
|
name = "openssl-macosx_x64",
|
||||||
|
revision = "1.1.1g",
|
||||||
|
extension = "zip")
|
||||||
|
private static class MACOSX_X64 { }
|
||||||
|
|
||||||
|
@Artifact(
|
||||||
|
organization = "jpg.tests.jdk.openssl",
|
||||||
|
name = "openssl-windows_x64",
|
||||||
|
revision = "1.1.1g",
|
||||||
|
extension = "zip")
|
||||||
|
private static class WINDOWS_X64 { }
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user