提交 ebb250fc 编写于 作者: A andrew

8225392: Comparison builds are failing due to cacerts file

Reviewed-by: shade
上级 d3243e3e
......@@ -25,14 +25,25 @@
package build.tools.generatecacerts;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* Generate cacerts
......@@ -41,22 +52,102 @@ import java.security.cert.CertificateFactory;
*/
public class GenerateCacerts {
public static void main(String[] args) throws Exception {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
try (FileOutputStream fos = new FileOutputStream(args[1])) {
store(args[0], fos, "changeit".toCharArray());
}
}
// The following code is copied from JavaKeyStore.java.
private static final int MAGIC = 0xfeedfeed;
private static final int VERSION_2 = 0x02;
// This method is a simplified version of JavaKeyStore::engineStore.
// A new "dir" argument is added. All cert names in "dir" is collected into
// a sorted array. Each cert is stored with a creation date set to its
// notBefore value. Thus the output is determined as long as the certs
// are the same.
public static void store(String dir, OutputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException
{
byte[] encoded; // the certificate encoding
CertificateFactory cf = CertificateFactory.getInstance("X509");
try (DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get(args[0]))) {
MessageDigest md = getPreKeyedHash(password);
DataOutputStream dos
= new DataOutputStream(new DigestOutputStream(stream, md));
dos.writeInt(MAGIC);
// always write the latest version
dos.writeInt(VERSION_2);
// All file names in dir sorted.
// README is excluded. Name starting with "." excluded.
SortedSet<String> entries = new TreeSet<String>();
try (DirectoryStream<Path> ds = Files.newDirectoryStream(Paths.get(dir))) {
for (Path p : ds) {
String fName = p.getFileName().toString();
if (!fName.equals("README")) {
String alias = fName + " [jdk]";
try (InputStream fis = Files.newInputStream(p)) {
ks.setCertificateEntry(alias, cf.generateCertificate(fis));
}
if (!fName.equals("README") && !fName.startsWith(".")) {
entries.add(fName);
}
}
}
try (FileOutputStream fos = new FileOutputStream(args[1])) {
ks.store(fos, "changeit".toCharArray());
dos.writeInt(entries.size());
for (String entry : entries) {
String alias = entry + " [jdk]";
X509Certificate cert;
try (InputStream fis = Files.newInputStream(Paths.get(dir, entry))) {
cert = (X509Certificate) cf.generateCertificate(fis);
}
dos.writeInt(2);
// Write the alias
dos.writeUTF(alias);
// Write the (entry creation) date, which is notBefore of the cert
dos.writeLong(cert.getNotBefore().getTime());
// Write the trusted certificate
encoded = cert.getEncoded();
dos.writeUTF(cert.getType());
dos.writeInt(encoded.length);
dos.write(encoded);
}
/*
* Write the keyed hash which is used to detect tampering with
* the keystore (such as deleting or modifying key or
* certificate entries).
*/
byte[] digest = md.digest();
dos.write(digest);
dos.flush();
}
private static MessageDigest getPreKeyedHash(char[] password)
throws NoSuchAlgorithmException, UnsupportedEncodingException
{
MessageDigest md = MessageDigest.getInstance("SHA");
byte[] passwdBytes = convertToBytes(password);
md.update(passwdBytes);
Arrays.fill(passwdBytes, (byte) 0x00);
md.update("Mighty Aphrodite".getBytes("UTF8"));
return md;
}
private static byte[] convertToBytes(char[] password) {
int i, j;
byte[] passwdBytes = new byte[password.length * 2];
for (i=0, j=0; i<password.length; i++) {
passwdBytes[j++] = (byte)(password[i] >> 8);
passwdBytes[j++] = (byte)password[i];
}
return passwdBytes;
}
}
......@@ -2246,9 +2246,9 @@ public final class Main {
out.println(form.format(source));
out.println();
for (Enumeration<String> e = keyStore.aliases();
e.hasMoreElements(); ) {
String alias = e.nextElement();
List<String> aliases = Collections.list(keyStore.aliases());
aliases.sort(String::compareTo);
for (String alias : aliases) {
doPrintEntry("<" + alias + ">", alias, out);
if (verbose || rfc) {
out.println(rb.getString("NEWLINE"));
......
......@@ -26,11 +26,13 @@
* @test
* @bug 8189131 8198240 8191844 8189949 8191031 8196141 8204923 8195774 8199779
* 8209452 8209506 8210432 8195793 8216577 8222089 8222133 8222137 8222136
* 8223499
* 8223499 8225392
* @summary Check root CA entries in cacerts file
*/
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.Certificate;
......@@ -52,6 +54,11 @@ public class VerifyCACerts {
// The numbers of certs now.
private static final int COUNT = 88;
// SHA-256 of cacerts, can be generated with
// shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95
private static final String CHECKSUM
= "4E:21:94:7C:1D:49:28:BB:34:B0:40:DF:AE:19:B4:41:C6:B5:8A:EE:EB:D5:DE:B4:EF:07:AF:63:18:73:A6:FE";
// map of cert alias to SHA-256 fingerprint
@SuppressWarnings("serial")
private static final Map<String, String> FINGERPRINT_MAP
......@@ -256,8 +263,16 @@ public class VerifyCACerts {
public static void main(String[] args) throws Exception {
System.out.println("cacerts file: " + CACERTS);
md = MessageDigest.getInstance("SHA-256");
byte[] data = Files.readAllBytes(Paths.get(CACERTS));
String checksum = toHexString(md.digest(data));
if (!checksum.equals(CHECKSUM)) {
atLeastOneFailed = true;
System.err.println("ERROR: wrong checksum\n" + checksum);
}
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(CACERTS), "changeit".toCharArray());
ks.load(new ByteArrayInputStream(data), "changeit".toCharArray());
// check the count of certs inside
if (ks.size() != COUNT) {
......
/*
* Copyright (c) 2019, 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.
*/
/**
* @test
* @bug 8225392
* @summary Comparison builds are failing due to cacerts file
* @library /lib/testlibrary
*/
import jdk.testlibrary.SecurityTools;
import java.util.Random;
public class ListOrder {
public static void main(String[] args) throws Throwable {
Random rand = new Random();
for (int i = 0; i < 10; i++) {
gen(String.format("a%02d", rand.nextInt(100)));
}
String last = "";
for (String line : SecurityTools.keytool(
"-keystore ks -storepass changeit -list").asLines()) {
if (line.contains("PrivateKeyEntry")) {
// This is the line starting with the alias
System.out.println(line);
if (line.compareTo(last) <= 0) {
throw new RuntimeException("Not ordered");
} else {
last = line;
}
}
}
}
static void gen(String a) throws Exception {
// Do not check result, there might be duplicated alias(es).
SecurityTools.keytool("-keystore ks -storepass changeit "
+ "-keyalg ec -genkeypair -alias " + a + " -dname CN=" + a);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册