提交 a9bdcaad 编写于 作者: W weijun

8011402: Move blacklisting certificate logic from hard code to data

Reviewed-by: erikj, mullan
上级 aa86257a
......@@ -70,9 +70,13 @@ POLICY_BUILD = $(LIBDIR)/security/java.policy
CACERTS_SRC = $(CACERTS_FILE)
CACERTS_BUILD = $(LIBDIR)/security/cacerts
BLACKLISTED_CERTS_SRC = $(TOPDIR)/src/share/lib/security/blacklisted.certs
BLACKLISTED_CERTS_BUILD = $(LIBDIR)/security/blacklisted.certs
ifndef OPENJDK
BLACKLIST_SRC = $(CLOSED_SHARE_SRC)/lib/security/blacklist
BLACKLIST_BUILD = $(LIBDIR)/security/blacklist
BLACKLISTED_CERTS_SRC += $(wildcard $(CLOSED_SHARE_SRC)/lib/security/blacklisted.certs)
TRUSTEDLIBS_SRC = $(CLOSED_SHARE_SRC)/lib/security/trusted.libraries
TRUSTEDLIBS_BUILD = $(LIBDIR)/security/trusted.libraries
endif
......@@ -85,9 +89,9 @@ FILES_class = $(FILES_java:%.java=$(CLASSBINDIR)/%.class)
include $(BUILDDIR)/common/Rules.gmk
ifdef OPENJDK
build: properties policy cacerts
build: properties policy cacerts blacklisted-certs
else
build: properties policy cacerts blacklist trustedlibs
build: properties policy cacerts blacklist blacklisted-certs trustedlibs
endif
install: all
......@@ -100,6 +104,8 @@ cacerts: classes $(CACERTS_BUILD)
blacklist: classes $(BLACKLIST_BUILD)
blacklisted-certs: classes $(BLACKLISTED_CERTS_BUILD)
trustedlibs: classes $(TRUSTEDLIBS_BUILD)
$(PROPS_BUILD): $(PROPS_SRC)
......@@ -114,12 +120,25 @@ $(CACERTS_BUILD): $(CACERTS_SRC)
$(BLACKLIST_BUILD): $(BLACKLIST_SRC)
$(install-file)
$(BLACKLISTED_CERTS_BUILD): $(BLACKLISTED_CERTS_SRC)
$(MKDIR) -p $(@D)
$(CAT) $^ | $(SED) '/^$$/d' | $(SORT) | $(UNIQ) > $@.tmp
$(GREP) -i Algorithm $@.tmp > $@
if [ `$(SED) -n -e "$$=" $@` != 1 ]; then \
$(ECHO) "Different algorithms defined in $^"; \
$(RM) $@ $@.tmp; \
false; \
fi
$(GREP) -iv Algorithm $@.tmp >> $@
$(RM) $@.tmp
$(TRUSTEDLIBS_BUILD): $(TRUSTEDLIBS_SRC)
$(install-file)
clean clobber:: .delete.classlist
$(RM) -r $(CLASSBINDIR)/java/security
$(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD) $(TRUSTEDLIBS_BUILD)
$(RM) $(PROPS_BUILD) $(POLICY_BUILD) $(CACERTS_BUILD) $(BLACKLIST_BUILD) \
$(BLACKLISTED_CERTS_BUILD) $(TRUSTEDLIBS_BUILD)
# Additional Rule for building sun.security.util
$(CLASSBINDIR)/%.class: $(SHARE_SRC)/sun/%.java
......
......@@ -382,11 +382,16 @@ COPY_FILES += $(CACERTS_DST)
##########################################################################################
BLACKLISTED_CERTS_SRC := $(JDK_TOPDIR)/src/share/lib/security/blacklisted.certs
BLACKLISTED_CERTS_DST := $(JDK_OUTPUTDIR)/lib/security/blacklisted.certs
ifndef OPENJDK
BLACKLIST_SRC := $(JDK_TOPDIR)/src/closed/share/lib/security/blacklist
BLACKLIST_DST := $(JDK_OUTPUTDIR)/lib/security/blacklist
BLACKLISTED_CERTS_SRC += $(wildcard $(JDK_TOPDIR)/src/closed/share/lib/security/blacklisted.certs)
TRUSTEDLIBS_SRC := $(JDK_TOPDIR)/src/closed/share/lib/security/trusted.libraries
TRUSTEDLIBS_DST := $(JDK_OUTPUTDIR)/lib/security/trusted.libraries
......@@ -402,6 +407,20 @@ COPY_FILES += $(TRUSTEDLIBS_DST)
endif
$(BLACKLISTED_CERTS_DST): $(BLACKLISTED_CERTS_SRC)
$(MKDIR) -p $(@D)
$(CAT) $^ | $(SED) '/^$$/d' | $(SORT) | $(UNIQ) > $@.tmp
$(GREP) -i Algorithm $@.tmp > $@
if [ `$(SED) -n -e "$$=" $@` != 1 ]; then \
$(ECHO) "Different algorithms defined in $^"; \
$(RM) $@ $@.tmp; \
false; \
fi
$(GREP) -iv Algorithm $@.tmp >> $@
$(RM) $@.tmp
COPY_FILES += $(BLACKLISTED_CERTS_DST)
##########################################################################################
ifndef OPENJDK
......
......@@ -66,6 +66,9 @@ public abstract class Certificate implements java.io.Serializable {
// the certificate type
private final String type;
/** Cache the hash code for the certiticate */
private int hash = -1; // Default to -1
/**
* Creates a certificate of the specified type.
*
......@@ -123,16 +126,16 @@ public abstract class Certificate implements java.io.Serializable {
* @return the hashcode value.
*/
public int hashCode() {
int retval = 0;
try {
byte[] certData = X509CertImpl.getEncodedInternal(this);
for (int i = 1; i < certData.length; i++) {
retval += certData[i] * i;
int h = hash;
if (h == -1) {
try {
h = Arrays.hashCode(X509CertImpl.getEncodedInternal(this));
} catch (CertificateException e) {
h = 0;
}
return retval;
} catch (CertificateException e) {
return retval;
hash = h;
}
return h;
}
/**
......
......@@ -37,6 +37,7 @@ import java.security.*;
import java.security.cert.*;
import java.security.cert.Certificate;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import javax.security.auth.x500.X500Principal;
......@@ -1913,4 +1914,45 @@ public class X509CertImpl extends X509Certificate implements DerEncoder {
}
return false;
}
private ConcurrentHashMap<String,String> fingerprints =
new ConcurrentHashMap<>(2);
public String getFingerprint(String algorithm) {
return fingerprints.computeIfAbsent(algorithm,
x -> getCertificateFingerPrint(x));
}
/**
* Gets the requested finger print of the certificate. The result
* only contains 0-9 and A-F. No small case, no colon.
*/
private String getCertificateFingerPrint(String mdAlg) {
String fingerPrint = "";
try {
byte[] encCertInfo = getEncoded();
MessageDigest md = MessageDigest.getInstance(mdAlg);
byte[] digest = md.digest(encCertInfo);
StringBuffer buf = new StringBuffer();
for (int i = 0; i < digest.length; i++) {
byte2hex(digest[i], buf);
}
fingerPrint = buf.toString();
} catch (NoSuchAlgorithmException | CertificateEncodingException e) {
// ignored
}
return fingerPrint;
}
/**
* Converts a byte to hex digit and writes to the supplied buffer
*/
private static void byte2hex(byte b, StringBuffer buf) {
char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F' };
int high = ((b & 0xf0) >> 4);
int low = (b & 0x0f);
buf.append(hexChars[high]);
buf.append(hexChars[low]);
}
}
/*
* Copyright (c) 2013, 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.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collection;
/**
* This is the tool to convert blacklisted.certs.pem to blacklisted.certs.
* Every time a new blacklisted certs is added, please append the PEM format
* to the end of blacklisted.certs.pem (with proper comments) and then use
* this tool to generate an updated blacklisted.certs. Make sure to include
* changes to both in a changeset.
*/
public class BlacklistedCertsConverter {
public static void main(String[] args) throws Exception {
if (args.length == 0) {
System.out.println("Usage: java BlacklistedCertsConverter SHA-256" +
" < blacklisted.certs.pem > blacklisted.certs");
System.exit(1);
}
String mdAlg = args[0];
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Collection<? extends Certificate> certs
= cf.generateCertificates(System.in);
System.out.println("Algorithm=" + mdAlg);
for (Certificate cert: certs) {
System.out.println(
getCertificateFingerPrint(mdAlg, (X509Certificate)cert));
}
}
/**
* Converts a byte to hex digit and writes to the supplied buffer
*/
private static void byte2hex(byte b, StringBuffer buf) {
char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F' };
int high = ((b & 0xf0) >> 4);
int low = (b & 0x0f);
buf.append(hexChars[high]);
buf.append(hexChars[low]);
}
/**
* Gets the requested finger print of the certificate.
*/
private static String getCertificateFingerPrint(String mdAlg,
X509Certificate cert) {
String fingerPrint = "";
try {
byte[] encCertInfo = cert.getEncoded();
MessageDigest md = MessageDigest.getInstance(mdAlg);
byte[] digest = md.digest(encCertInfo);
StringBuffer buf = new StringBuffer();
for (int i = 0; i < digest.length; i++) {
byte2hex(digest[i], buf);
}
fingerPrint = buf.toString();
} catch (NoSuchAlgorithmException | CertificateEncodingException e) {
// ignored
}
return fingerPrint;
}
}
Algorithm=SHA-256
76A45A496031E4DD2D7ED23E8F6FF97DBDEA980BAAC8B0BA94D7EDB551348645
4CBBF8256BC9888A8007B2F386940A2E394378B0D903CBB3863C5A6394B889CE
D24566BF315F4E597D6E381C87119FB4198F5E9E2607F5F4AB362EF7E2E7672F
14E6D2764A4B06701C6CBC376A253775F79C782FBCB6C0EE6F99DE4BA1024ADD
D3A936E1A7775A45217C8296A1F22AC5631DCDEC45594099E78EEEBBEDCBA967
5E83124D68D24E8E177E306DF643D5EA99C5A94D6FC34B072F7544A1CABB7C7B
9ED8F9B0E8E42A1656B8E1DD18F42BA42DC06FE52686173BA2FC70E756F207DC
FDEDB5BDFCB67411513A61AEE5CB5B5D7C52AF06028EFC996CC1B05B1D6CEA2B
A686FEE577C88AB664D0787ECDFFF035F4806F3DE418DC9E4D516324FFF02083
4FEE0163686ECBD65DB968E7494F55D84B25486D438E9DE558D629D28CD4D176
8A1BD21661C60015065212CC98B1ABB50DFD14C872A208E66BAE890F25C448AF
B8686723E415534BC0DBD16326F9486F85B0B0799BF6639334E61DAAE67F36CD
3946901F46B0071E90D78279E82FABABCA177231A704BE72C5B0E8918566EA66
31C8FD37DB9B56E708B03D1F01848B068C6DA66F36FB5D82C008C6040FA3E133
450F1B421BB05C8609854884559C323319619E8B06B001EA2DCBB74A23AA3BE2
FC02FD48DB92D4DCE6F11679D38354CF750CFC7F584A520EB90BDE80E241F2BD
DF21016B00FC54F9FE3BC8B039911BB216E9162FAD2FD14D990AB96E951B49BE
F5B6F88F75D391A4B1EB336F9E201239FB6B1377DB8CFA7B84736216E5AFFFD7
此差异已折叠。
/*
* Copyright (c) 2013, 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 8011402
* @summary Move blacklisting certificate logic from hard code to data
*/
import sun.security.util.UntrustedCertificates;
import java.io.*;
import java.security.KeyStore;
import java.security.cert.*;
import java.util.*;
public class CheckBlacklistedCerts {
public static void main(String[] args) throws Exception {
String home = System.getProperty("java.home");
boolean failed = false;
// Root CAs should always be trusted
File file = new File(home, "lib/security/cacerts");
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
try (FileInputStream fis = new FileInputStream(file)) {
ks.load(new FileInputStream(file), null);
}
System.out.println("Check for cacerts: " + ks.size());
for (String alias: Collections.list(ks.aliases())) {
X509Certificate cert = (X509Certificate)ks.getCertificate(alias);
if (UntrustedCertificates.isUntrusted(cert)) {
System.out.print(alias + " is untrusted");
failed = true;
}
}
// All certs in the pem files
Set<Certificate> blacklisted = new HashSet<>();
// Hopefully src comes with test, but it might be missing if doing
// a -testonly JPRT job.
File[] blacklists = {
new File(System.getProperty("test.src"),
"../../../src/share/lib/security/blacklisted.certs.pem"),
new File(System.getProperty("test.src"),
"../../../src/closed/share/lib/security/blacklisted.certs.pem")
};
// Is this an OPENJDK build?
if (!new File(home, "lib/security/local_policy.jar").exists()) {
blacklists = Arrays.copyOf(blacklists, 1);
}
CertificateFactory cf = CertificateFactory.getInstance("X.509");
for (File blacklist: blacklists) {
System.out.print("Check for " + blacklist + ": ");
if (!blacklist.exists()) {
System.out.println("does not exist");
} else {
try (FileInputStream fis = new FileInputStream(blacklist)) {
Collection<? extends Certificate> certs
= cf.generateCertificates(fis);
System.out.println(certs.size());
for (Certificate c: certs) {
blacklisted.add(c);
X509Certificate cert = ((X509Certificate)c);
if (!UntrustedCertificates.isUntrusted(cert)) {
System.out.println(cert.getSubjectDN() + " is trusted");
failed = true;
}
}
}
}
}
// Check the blacklisted.certs file itself
file = new File(home, "lib/security/blacklisted.certs");
System.out.print("Check for " + file + ": ");
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(file)))) {
int acount = 0;
int ccount = 0;
while (true) {
String line = reader.readLine();
if (line == null) break;
if (line.startsWith("Algorithm")) {
acount++;
} else if (!line.isEmpty() && !line.startsWith("#")) {
ccount++;
}
}
System.out.println(acount + " algs, " + ccount + " certs" );
if (acount != 1) {
System.out.println("There are " + acount + " algorithms");
failed = true;
}
if (ccount != blacklisted.size()
&& !blacklisted.isEmpty()) {
System.out.println("Wrong blacklisted.certs size: "
+ ccount + " fingerprints, "
+ blacklisted.size() + " certs");
failed = true;
}
}
if (failed) {
throw new Exception("Failed");
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册