Mercurial > hg > openjdk > jdk8u > jdk
changeset 11387:8bef978e2374 jdk8u76-b03
Merge
author | asaha |
---|---|
date | Fri, 15 Jan 2016 16:23:58 -0800 |
parents | 3fc3108f886f (current diff) 8fe85977d5a6 (diff) |
children | c7d016751fa5 |
files | src/share/classes/sun/security/ssl/ServerHandshaker.java src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java src/share/classes/sun/security/x509/X509CertImpl.java |
diffstat | 18 files changed, 272 insertions(+), 62 deletions(-) [+] |
line wrap: on
line diff
--- a/make/CompileDemos.gmk Tue Jan 05 08:49:57 2016 -0800 +++ b/make/CompileDemos.gmk Fri Jan 15 16:23:58 2016 -0800 @@ -229,7 +229,7 @@ BUILD_DEMO_JVMTI_$1_LANG := $4 endif ifeq (C++, $4) - $1_EXTRA_CXX := $(LDFLAGS_CXX_JDK) $(LIBCXX) + $1_EXTRA_CXX := $$(LDFLAGS_CXX_JDK) $(LIBCXX) endif $1_CXXFLAGS := $(CXXFLAGS_JDKLIB) -I$(JDK_TOPDIR)/src/share/demo/jvmti/$1 \ @@ -251,8 +251,8 @@ LANG := $$(BUILD_DEMO_JVMTI_$1_LANG), \ OPTIMIZATION := LOW, \ CXXFLAGS := $$($1_CXXFLAGS), \ - LDFLAGS := $(filter-out -incremental:no -opt:ref, $(LDFLAGS_JDKLIB)), \ - LDFLAGS_macosx := $(call SET_EXECUTABLE_ORIGIN), \ + LDFLAGS := $(filter-out -incremental:no -opt:ref, $$(LDFLAGS_JDKLIB)), \ + LDFLAGS_macosx := $$(call SET_EXECUTABLE_ORIGIN), \ LDFLAGS_SUFFIX := $$($1_EXTRA_CXX), \ LDFLAGS_SUFFIX_posix := $5, \ LDFLAGS_SUFFIX_windows := $6, \
--- a/src/share/classes/java/util/AbstractMap.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/java/util/AbstractMap.java Fri Jan 15 16:23:58 2016 -0800 @@ -304,9 +304,28 @@ * Each of these fields are initialized to contain an instance of the * appropriate view the first time this view is requested. The views are * stateless, so there's no reason to create more than one of each. + * + * <p>Since there is no synchronization performed while accessing these fields, + * it is expected that java.util.Map view classes using these fields have + * no non-final fields (or any fields at all except for outer-this). Adhering + * to this rule would make the races on these fields benign. + * + * <p>It is also imperative that implementations read the field only once, + * as in: + * + * <pre> {@code + * public Set<K> keySet() { + * Set<K> ks = keySet; // single racy read + * if (ks == null) { + * ks = new KeySet(); + * keySet = ks; + * } + * return ks; + * } + *}</pre> */ - transient volatile Set<K> keySet; - transient volatile Collection<V> values; + transient Set<K> keySet; + transient Collection<V> values; /** * {@inheritDoc} @@ -325,8 +344,9 @@ * method will not all return the same set. */ public Set<K> keySet() { - if (keySet == null) { - keySet = new AbstractSet<K>() { + Set<K> ks = keySet; + if (ks == null) { + ks = new AbstractSet<K>() { public Iterator<K> iterator() { return new Iterator<K>() { private Iterator<Entry<K,V>> i = entrySet().iterator(); @@ -361,8 +381,9 @@ return AbstractMap.this.containsKey(k); } }; + keySet = ks; } - return keySet; + return ks; } /** @@ -382,8 +403,9 @@ * method will not all return the same collection. */ public Collection<V> values() { - if (values == null) { - values = new AbstractCollection<V>() { + Collection<V> vals = values; + if (vals == null) { + vals = new AbstractCollection<V>() { public Iterator<V> iterator() { return new Iterator<V>() { private Iterator<Entry<K,V>> i = entrySet().iterator(); @@ -418,8 +440,9 @@ return AbstractMap.this.containsValue(v); } }; + values = vals; } - return values; + return vals; } public abstract Set<Entry<K,V>> entrySet();
--- a/src/share/classes/java/util/EnumMap.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/java/util/EnumMap.java Fri Jan 15 16:23:58 2016 -0800 @@ -380,10 +380,11 @@ */ public Set<K> keySet() { Set<K> ks = keySet; - if (ks != null) - return ks; - else - return keySet = new KeySet(); + if (ks == null) { + ks = new KeySet(); + keySet = ks; + } + return ks; } private class KeySet extends AbstractSet<K> { @@ -418,10 +419,11 @@ */ public Collection<V> values() { Collection<V> vs = values; - if (vs != null) - return vs; - else - return values = new Values(); + if (vs == null) { + vs = new Values(); + values = vs; + } + return vs; } private class Values extends AbstractCollection<V> {
--- a/src/share/classes/java/util/HashMap.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/java/util/HashMap.java Fri Jan 15 16:23:58 2016 -0800 @@ -902,8 +902,12 @@ * @return a set view of the keys contained in this map */ public Set<K> keySet() { - Set<K> ks; - return (ks = keySet) == null ? (keySet = new KeySet()) : ks; + Set<K> ks = keySet; + if (ks == null) { + ks = new KeySet(); + keySet = ks; + } + return ks; } final class KeySet extends AbstractSet<K> { @@ -949,8 +953,12 @@ * @return a view of the values contained in this map */ public Collection<V> values() { - Collection<V> vs; - return (vs = values) == null ? (values = new Values()) : vs; + Collection<V> vs = values; + if (vs == null) { + vs = new Values(); + values = vs; + } + return vs; } final class Values extends AbstractCollection<V> {
--- a/src/share/classes/java/util/IdentityHashMap.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/java/util/IdentityHashMap.java Fri Jan 15 16:23:58 2016 -0800 @@ -964,10 +964,11 @@ */ public Set<K> keySet() { Set<K> ks = keySet; - if (ks != null) - return ks; - else - return keySet = new KeySet(); + if (ks == null) { + ks = new KeySet(); + keySet = ks; + } + return ks; } private class KeySet extends AbstractSet<K> { @@ -1069,10 +1070,11 @@ */ public Collection<V> values() { Collection<V> vs = values; - if (vs != null) - return vs; - else - return values = new Values(); + if (vs == null) { + vs = new Values(); + values = vs; + } + return vs; } private class Values extends AbstractCollection<V> {
--- a/src/share/classes/java/util/LinkedHashMap.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/java/util/LinkedHashMap.java Fri Jan 15 16:23:58 2016 -0800 @@ -528,8 +528,12 @@ * @return a set view of the keys contained in this map */ public Set<K> keySet() { - Set<K> ks; - return (ks = keySet) == null ? (keySet = new LinkedKeySet()) : ks; + Set<K> ks = keySet; + if (ks == null) { + ks = new LinkedKeySet(); + keySet = ks; + } + return ks; } final class LinkedKeySet extends AbstractSet<K> { @@ -577,8 +581,12 @@ * @return a view of the values contained in this map */ public Collection<V> values() { - Collection<V> vs; - return (vs = values) == null ? (values = new LinkedValues()) : vs; + Collection<V> vs = values; + if (vs == null) { + vs = new LinkedValues(); + values = vs; + } + return vs; } final class LinkedValues extends AbstractCollection<V> {
--- a/src/share/classes/java/util/TreeMap.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/java/util/TreeMap.java Fri Jan 15 16:23:58 2016 -0800 @@ -855,7 +855,11 @@ */ public Collection<V> values() { Collection<V> vs = values; - return (vs != null) ? vs : (values = new Values()); + if (vs == null) { + vs = new Values(); + values = vs; + } + return vs; } /**
--- a/src/share/classes/java/util/WeakHashMap.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/java/util/WeakHashMap.java Fri Jan 15 16:23:58 2016 -0800 @@ -865,7 +865,11 @@ */ public Set<K> keySet() { Set<K> ks = keySet; - return (ks != null ? ks : (keySet = new KeySet())); + if (ks == null) { + ks = new KeySet(); + keySet = ks; + } + return ks; } private class KeySet extends AbstractSet<K> { @@ -914,7 +918,11 @@ */ public Collection<V> values() { Collection<V> vs = values; - return (vs != null) ? vs : (values = new Values()); + if (vs == null) { + vs = new Values(); + values = vs; + } + return vs; } private class Values extends AbstractCollection<V> {
--- a/src/share/classes/sun/security/pkcs10/PKCS10.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/sun/security/pkcs10/PKCS10.java Fri Jan 15 16:23:58 2016 -0800 @@ -290,8 +290,9 @@ throw new SignatureException("Cert request was not signed"); + byte[] CRLF = new byte[] {'\r', '\n'}; out.println("-----BEGIN NEW CERTIFICATE REQUEST-----"); - out.println(Base64.getMimeEncoder().encodeToString(encoded)); + out.println(Base64.getMimeEncoder(64, CRLF).encodeToString(encoded)); out.println("-----END NEW CERTIFICATE REQUEST-----"); }
--- a/src/share/classes/sun/security/provider/X509Factory.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/sun/security/provider/X509Factory.java Fri Jan 15 16:23:58 2016 -0800 @@ -28,6 +28,8 @@ import java.io.*; import java.util.*; import java.security.cert.*; + +import sun.security.util.Pem; import sun.security.x509.X509CertImpl; import sun.security.x509.X509CRLImpl; import sun.security.pkcs.PKCS7; @@ -633,7 +635,7 @@ checkHeaderFooter(header.toString(), footer.toString()); - return Base64.getMimeDecoder().decode(new String(data, 0, pos)); + return Pem.decode(new String(data, 0, pos)); } }
--- a/src/share/classes/sun/security/ssl/HandshakeHash.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/sun/security/ssl/HandshakeHash.java Fri Jan 15 16:23:58 2016 -0800 @@ -246,7 +246,7 @@ try { return cloneDigest(finMD).digest(); } catch (Exception e) { - throw new Error("BAD"); + throw new Error("Error during hash calculation", e); } } }
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java Fri Jan 15 16:23:58 2016 -0800 @@ -1259,8 +1259,8 @@ } } - // need EC cert signed using EC - if (setupPrivateKeyAndChain("EC_EC") == false) { + // need EC cert + if (setupPrivateKeyAndChain("EC") == false) { return false; } if (setupEphemeralECDHKeys() == false) { @@ -1268,15 +1268,15 @@ } break; case K_ECDH_RSA: - // need EC cert signed using RSA - if (setupPrivateKeyAndChain("EC_RSA") == false) { + // need EC cert + if (setupPrivateKeyAndChain("EC") == false) { return false; } setupStaticECDHKeys(); break; case K_ECDH_ECDSA: - // need EC cert signed using EC - if (setupPrivateKeyAndChain("EC_EC") == false) { + // need EC cert + if (setupPrivateKeyAndChain("EC") == false) { return false; } setupStaticECDHKeys();
--- a/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Fri Jan 15 16:23:58 2016 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2016, 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 @@ -152,13 +152,11 @@ getSupportedAlgorithms(AlgorithmConstraints constraints) { Collection<SignatureAndHashAlgorithm> supported = new ArrayList<>(); - synchronized (priorityMap) { - for (SignatureAndHashAlgorithm sigAlg : priorityMap.values()) { - if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM && - constraints.permits(SIGNATURE_PRIMITIVE_SET, - sigAlg.algorithm, null)) { - supported.add(sigAlg); - } + for (SignatureAndHashAlgorithm sigAlg : priorityMap.values()) { + if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM && + constraints.permits(SIGNATURE_PRIMITIVE_SET, + sigAlg.algorithm, null)) { + supported.add(sigAlg); } }
--- a/src/share/classes/sun/security/tools/keytool/Main.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/sun/security/tools/keytool/Main.java Fri Jan 15 16:23:58 2016 -0800 @@ -79,6 +79,7 @@ import sun.security.tools.KeyStoreUtil; import sun.security.tools.PathList; import sun.security.util.DerValue; +import sun.security.util.Pem; import sun.security.x509.*; import static java.security.KeyStore.*; @@ -99,6 +100,8 @@ */ public final class Main { + private static final byte[] CRLF = new byte[] {'\r', '\n'}; + private boolean debug = false; private Command command = null; private String sigAlgName = null; @@ -1205,7 +1208,7 @@ sb.append(s); } } - byte[] rawReq = Base64.getMimeDecoder().decode(new String(sb)); + byte[] rawReq = Pem.decode(new String(sb)); PKCS10 req = new PKCS10(rawReq); info.set(X509CertInfo.KEY, new CertificateX509Key(req.getSubjectPublicKeyInfo())); @@ -1282,7 +1285,7 @@ crl.sign(privateKey, sigAlgName); if (rfc) { out.println("-----BEGIN X509 CRL-----"); - out.println(Base64.getMimeEncoder().encodeToString(crl.getEncodedInternal())); + out.println(Base64.getMimeEncoder(64, CRLF).encodeToString(crl.getEncodedInternal())); out.println("-----END X509 CRL-----"); } else { out.write(crl.getEncodedInternal()); @@ -2251,7 +2254,7 @@ if (rfc) { X509CRL xcrl = (X509CRL)crl; out.println("-----BEGIN X509 CRL-----"); - out.println(Base64.getMimeEncoder().encodeToString(xcrl.getEncoded())); + out.println(Base64.getMimeEncoder(64, CRLF).encodeToString(xcrl.getEncoded())); out.println("-----END X509 CRL-----"); } else { out.println(crl.toString()); @@ -2278,7 +2281,7 @@ sb.append(s); } } - PKCS10 req = new PKCS10(Base64.getMimeDecoder().decode(new String(sb))); + PKCS10 req = new PKCS10(Pem.decode(new String(sb))); PublicKey pkey = req.getSubjectPublicKeyInfo(); out.printf(rb.getString("PKCS.10.Certificate.Request.Version.1.0.Subject.s.Public.Key.s.format.s.key."), @@ -3059,7 +3062,7 @@ { if (rfc) { out.println(X509Factory.BEGIN_CERT); - out.println(Base64.getMimeEncoder().encodeToString(cert.getEncoded())); + out.println(Base64.getMimeEncoder(64, CRLF).encodeToString(cert.getEncoded())); out.println(X509Factory.END_CERT); } else { out.write(cert.getEncoded()); // binary
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/security/util/Pem.java Fri Jan 15 16:23:58 2016 -0800 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 sun.security.util; + +import java.io.IOException; +import java.util.Base64; + +/** + * The Length interface defines the length of an object + */ +public class Pem { + + /** + * Decodes a PEM-encoded block. + * + * @param input the input string, according to RFC 1421, can only contain + * characters in the base-64 alphabet and whitespaces. + * @return the decoded bytes + * @throws java.io.IOException if input is invalid + */ + public static byte[] decode(String input) throws IOException { + byte[] src = input.replaceAll("\\s+", "").getBytes(); + try { + return Base64.getDecoder().decode(src); + } catch (IllegalArgumentException e) { + throw new IOException(e); + } + } +}
--- a/src/share/classes/sun/security/x509/X509CertImpl.java Tue Jan 05 08:49:57 2016 -0800 +++ b/src/share/classes/sun/security/x509/X509CertImpl.java Fri Jan 15 16:23:58 2016 -0800 @@ -271,7 +271,7 @@ der = new DerValue(decstream.toByteArray()); break; } else { - decstream.write(Base64.getMimeDecoder().decode(line)); + decstream.write(Pem.decode(line)); } } } catch (IOException ioe2) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/provider/X509Factory/BadPem.java Fri Jan 15 16:23:58 2016 -0800 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, 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 8074935 + * @summary jdk8 keytool doesn't validate pem files for RFC 1421 correctness, as jdk7 did + */ + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.security.KeyStore; +import java.security.cert.CertificateException; +import java.util.Arrays; +import java.util.Base64; + +import sun.security.provider.X509Factory; +import java.security.cert.CertificateFactory; +import java.io.ByteArrayInputStream; + +public class BadPem { + + public static void main(String[] args) throws Exception { + String ks = System.getProperty("test.src", ".") + + "/../../ssl/etc/keystore"; + String pass = "passphrase"; + String alias = "dummy"; + + KeyStore keyStore = KeyStore.getInstance("JKS"); + keyStore.load(new FileInputStream(ks), pass.toCharArray()); + byte[] cert = keyStore.getCertificate(alias).getEncoded(); + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + PrintStream pout = new PrintStream(bout); + byte[] CRLF = new byte[] {'\r', '\n'}; + pout.println(X509Factory.BEGIN_CERT); + for (int i=0; i<cert.length; i += 48) { + int blockLen = (cert.length > i + 48) ? 48 : (cert.length - i); + pout.println("!" + Base64.getEncoder() + .encodeToString(Arrays.copyOfRange(cert, i, i + blockLen))); + } + pout.println(X509Factory.END_CERT); + + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + try { + cf.generateCertificate(new ByteArrayInputStream(bout.toByteArray())); + throw new Exception("Should fail"); + } catch (CertificateException e) { + // Good + } + } +} +
--- a/test/sun/security/tools/keytool/KeyToolTest.java Tue Jan 05 08:49:57 2016 -0800 +++ b/test/sun/security/tools/keytool/KeyToolTest.java Fri Jan 15 16:23:58 2016 -0800 @@ -55,6 +55,8 @@ * NSS PKCS11 config file are changed, DSA not supported now. */ +import java.nio.file.Files; +import java.nio.file.Paths; import java.security.KeyStore; import sun.security.x509.*; import java.io.*; @@ -844,6 +846,24 @@ remove("mykey.cert"); } + // 8074935: jdk8 keytool doesn't validate pem files for RFC 1421 correctness + static void checkPem(String file) throws Exception { + boolean maybeLast = false; + for (String s: Files.readAllLines(Paths.get(file))) { + if (s.isEmpty()) continue; + if (s.startsWith("---")) continue; + if (maybeLast) { + throw new Exception("Last line already seen"); + } + if (s.length() > 64) { + throw new Exception(s); + } + if (s.length() < 64) { + maybeLast = true; + } + } + } + void v3extTest(String keyAlg) throws Exception { KeyStore ks; remove("x.jks"); @@ -1153,11 +1173,14 @@ "-rfc -file test.req"); // printcertreq testOK("", "-printcertreq -file test.req"); - // issue: deny KU, change criticality of 1.2.3 and 1.2.4, change content of BC, add 2.3.4 + checkPem("test.req"); + // issue: deny KU, change criticality of 1.2.3 and 1.2.4, + // change content of BC, add 2.3.4 testOK("", simple+"-gencert -alias ca -infile test.req -ext " + "honored=all,-KU,1.2.3:critical,1.2.4:non-critical " + "-ext BC=2 -ext 2.3.4=01020304 " + "-debug -rfc -outfile test.cert"); + checkPem("test.cert"); testOK("", simple+"-importcert -file test.cert -alias a"); ks = loadStore("x.jks", "changeit", "JKS"); X509CertImpl a = (X509CertImpl)ks.getCertificate("a");