# HG changeset patch # User andrew # Date 1619138858 -3600 # Node ID 3df509b41e518e46c359d782b691d6974b8a3ea0 # Parent 1bb0d5a206febd3beaa8c694eb16016bc6621bec# Parent bbffc81f10de05b68379b7d3422e5c50875ecaab Merge diff -r 1bb0d5a206fe -r 3df509b41e51 .hgtags --- a/.hgtags Fri Mar 26 17:13:49 2021 +0000 +++ b/.hgtags Fri Apr 23 01:47:38 2021 +0100 @@ -1079,3 +1079,7 @@ 7c8bbbfe6acbe08eadae04e1ec46d94e9f98b743 jdk8u292-b05 42f6981cebc518fd4d33f8d55351b32dbd900478 jdk8u292-b06 99b8202e7f718c01393f373609615a9c2721abe3 jdk8u292-b07 +d103481ecd91690051bbd06e4eb4d3f3b4938dfc jdk8u292-b08 +364cf530fbd346293f4fe51e725b1b3a807fd30f jdk8u292-b09 +4eae74c62a511317a50759f5faad3e748d34be95 jdk8u292-b10 +4eae74c62a511317a50759f5faad3e748d34be95 jdk8u292-ga diff -r 1bb0d5a206fe -r 3df509b41e51 make/data/tzdata/VERSION --- a/make/data/tzdata/VERSION Fri Mar 26 17:13:49 2021 +0000 +++ b/make/data/tzdata/VERSION Fri Apr 23 01:47:38 2021 +0100 @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2020f +tzdata2021a diff -r 1bb0d5a206fe -r 3df509b41e51 make/data/tzdata/africa --- a/make/data/tzdata/africa Fri Mar 26 17:13:49 2021 +0000 +++ b/make/data/tzdata/africa Fri Apr 23 01:47:38 2021 +0100 @@ -1550,11 +1550,17 @@ 3:00 - EAT 2017 Nov 1 2:00 - CAT +# From Steffen Thorsen (2021-01-18): +# "South Sudan will change its time zone by setting the clock back 1 +# hour on February 1, 2021...." +# from https://eyeradio.org/south-sudan-adopts-new-time-zone-makuei/ + # South Sudan # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Juba 2:06:28 - LMT 1931 2:00 Sudan CA%sT 2000 Jan 15 12:00 - 3:00 - EAT + 3:00 - EAT 2021 Feb 1 00:00 + 2:00 - CAT # Tanzania # See Africa/Nairobi. diff -r 1bb0d5a206fe -r 3df509b41e51 make/data/tzdata/leapseconds --- a/make/data/tzdata/leapseconds Fri Mar 26 17:13:49 2021 +0000 +++ b/make/data/tzdata/leapseconds Fri Apr 23 01:47:38 2021 +0100 @@ -95,11 +95,11 @@ # Any additional leap seconds will come after this. # This Expires line is commented out for now, # so that pre-2020a zic implementations do not reject this file. -#Expires 2021 Jun 28 00:00:00 +#Expires 2021 Dec 28 00:00:00 # POSIX timestamps for the data in this file: #updated 1467936000 (2016-07-08 00:00:00 UTC) -#expires 1624838400 (2021-06-28 00:00:00 UTC) +#expires 1640649600 (2021-12-28 00:00:00 UTC) -# Updated through IERS Bulletin C60 -# File expires on: 28 June 2021 +# Updated through IERS Bulletin C61 +# File expires on: 28 December 2021 diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/com/sun/jndi/ldap/Obj.java --- a/src/share/classes/com/sun/jndi/ldap/Obj.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/com/sun/jndi/ldap/Obj.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2020, 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 @@ -235,6 +235,9 @@ String[] codebases = getCodebases(attrs.get(JAVA_ATTRIBUTES[CODEBASE])); try { if ((attr = attrs.get(JAVA_ATTRIBUTES[SERIALIZED_DATA])) != null) { + if (!VersionHelper12.isSerialDataAllowed()) { + throw new NamingException("Object deserialization is not allowed"); + } ClassLoader cl = helper.getURLClassLoader(codebases); return deserializeObject((byte[])attr.get(), cl); } else if ((attr = attrs.get(JAVA_ATTRIBUTES[REMOTE_LOC])) != null) { diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/com/sun/jndi/ldap/VersionHelper12.java --- a/src/share/classes/com/sun/jndi/ldap/VersionHelper12.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/com/sun/jndi/ldap/VersionHelper12.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2020, 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 @@ -39,19 +39,48 @@ private static final String TRUST_URL_CODEBASE_PROPERTY = "com.sun.jndi.ldap.object.trustURLCodebase"; + // System property to control whether classes are allowed to be loaded from + // 'javaSerializedData' attribute + private static final String TRUST_SERIAL_DATA_PROPERTY = + "com.sun.jndi.ldap.object.trustSerialData"; + + /** + * Determines whether objects may be deserialized from the content of + * 'javaSerializedData' attribute. + */ + private static final boolean trustSerialData; + // Determine whether classes may be loaded from an arbitrary URL code base. - private static final String trustURLCodebase = - AccessController.doPrivileged( - new PrivilegedAction() { - public String run() { - return System.getProperty(TRUST_URL_CODEBASE_PROPERTY, - "false"); - } - } - ); + private static final boolean trustURLCodebase; + + static { + String trust = getPrivilegedProperty(TRUST_URL_CODEBASE_PROPERTY, "false"); + trustURLCodebase = "true".equalsIgnoreCase(trust); + String trustSDString = getPrivilegedProperty(TRUST_SERIAL_DATA_PROPERTY, "true"); + trustSerialData = "true".equalsIgnoreCase(trustSDString); + } + + private static String getPrivilegedProperty(String propertyName, String defaultVal) { + PrivilegedAction action = () -> System.getProperty(propertyName, defaultVal); + if (System.getSecurityManager() == null) { + return action.run(); + } else { + return AccessController.doPrivileged(action); + } + } VersionHelper12() {} // Disallow external from creating one of these. + /** + * Returns true if deserialization of objects from 'javaSerializedData' + * LDAP attribute is allowed. + * + * @return true if deserialization is allowed; false - otherwise + */ + public static boolean isSerialDataAllowed() { + return trustSerialData; + } + ClassLoader getURLClassLoader(String[] url) throws MalformedURLException { ClassLoader parent = getContextClassLoader(); @@ -60,7 +89,7 @@ * the system property com.sun.jndi.ldap.object.trustURLCodebase * has been set to "true". */ - if (url != null && "true".equalsIgnoreCase(trustURLCodebase)) { + if (url != null && trustURLCodebase) { return URLClassLoader.newInstance(getUrlArray(url), parent); } else { return parent; diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/com/sun/naming/internal/ObjectFactoriesFilter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/naming/internal/ObjectFactoriesFilter.java Fri Apr 23 01:47:38 2021 +0100 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020, 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 com.sun.naming.internal; + +import javax.naming.Reference; + +import sun.misc.ObjectInputFilter; +import sun.misc.ObjectInputFilter.FilterInfo; +import sun.misc.ObjectInputFilter.Status; + +import sun.security.util.SecurityProperties; + +/** + * This class implements the filter that validates object factories classes instantiated + * during {@link Reference} lookups. + * There is one system-wide filter instance per VM that can be set via + * the {@code "jdk.jndi.object.factoriesFilter"} system property value, or via + * setting the property in the security properties file. The system property value supersedes + * the security property value. If none of the properties are specified the default + * "*" value is used. + * The filter is implemented as {@link ObjectInputFilter} with capabilities limited to the + * validation of a factory's class types only ({@linkplain FilterInfo#serialClass()}). + * Array length, number of object references, depth, and stream size filtering capabilities are + * not supported by the filter. + */ +public final class ObjectFactoriesFilter { + + /** + * Checks if serial filter configured with {@code "jdk.jndi.object.factoriesFilter"} + * system property value allows instantiation of the specified objects factory class. + * If the filter result is not {@linkplain Status#REJECTED REJECTED}, the filter will + * allow the instantiation of objects factory class. + * + * @param factoryClass objects factory class + * @return true - if the factory is allowed to be instantiated; false - otherwise + */ + public static boolean canInstantiateObjectsFactory(Class factoryClass) { + return checkInput(() -> factoryClass); + } + + private static boolean checkInput(FactoryInfo factoryInfo) { + Status result = GLOBAL.checkInput(factoryInfo); + return result != Status.REJECTED; + } + + // FilterInfo to check if objects factory class is allowed by the system-wide + // filter. Array length, number of object references, depth, and stream size + // capabilities are ignored. + @FunctionalInterface + private interface FactoryInfo extends FilterInfo { + @Override + default long arrayLength() { + return -1; + } + + @Override + default long depth() { + return 1; + } + + @Override + default long references() { + return 0; + } + + @Override + default long streamBytes() { + return 0; + } + } + + // Prevent instantiation of the factories filter class + private ObjectFactoriesFilter() { + throw new InternalError("Not instantiable"); + } + + // System property name that contains the patterns to filter object factory names + private static final String FACTORIES_FILTER_PROPNAME = "jdk.jndi.object.factoriesFilter"; + + // Default system property value that allows the load of any object factory classes + private static final String DEFAULT_SP_VALUE = "*"; + + // System wide object factories filter constructed from the system property + private static final ObjectInputFilter GLOBAL = + ObjectInputFilter.Config.createFilter(getFilterPropertyValue()); + + // Get security or system property value + private static String getFilterPropertyValue() { + String propVal = SecurityProperties.privilegedGetOverridable(FACTORIES_FILTER_PROPNAME); + return propVal != null ? propVal : DEFAULT_SP_VALUE; + } +} diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/com/sun/naming/internal/VersionHelper.java --- a/src/share/classes/com/sun/naming/internal/VersionHelper.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/com/sun/naming/internal/VersionHelper.java Fri Apr 23 01:47:38 2021 +0100 @@ -77,6 +77,9 @@ return helper; } + public abstract Class loadClassWithoutInit(String className) + throws ClassNotFoundException; + public abstract Class loadClass(String className) throws ClassNotFoundException; diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/com/sun/naming/internal/VersionHelper12.java --- a/src/share/classes/com/sun/naming/internal/VersionHelper12.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/com/sun/naming/internal/VersionHelper12.java Fri Apr 23 01:47:38 2021 +0100 @@ -61,6 +61,10 @@ return loadClass(className, getContextClassLoader()); } + public Class loadClassWithoutInit(String className) throws ClassNotFoundException { + return loadClass(className, false, getContextClassLoader()); + } + /** * Determines whether classes may be loaded from an arbitrary URL code base. */ @@ -86,10 +90,15 @@ * This internal method is used with Thread Context Class Loader (TCCL), * please don't expose this method as public. */ + Class loadClass(String className, boolean initialize, ClassLoader cl) + throws ClassNotFoundException { + Class cls = Class.forName(className, initialize, cl); + return cls; + } + Class loadClass(String className, ClassLoader cl) throws ClassNotFoundException { - Class cls = Class.forName(className, true, cl); - return cls; + return loadClass(className, true, cl); } /** diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/java/io/File.java --- a/src/share/classes/java/io/File.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/java/io/File.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -500,6 +500,9 @@ public File getParentFile() { String p = this.getParent(); if (p == null) return null; + if (getClass() != File.class) { + p = fs.normalize(p); + } return new File(p, this.prefixLength); } @@ -572,6 +575,9 @@ */ public File getAbsoluteFile() { String absPath = getAbsolutePath(); + if (getClass() != File.class) { + absPath = fs.normalize(absPath); + } return new File(absPath, fs.prefixLength(absPath)); } @@ -643,6 +649,9 @@ */ public File getCanonicalFile() throws IOException { String canonPath = getCanonicalPath(); + if (getClass() != File.class) { + canonPath = fs.normalize(canonPath); + } return new File(canonPath, fs.prefixLength(canonPath)); } @@ -1114,6 +1123,26 @@ * the directory */ public String[] list() { + return normalizedList(); + } + + /** + * Returns an array of strings naming the files and directories in the + * directory denoted by this abstract pathname. The strings are + * ensured to represent normalized paths. + * + * @return An array of strings naming the files and directories in the + * directory denoted by this abstract pathname. The array will be + * empty if the directory is empty. Returns {@code null} if + * this abstract pathname does not denote a directory, or if an + * I/O error occurs. + * + * @throws SecurityException + * If a security manager exists and its {@link + * SecurityManager#checkRead(String)} method denies read access to + * the directory + */ + private final String[] normalizedList() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkRead(path); @@ -1121,7 +1150,15 @@ if (isInvalid()) { return null; } - return fs.list(this); + String[] s = fs.list(this); + if (s != null && getClass() != File.class) { + String[] normalized = new String[s.length]; + for (int i = 0; i < s.length; i++) { + normalized[i] = fs.normalize(s[i]); + } + s = normalized; + } + return s; } /** @@ -1154,7 +1191,7 @@ * @see java.nio.file.Files#newDirectoryStream(Path,String) */ public String[] list(FilenameFilter filter) { - String names[] = list(); + String names[] = normalizedList(); if ((names == null) || (filter == null)) { return names; } @@ -1206,7 +1243,7 @@ * @since 1.2 */ public File[] listFiles() { - String[] ss = list(); + String[] ss = normalizedList(); if (ss == null) return null; int n = ss.length; File[] fs = new File[n]; @@ -1247,7 +1284,7 @@ * @see java.nio.file.Files#newDirectoryStream(Path,String) */ public File[] listFiles(FilenameFilter filter) { - String ss[] = list(); + String ss[] = normalizedList(); if (ss == null) return null; ArrayList files = new ArrayList<>(); for (String s : ss) @@ -1285,7 +1322,7 @@ * @see java.nio.file.Files#newDirectoryStream(Path,java.nio.file.DirectoryStream.Filter) */ public File[] listFiles(FileFilter filter) { - String ss[] = list(); + String ss[] = normalizedList(); if (ss == null) return null; ArrayList files = new ArrayList<>(); for (String s : ss) { diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/java/security/cert/CertPathHelperImpl.java --- a/src/share/classes/java/security/cert/CertPathHelperImpl.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/java/security/cert/CertPathHelperImpl.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2020, 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 @@ -63,4 +63,8 @@ protected void implSetDateAndTime(X509CRLSelector sel, Date date, long skew) { sel.setDateAndTime(date, skew); } + + protected boolean implIsJdkCA(TrustAnchor anchor) { + return anchor.isJdkCA(); + } } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/java/security/cert/TrustAnchor.java --- a/src/share/classes/java/security/cert/TrustAnchor.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/java/security/cert/TrustAnchor.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, 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 @@ -30,6 +30,7 @@ import javax.security.auth.x500.X500Principal; +import sun.security.util.AnchorCertificates; import sun.security.x509.NameConstraintsExtension; import sun.security.x509.X500Name; @@ -68,6 +69,12 @@ private final X509Certificate trustedCert; private byte[] ncBytes; private NameConstraintsExtension nc; + private boolean jdkCA; + private boolean hasJdkCABeenChecked; + + static { + CertPathHelperImpl.initialize(); + } /** * Creates an instance of {@code TrustAnchor} with the specified @@ -330,4 +337,18 @@ sb.append(" Name Constraints: " + nc.toString() + "\n"); return sb.toString(); } + + /** + * Returns true if anchor is a JDK CA (a root CA that is included by + * default in the cacerts keystore). + */ + synchronized boolean isJdkCA() { + if (!hasJdkCABeenChecked) { + if (trustedCert != null) { + jdkCA = AnchorCertificates.contains(trustedCert); + } + hasJdkCABeenChecked = true; + } + return jdkCA; + } } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/javax/naming/spi/NamingManager.java --- a/src/share/classes/javax/naming/spi/NamingManager.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/javax/naming/spi/NamingManager.java Fri Apr 23 01:47:38 2021 +0100 @@ -31,6 +31,8 @@ import java.net.MalformedURLException; import javax.naming.*; + +import com.sun.naming.internal.ObjectFactoriesFilter; import com.sun.naming.internal.VersionHelper; import com.sun.naming.internal.ResourceManager; import com.sun.naming.internal.FactoryEnumeration; @@ -143,7 +145,11 @@ // Try to use current class loader try { - clas = helper.loadClass(factoryName); + clas = helper.loadClassWithoutInit(factoryName); + // Validate factory's class with the objects factory serial filter + if (!ObjectFactoriesFilter.canInstantiateObjectsFactory(clas)) { + return null; + } } catch (ClassNotFoundException e) { // ignore and continue // e.printStackTrace(); @@ -156,6 +162,11 @@ (codebase = ref.getFactoryClassLocation()) != null) { try { clas = helper.loadClass(factoryName, codebase); + // Validate factory's class with the objects factory serial filter + if (clas == null || + !ObjectFactoriesFilter.canInstantiateObjectsFactory(clas)) { + return null; + } } catch (ClassNotFoundException e) { } } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/pkcs/SignerInfo.java --- a/src/share/classes/sun/security/pkcs/SignerInfo.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/pkcs/SignerInfo.java Fri Apr 23 01:47:38 2021 +0100 @@ -35,26 +35,28 @@ import java.security.cert.X509Certificate; import java.security.*; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; -import java.util.EnumSet; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; import java.util.Set; import sun.misc.HexDumpEncoder; import sun.security.timestamp.TimestampToken; -import sun.security.util.ConstraintsParameters; import sun.security.util.Debug; import sun.security.util.DerEncoder; import sun.security.util.DerInputStream; import sun.security.util.DerOutputStream; import sun.security.util.DerValue; import sun.security.util.DisabledAlgorithmConstraints; +import sun.security.util.JarConstraintsParameters; import sun.security.util.KeyUtil; import sun.security.util.ObjectIdentifier; +import sun.security.util.SignatureUtil; import sun.security.x509.AlgorithmId; import sun.security.x509.X500Name; import sun.security.x509.KeyUsageExtension; -import sun.security.util.SignatureUtil; /** * A SignerInfo, as defined in PKCS#7's signedData type. @@ -63,16 +65,8 @@ */ public class SignerInfo implements DerEncoder { - // Digest and Signature restrictions - private static final Set DIGEST_PRIMITIVE_SET = - Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST)); - - private static final Set SIG_PRIMITIVE_SET = - Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE)); - private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK = - new DisabledAlgorithmConstraints( - DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS); + DisabledAlgorithmConstraints.jarConstraints(); BigInteger version; X500Name issuerName; @@ -87,6 +81,14 @@ PKCS9Attributes authenticatedAttributes; PKCS9Attributes unauthenticatedAttributes; + /** + * A map containing the algorithms in this SignerInfo. This is used to + * avoid checking algorithms to see if they are disabled more than once. + * The key is the AlgorithmId of the algorithm, and the value is the name of + * the field or attribute. + */ + private Map algorithms = new HashMap<>(); + public SignerInfo(X500Name issuerName, BigInteger serial, AlgorithmId digestAlgorithmId, @@ -313,21 +315,15 @@ throws NoSuchAlgorithmException, SignatureException { try { + Timestamp timestamp = getTimestamp(); ContentInfo content = block.getContentInfo(); if (data == null) { data = content.getContentBytes(); } - Timestamp timestamp = null; - try { - timestamp = getTimestamp(); - } catch (Exception ignore) { - } - - ConstraintsParameters cparams = - new ConstraintsParameters(timestamp); - String digestAlgname = getDigestAlgorithmId().getName(); + String digestAlgName = digestAlgorithmId.getName(); + algorithms.put(digestAlgorithmId, "SignerInfo digestAlgorithm field"); byte[] dataSigned; @@ -353,21 +349,11 @@ if (messageDigest == null) // fail if there is no message digest return null; - // check that digest algorithm is not restricted - try { - JAR_DISABLED_CHECK.permits(digestAlgname, cparams); - } catch (CertPathValidatorException e) { - throw new SignatureException(e.getMessage(), e); - } - - MessageDigest md = MessageDigest.getInstance(digestAlgname); + MessageDigest md = MessageDigest.getInstance(digestAlgName); byte[] computedMessageDigest = md.digest(data); - if (messageDigest.length != computedMessageDigest.length) + if (!MessageDigest.isEqual(messageDigest, computedMessageDigest)) { return null; - for (int i = 0; i < messageDigest.length; i++) { - if (messageDigest[i] != computedMessageDigest[i]) - return null; } // message digest attribute matched @@ -381,21 +367,23 @@ // put together digest algorithm and encryption algorithm // to form signing algorithm - String encryptionAlgname = + String encryptionAlgName = getDigestEncryptionAlgorithmId().getName(); // Workaround: sometimes the encryptionAlgname is actually // a signature name - String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname); - if (tmp != null) encryptionAlgname = tmp; - String algname = AlgorithmId.makeSigAlg( - digestAlgname, encryptionAlgname); - - // check that jar signature algorithm is not restricted + String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgName); + if (tmp != null) encryptionAlgName = tmp; + String sigAlgName = AlgorithmId.makeSigAlg( + digestAlgName, encryptionAlgName); try { - JAR_DISABLED_CHECK.permits(algname, cparams); - } catch (CertPathValidatorException e) { - throw new SignatureException(e.getMessage(), e); + ObjectIdentifier oid = AlgorithmId.get(sigAlgName).getOID(); + AlgorithmId sigAlgId = + new AlgorithmId(oid, + digestEncryptionAlgorithmId.getParameters()); + algorithms.put(sigAlgId, + "SignerInfo digestEncryptionAlgorithm field"); + } catch (NoSuchAlgorithmException ignore) { } X509Certificate cert = getCertificate(block); @@ -404,14 +392,6 @@ } PublicKey key = cert.getPublicKey(); - // check if the public key is restricted - if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - throw new SignatureException("Public key check failed. " + - "Disabled key used: " + - KeyUtil.getKeySize(key) + " bit " + - key.getAlgorithm()); - } - if (cert.hasUnsupportedCriticalExtension()) { throw new SignatureException("Certificate has unsupported " + "critical extension(s)"); @@ -448,13 +428,13 @@ } } - Signature sig = Signature.getInstance(algname); + Signature sig = Signature.getInstance(sigAlgName); AlgorithmParameters ap = digestEncryptionAlgorithmId.getParameters(); try { SignatureUtil.initVerifyWithParam(sig, key, - SignatureUtil.getParamSpec(algname, ap)); + SignatureUtil.getParamSpec(sigAlgName, ap)); } catch (ProviderException | InvalidAlgorithmParameterException | InvalidKeyException e) { throw new SignatureException(e.getMessage(), e); @@ -464,9 +444,8 @@ if (sig.verify(encryptedDigest)) { return this; } - } catch (IOException e) { - throw new SignatureException("IO error verifying signature:\n" + - e.getMessage()); + } catch (IOException | CertificateException e) { + throw new SignatureException("Error verifying signature", e); } return null; } @@ -564,6 +543,9 @@ // Extract the signer (the Timestamping Authority) // while verifying the content SignerInfo[] tsa = tsToken.verify(encTsTokenInfo); + if (tsa == null || tsa.length == 0) { + throw new SignatureException("Unable to verify timestamp"); + } // Expect only one signer ArrayList chain = tsa[0].getCertificateChain(tsToken); CertificateFactory cf = CertificateFactory.getInstance("X.509"); @@ -572,6 +554,7 @@ TimestampToken tsTokenInfo = new TimestampToken(encTsTokenInfo); // Check that the signature timestamp applies to this signature verifyTimestamp(tsTokenInfo); + algorithms.putAll(tsa[0].algorithms); // Create a timestamp object timestamp = new Timestamp(tsTokenInfo.getDate(), tsaChain); return timestamp; @@ -584,18 +567,13 @@ */ private void verifyTimestamp(TimestampToken token) throws NoSuchAlgorithmException, SignatureException { - String digestAlgname = token.getHashAlgorithm().getName(); - // check that algorithm is not restricted - if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, digestAlgname, - null)) { - throw new SignatureException("Timestamp token digest check failed. " + - "Disabled algorithm used: " + digestAlgname); - } + + AlgorithmId digestAlgId = token.getHashAlgorithm(); + algorithms.put(digestAlgId, "TimestampToken digestAlgorithm field"); - MessageDigest md = - MessageDigest.getInstance(digestAlgname); + MessageDigest md = MessageDigest.getInstance(digestAlgId.getName()); - if (!Arrays.equals(token.getHashedMessage(), + if (!MessageDigest.isEqual(token.getHashedMessage(), md.digest(encryptedDigest))) { throw new SignatureException("Signature timestamp (#" + @@ -636,4 +614,35 @@ } return out; } + + /** + * Verify all of the algorithms in the array of SignerInfos against the + * constraints in the jdk.jar.disabledAlgorithms security property. + * + * @param infos array of SignerInfos + * @param params constraint parameters + * @param name the name of the signer's PKCS7 file + * @return a set of algorithms that passed the checks and are not disabled + */ + public static Set verifyAlgorithms(SignerInfo[] infos, + JarConstraintsParameters params, String name) throws SignatureException { + Map algorithms = new HashMap<>(); + for (SignerInfo info : infos) { + algorithms.putAll(info.algorithms); + } + + Set enabledAlgorithms = new HashSet<>(); + try { + for (Map.Entry algorithm : algorithms.entrySet()) { + params.setExtendedExceptionMsg(name, algorithm.getValue()); + AlgorithmId algId = algorithm.getKey(); + JAR_DISABLED_CHECK.permits(algId.getName(), + algId.getParameters(), params); + enabledAlgorithms.add(algId.getName()); + } + } catch (CertPathValidatorException e) { + throw new SignatureException(e); + } + return enabledAlgorithms; + } } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java --- a/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2020, 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 @@ -27,8 +27,6 @@ import java.security.AlgorithmConstraints; import java.security.CryptoPrimitive; -import java.security.Timestamp; -import java.security.cert.CertPathValidator; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -53,14 +51,13 @@ import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAPublicKeySpec; -import sun.security.util.AnchorCertificates; import sun.security.util.ConstraintsParameters; import sun.security.util.Debug; import sun.security.util.DisabledAlgorithmConstraints; import sun.security.validator.Validator; +import sun.security.x509.AlgorithmId; import sun.security.x509.X509CertImpl; import sun.security.x509.X509CRLImpl; -import sun.security.x509.AlgorithmId; /** * A {@code PKIXCertPathChecker} implementation to check whether a @@ -78,10 +75,10 @@ private final AlgorithmConstraints constraints; private final PublicKey trustedPubKey; - private final Date pkixdate; + private final Date date; private PublicKey prevPubKey; - private final Timestamp jarTimestamp; private final String variant; + private TrustAnchor anchor; private static final Set SIGNATURE_PRIMITIVE_SET = Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE)); @@ -94,95 +91,70 @@ CryptoPrimitive.KEY_AGREEMENT)); private static final DisabledAlgorithmConstraints - certPathDefaultConstraints = new DisabledAlgorithmConstraints( - DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS); - - // If there is no "cacerts" keyword, then disable anchor checking - private static final boolean publicCALimits = - certPathDefaultConstraints.checkProperty("jdkCA"); - - // If anchor checking enabled, this will be true if the trust anchor - // has a match in the cacerts file - private boolean trustedMatch = false; + certPathDefaultConstraints = + DisabledAlgorithmConstraints.certPathConstraints(); /** - * Create a new {@code AlgorithmChecker} with the given algorithm - * given {@code TrustAnchor} and {@code String} variant. + * Create a new {@code AlgorithmChecker} with the given + * {@code TrustAnchor} and {@code String} variant. * * @param anchor the trust anchor selected to validate the target * certificate - * @param variant is the Validator variants of the operation. A null value + * @param variant the Validator variant of the operation. A null value * passed will set it to Validator.GENERIC. */ public AlgorithmChecker(TrustAnchor anchor, String variant) { - this(anchor, certPathDefaultConstraints, null, null, variant); + this(anchor, certPathDefaultConstraints, null, variant); } /** * Create a new {@code AlgorithmChecker} with the given - * {@code AlgorithmConstraints}, {@code Timestamp}, and {@code String} - * variant. + * {@code AlgorithmConstraints} and {@code String} variant. * * Note that this constructor can initialize a variation of situations where - * the AlgorithmConstraints, Timestamp, or Variant maybe known. + * the AlgorithmConstraints or Variant maybe known. * * @param constraints the algorithm constraints (or null) - * @param jarTimestamp Timestamp passed for JAR timestamp constraint - * checking. Set to null if not applicable. - * @param variant is the Validator variants of the operation. A null value + * @param variant the Validator variant of the operation. A null value * passed will set it to Validator.GENERIC. */ - public AlgorithmChecker(AlgorithmConstraints constraints, - Timestamp jarTimestamp, String variant) { - this(null, constraints, null, jarTimestamp, variant); + public AlgorithmChecker(AlgorithmConstraints constraints, String variant) { + this(null, constraints, null, variant); } /** * Create a new {@code AlgorithmChecker} with the - * given {@code TrustAnchor}, {@code AlgorithmConstraints}, - * {@code Timestamp}, and {@code String} variant. + * given {@code TrustAnchor}, {@code AlgorithmConstraints}, {@code Date}, + * and {@code String} variant. * * @param anchor the trust anchor selected to validate the target * certificate * @param constraints the algorithm constraints (or null) - * @param pkixdate The date specified by the PKIXParameters date. If the - * PKIXParameters is null, the current date is used. This - * should be null when jar files are being checked. - * @param jarTimestamp Timestamp passed for JAR timestamp constraint - * checking. Set to null if not applicable. - * @param variant is the Validator variants of the operation. A null value + * @param date the date specified by the PKIXParameters date, or the + * JAR timestamp if jar files are being validated and the + * JAR is timestamped. May be null if no timestamp or + * PKIXParameter date is set. + * @param variant the Validator variant of the operation. A null value * passed will set it to Validator.GENERIC. */ public AlgorithmChecker(TrustAnchor anchor, - AlgorithmConstraints constraints, Date pkixdate, - Timestamp jarTimestamp, String variant) { + AlgorithmConstraints constraints, Date date, String variant) { if (anchor != null) { if (anchor.getTrustedCert() != null) { this.trustedPubKey = anchor.getTrustedCert().getPublicKey(); - // Check for anchor certificate restrictions - trustedMatch = checkFingerprint(anchor.getTrustedCert()); - if (trustedMatch && debug != null) { - debug.println("trustedMatch = true"); - } } else { this.trustedPubKey = anchor.getCAPublicKey(); } + this.anchor = anchor; } else { this.trustedPubKey = null; - if (debug != null) { - debug.println("TrustAnchor is null, trustedMatch is false."); - } } this.prevPubKey = this.trustedPubKey; this.constraints = (constraints == null ? certPathDefaultConstraints : constraints); - // If we are checking jar files, set pkixdate the same as the timestamp - // for certificate checking - this.pkixdate = (jarTimestamp != null ? jarTimestamp.getTimestamp() : - pkixdate); - this.jarTimestamp = jarTimestamp; + this.date = date; this.variant = (variant == null ? Validator.VAR_GENERIC : variant); } @@ -194,24 +166,11 @@ * certificate * @param pkixdate Date the constraints are checked against. The value is * either the PKIXParameters date or null for the current date. - * @param variant is the Validator variants of the operation. A null value + * @param variant the Validator variant of the operation. A null value * passed will set it to Validator.GENERIC. */ public AlgorithmChecker(TrustAnchor anchor, Date pkixdate, String variant) { - this(anchor, certPathDefaultConstraints, pkixdate, null, variant); - } - - // Check this 'cert' for restrictions in the AnchorCertificates - // trusted certificates list - private static boolean checkFingerprint(X509Certificate cert) { - if (!publicCALimits) { - return false; - } - - if (debug != null) { - debug.println("AlgorithmChecker.contains: " + cert.getSigAlgName()); - } - return AnchorCertificates.contains(cert); + this(anchor, certPathDefaultConstraints, pkixdate, variant); } @Override @@ -318,18 +277,19 @@ } ConstraintsParameters cp = - new ConstraintsParameters((X509Certificate)cert, - trustedMatch, pkixdate, jarTimestamp, variant); + new CertPathConstraintsParameters(x509Cert, variant, + anchor, date); // Check against local constraints if it is DisabledAlgorithmConstraints if (constraints instanceof DisabledAlgorithmConstraints) { - ((DisabledAlgorithmConstraints)constraints).permits(currSigAlg, cp); + ((DisabledAlgorithmConstraints)constraints).permits(currSigAlg, + currSigAlgParams, cp); // DisabledAlgorithmsConstraints does not check primitives, so key // additional key check. } else { // Perform the default constraints checking anyway. - certPathDefaultConstraints.permits(currSigAlg, cp); + certPathDefaultConstraints.permits(currSigAlg, currSigAlgParams, cp); // Call locally set constraints to check key with primitives. if (!constraints.permits(primitives, currPubKey)) { throw new CertPathValidatorException( @@ -408,14 +368,10 @@ // Don't bother to change the trustedPubKey. if (anchor.getTrustedCert() != null) { prevPubKey = anchor.getTrustedCert().getPublicKey(); - // Check for anchor certificate restrictions - trustedMatch = checkFingerprint(anchor.getTrustedCert()); - if (trustedMatch && debug != null) { - debug.println("trustedMatch = true"); - } } else { prevPubKey = anchor.getCAPublicKey(); } + this.anchor = anchor; } } @@ -424,11 +380,12 @@ * * @param key the public key to verify the CRL signature * @param crl the target CRL - * @param variant is the Validator variants of the operation. A null value + * @param variant the Validator variant of the operation. A null value * passed will set it to Validator.GENERIC. + * @param anchor the trust anchor selected to validate the CRL issuer */ - static void check(PublicKey key, X509CRL crl, String variant) - throws CertPathValidatorException { + static void check(PublicKey key, X509CRL crl, String variant, + TrustAnchor anchor) throws CertPathValidatorException { X509CRLImpl x509CRLImpl = null; try { @@ -438,7 +395,7 @@ } AlgorithmId algorithmId = x509CRLImpl.getSigAlgId(); - check(key, algorithmId, variant); + check(key, algorithmId, variant, anchor); } /** @@ -446,16 +403,16 @@ * * @param key the public key to verify the CRL signature * @param algorithmId signature algorithm Algorithm ID - * @param variant is the Validator variants of the operation. A null value - * passed will set it to Validator.GENERIC. + * @param variant the Validator variant of the operation. A null + * value passed will set it to Validator.GENERIC. + * @param anchor the trust anchor selected to validate the public key */ - static void check(PublicKey key, AlgorithmId algorithmId, String variant) - throws CertPathValidatorException { - String sigAlgName = algorithmId.getName(); - AlgorithmParameters sigAlgParams = algorithmId.getParameters(); + static void check(PublicKey key, AlgorithmId algorithmId, String variant, + TrustAnchor anchor) throws CertPathValidatorException { - certPathDefaultConstraints.permits(new ConstraintsParameters( - sigAlgName, sigAlgParams, key, variant)); + certPathDefaultConstraints.permits(algorithmId.getName(), + algorithmId.getParameters(), + new CertPathConstraintsParameters(key, variant, anchor)); } } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/provider/certpath/CertPathConstraintsParameters.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/security/provider/certpath/CertPathConstraintsParameters.java Fri Apr 23 01:47:38 2021 +0100 @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2020, 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.provider.certpath; + +import java.security.Key; +import java.security.cert.TrustAnchor; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.Set; +import java.util.Collections; + +import sun.security.util.ConstraintsParameters; +import sun.security.validator.Validator; + +/** + * This class contains parameters for checking certificates against + * constraints specified in the jdk.certpath.disabledAlgorithms security + * property. + */ +class CertPathConstraintsParameters implements ConstraintsParameters { + // The public key of the certificate + private final Key key; + // The certificate's trust anchor which will be checked against the + // jdkCA constraint, if specified. + private final TrustAnchor anchor; + // The PKIXParameter validity date or the timestamp of the signed JAR + // file, if this chain is associated with a timestamped signed JAR. + private final Date date; + // The variant or usage of this certificate + private final String variant; + // The certificate being checked (may be null if a CRL or OCSPResponse is + // being checked) + private final X509Certificate cert; + + public CertPathConstraintsParameters(X509Certificate cert, + String variant, TrustAnchor anchor, Date date) { + this(cert.getPublicKey(), variant, anchor, date, cert); + } + + public CertPathConstraintsParameters(Key key, String variant, + TrustAnchor anchor) { + this(key, variant, anchor, null, null); + } + + private CertPathConstraintsParameters(Key key, String variant, + TrustAnchor anchor, Date date, X509Certificate cert) { + this.key = key; + this.variant = (variant == null ? Validator.VAR_GENERIC : variant); + this.anchor = anchor; + this.date = date; + this.cert = cert; + } + + @Override + public boolean anchorIsJdkCA() { + return CertPathHelper.isJdkCA(anchor); + } + + @Override + public Set getKeys() { + return (key == null) ? Collections.emptySet() + : Collections.singleton(key); + } + + @Override + public Date getDate() { + return date; + } + + @Override + public String getVariant() { + return variant; + } + + @Override + public String extendedExceptionMsg() { + return (cert == null ? "." + : " used with certificate: " + + cert.getSubjectX500Principal()); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("[\n"); + sb.append("\n Variant: ").append(variant); + if (anchor != null) { + sb.append("\n Anchor: ").append(anchor); + } + if (cert != null) { + sb.append("\n Cert Issuer: ") + .append(cert.getIssuerX500Principal()); + sb.append("\n Cert Subject: ") + .append(cert.getSubjectX500Principal()); + } + if (key != null) { + sb.append("\n Key: ").append(key.getAlgorithm()); + } + if (date != null) { + sb.append("\n Date: ").append(date); + } + sb.append("\n]"); + return sb.toString(); + } +} diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/provider/certpath/CertPathHelper.java --- a/src/share/classes/sun/security/provider/certpath/CertPathHelper.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/provider/certpath/CertPathHelper.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2020, 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 @@ -28,13 +28,14 @@ import java.util.Date; import java.util.Set; +import java.security.cert.TrustAnchor; import java.security.cert.X509CertSelector; import java.security.cert.X509CRLSelector; import sun.security.x509.GeneralNameInterface; /** - * Helper class that allows access to Sun specific known-public methods in the + * Helper class that allows access to JDK specific known-public methods in the * java.security.cert package. It relies on a subclass in the * java.security.cert packages that is initialized before any of these methods * are called (achieved via static initializers). @@ -59,6 +60,8 @@ protected abstract void implSetDateAndTime(X509CRLSelector sel, Date date, long skew); + protected abstract boolean implIsJdkCA(TrustAnchor anchor); + static void setPathToNames(X509CertSelector sel, Set names) { instance.implSetPathToNames(sel, names); @@ -67,4 +70,8 @@ public static void setDateAndTime(X509CRLSelector sel, Date date, long skew) { instance.implSetDateAndTime(sel, date, skew); } + + public static boolean isJdkCA(TrustAnchor anchor) { + return (anchor == null) ? false : instance.implIsJdkCA(anchor); + } } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java --- a/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Fri Apr 23 01:47:38 2021 +0100 @@ -73,7 +73,7 @@ throws CertStoreException { return getCRLs(selector, signFlag, prevKey, null, provider, certStores, - reasonsMask, trustAnchors, validity, variant); + reasonsMask, trustAnchors, validity, variant, null); } /** * Return the X509CRLs matching this selector. The selector must be @@ -90,8 +90,14 @@ Date validity) throws CertStoreException { + if (trustAnchors.isEmpty()) { + throw new CertStoreException( + "at least one TrustAnchor must be specified"); + } + TrustAnchor anchor = trustAnchors.iterator().next(); return getCRLs(selector, signFlag, prevKey, null, provider, certStores, - reasonsMask, trustAnchors, validity, Validator.VAR_GENERIC); + reasonsMask, trustAnchors, validity, + Validator.VAR_PLUGIN_CODE_SIGNING, anchor); } /** @@ -107,7 +113,8 @@ boolean[] reasonsMask, Set trustAnchors, Date validity, - String variant) + String variant, + TrustAnchor anchor) throws CertStoreException { X509Certificate cert = selector.getCertificateChecking(); @@ -136,7 +143,7 @@ DistributionPoint point = t.next(); Collection crls = getCRLs(selector, certImpl, point, reasonsMask, signFlag, prevKey, prevCert, provider, - certStores, trustAnchors, validity, variant); + certStores, trustAnchors, validity, variant, anchor); results.addAll(crls); } if (debug != null) { @@ -161,7 +168,8 @@ X509CertImpl certImpl, DistributionPoint point, boolean[] reasonsMask, boolean signFlag, PublicKey prevKey, X509Certificate prevCert, String provider, List certStores, - Set trustAnchors, Date validity, String variant) + Set trustAnchors, Date validity, String variant, + TrustAnchor anchor) throws CertStoreException { // check for full name @@ -224,7 +232,7 @@ selector.setIssuerNames(null); if (selector.match(crl) && verifyCRL(certImpl, point, crl, reasonsMask, signFlag, prevKey, prevCert, provider, - trustAnchors, certStores, validity, variant)) { + trustAnchors, certStores, validity, variant, anchor)) { crls.add(crl); } } catch (IOException | CRLException e) { @@ -333,7 +341,8 @@ X509CRL crl, boolean[] reasonsMask, boolean signFlag, PublicKey prevKey, X509Certificate prevCert, String provider, Set trustAnchors, List certStores, - Date validity, String variant) throws CRLException, IOException { + Date validity, String variant, TrustAnchor anchor) + throws CRLException, IOException { if (debug != null) { debug.println("DistributionPointFetcher.verifyCRL: " + @@ -680,7 +689,7 @@ // check the crl signature algorithm try { - AlgorithmChecker.check(prevKey, crl, variant); + AlgorithmChecker.check(prevKey, crl, variant, anchor); } catch (CertPathValidatorException cpve) { if (debug != null) { debug.println("CRL signature algorithm check failed: " + cpve); diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/provider/certpath/OCSP.java --- a/src/share/classes/sun/security/provider/certpath/OCSP.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/provider/certpath/OCSP.java Fri Apr 23 01:47:38 2021 +0100 @@ -121,7 +121,8 @@ throws IOException, CertPathValidatorException { return check(cert, issuerCert, responderURI, responderCert, date, - Collections.emptyList(), Validator.VAR_GENERIC); + Collections.emptyList(), + Validator.VAR_PLUGIN_CODE_SIGNING); } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/provider/certpath/OCSPResponse.java --- a/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -465,6 +465,7 @@ } // Check whether the signer cert returned by the responder is trusted + boolean signedByTrustedResponder = false; if (signerCert != null) { // Check if the response is signed by the issuing CA if (signerCert.getSubjectX500Principal().equals( @@ -479,6 +480,7 @@ // Check if the response is signed by a trusted responder } else if (signerCert.equals(responderCert)) { + signedByTrustedResponder = true; if (debug != null) { debug.println("OCSP response is signed by a Trusted " + "Responder"); @@ -569,7 +571,10 @@ if (signerCert != null) { // Check algorithm constraints specified in security property // "jdk.certpath.disabledAlgorithms". - AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId, variant); + AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId, variant, + signedByTrustedResponder + ? new TrustAnchor(responderCert, null) + : issuerInfo.getAnchor()); if (!verifySignature(signerCert)) { throw new CertPathValidatorException( diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/provider/certpath/PKIX.java --- a/src/share/classes/sun/security/provider/certpath/PKIX.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/provider/certpath/PKIX.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, 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 @@ -33,6 +33,7 @@ import javax.security.auth.x500.X500Principal; import sun.security.util.Debug; +import sun.security.validator.Validator; /** * Common utility methods and classes used by the PKIX CertPathValidator and @@ -87,7 +88,7 @@ private Set anchors; private List certs; private Timestamp timestamp; - private String variant; + private String variant = Validator.VAR_GENERIC; ValidatorParams(CertPath cp, PKIXParameters params) throws InvalidAlgorithmParameterException @@ -155,9 +156,17 @@ } Date date() { if (!gotDate) { - date = params.getDate(); - if (date == null) - date = new Date(); + // use timestamp if checking signed code that is + // timestamped, otherwise use date parameter + if (timestamp != null && + (variant.equals(Validator.VAR_CODE_SIGNING) || + variant.equals(Validator.VAR_PLUGIN_CODE_SIGNING))) { + date = timestamp.getTimestamp(); + } else { + date = params.getDate(); + if (date == null) + date = new Date(); + } gotDate = true; } return date; @@ -198,10 +207,6 @@ return params; } - Timestamp timestamp() { - return timestamp; - } - String variant() { return variant; } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java --- a/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2020, 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 @@ -31,7 +31,6 @@ import java.util.*; import sun.security.provider.certpath.PKIX.ValidatorParams; -import sun.security.validator.Validator; import sun.security.x509.X509CertImpl; import sun.security.util.Debug; @@ -174,7 +173,7 @@ // add standard checkers that we will be using certPathCheckers.add(untrustedChecker); certPathCheckers.add(new AlgorithmChecker(anchor, null, params.date(), - params.timestamp(), params.variant())); + params.variant())); certPathCheckers.add(new KeyChecker(certPathLen, params.targetCertConstraints())); certPathCheckers.add(new ConstraintsChecker(certPathLen)); @@ -191,19 +190,7 @@ rootNode); certPathCheckers.add(pc); - // the time that the certificate validity period should be - // checked against - Date timeToCheck = null; - // use timestamp if checking signed code that is timestamped, otherwise - // use date parameter from PKIXParameters - if ((params.variant() == Validator.VAR_CODE_SIGNING || - params.variant() == Validator.VAR_PLUGIN_CODE_SIGNING) && - params.timestamp() != null) { - timeToCheck = params.timestamp().getTimestamp(); - } else { - timeToCheck = params.date(); - } - BasicChecker bc = new BasicChecker(anchor, timeToCheck, + BasicChecker bc = new BasicChecker(anchor, params.date(), params.sigProvider(), false); certPathCheckers.add(bc); diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/provider/certpath/RevocationChecker.java --- a/src/share/classes/sun/security/provider/certpath/RevocationChecker.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/provider/certpath/RevocationChecker.java Fri Apr 23 01:47:38 2021 +0100 @@ -579,7 +579,7 @@ approvedCRLs.addAll(DistributionPointFetcher.getCRLs( sel, signFlag, prevKey, prevCert, params.sigProvider(), certStores, reasonsMask, - anchors, null, params.variant())); + anchors, null, params.variant(), anchor)); } } catch (CertStoreException e) { if (e instanceof CertStoreTypeException) { @@ -853,7 +853,7 @@ if (DistributionPointFetcher.verifyCRL( certImpl, point, crl, reasonsMask, signFlag, prevKey, null, params.sigProvider(), anchors, - certStores, params.date(), params.variant())) + certStores, params.date(), params.variant(), anchor)) { results.add(crl); } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/ssl/SSLContextImpl.java --- a/src/share/classes/sun/security/ssl/SSLContextImpl.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/ssl/SSLContextImpl.java Fri Apr 23 01:47:38 2021 +0100 @@ -1374,7 +1374,7 @@ // A forward checker, need to check from trust to target if (checkedLength >= 0) { AlgorithmChecker checker = - new AlgorithmChecker(constraints, null, + new AlgorithmChecker(constraints, (checkClientTrusted ? Validator.VAR_TLS_CLIENT : Validator.VAR_TLS_SERVER)); checker.init(false); diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/ssl/X509KeyManagerImpl.java --- a/src/share/classes/sun/security/ssl/X509KeyManagerImpl.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/ssl/X509KeyManagerImpl.java Fri Apr 23 01:47:38 2021 +0100 @@ -831,8 +831,7 @@ AlgorithmConstraints constraints, Certificate[] chain, String variant) { - AlgorithmChecker checker = - new AlgorithmChecker(constraints, null, variant); + AlgorithmChecker checker = new AlgorithmChecker(constraints, variant); try { checker.init(false); } catch (CertPathValidatorException cpve) { diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/util/AnchorCertificates.java --- a/src/share/classes/sun/security/util/AnchorCertificates.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/util/AnchorCertificates.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, 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 @@ -35,6 +35,7 @@ import java.util.Enumeration; import java.util.HashSet; import java.util.Set; +import javax.security.auth.x500.X500Principal; import sun.security.x509.X509CertImpl; @@ -47,6 +48,7 @@ private static final Debug debug = Debug.getInstance("certpath"); private static final String HASH = "SHA-256"; private static Set certs = Collections.emptySet(); + private static Set certIssuers = Collections.emptySet(); static { AccessController.doPrivileged(new PrivilegedAction() { @@ -60,15 +62,16 @@ try (FileInputStream fis = new FileInputStream(f)) { cacerts.load(fis, null); certs = new HashSet<>(); + certIssuers = new HashSet<>(); Enumeration list = cacerts.aliases(); - String alias; while (list.hasMoreElements()) { - alias = list.nextElement(); + String alias = list.nextElement(); // Check if this cert is labeled a trust anchor. if (alias.contains(" [jdk")) { X509Certificate cert = (X509Certificate) cacerts .getCertificate(alias); certs.add(X509CertImpl.getFingerprint(HASH, cert)); + certIssuers.add(cert.getSubjectX500Principal()); } } } @@ -84,10 +87,10 @@ } /** - * Checks if a certificate is a trust anchor. + * Checks if a certificate is a JDK trust anchor. * * @param cert the certificate to check - * @return true if the certificate is trusted. + * @return true if the certificate is a JDK trust anchor */ public static boolean contains(X509Certificate cert) { String key = X509CertImpl.getFingerprint(HASH, cert); @@ -99,5 +102,15 @@ return result; } + /** + * Checks if a JDK trust anchor is the issuer of a certificate. + * + * @param cert the certificate to check + * @return true if the certificate is issued by a trust anchor + */ + public static boolean issuerOf(X509Certificate cert) { + return certIssuers.contains(cert.getIssuerX500Principal()); + } + private AnchorCertificates() {} } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/util/ConstraintsParameters.java --- a/src/share/classes/sun/security/util/ConstraintsParameters.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/util/ConstraintsParameters.java Fri Apr 23 01:47:38 2021 +0100 @@ -25,160 +25,42 @@ package sun.security.util; -import sun.security.validator.Validator; - -import java.security.AlgorithmParameters; import java.security.Key; -import java.security.Timestamp; -import java.security.cert.X509Certificate; -import java.security.interfaces.ECKey; import java.util.Date; +import java.util.Set; /** - * This class contains parameters for checking against constraints that extend - * past the publicly available parameters in java.security.AlgorithmConstraints. - - * This is currently on passed between between PKIX, AlgorithmChecker, - * and DisabledAlgorithmConstraints. + * This interface contains parameters for checking against constraints that + * extend past the publicly available parameters in + * java.security.AlgorithmConstraints. */ -public class ConstraintsParameters { - /* - * The below 3 values are used the same as the permit() methods - * published in java.security.AlgorithmConstraints. - */ - // Algorithm string to be checked against constraints - private final String algorithm; - // AlgorithmParameters to the algorithm being checked - private final AlgorithmParameters algParams; - // Key being checked against constraints - private final Key key; - - /* - * New values that are checked against constraints that the current public - * API does not support. - */ - // A certificate being passed to check against constraints. - private final X509Certificate cert; - // This is true if the trust anchor in the certificate chain matches a cert - // in AnchorCertificates - private final boolean trustedMatch; - // PKIXParameter date - private final Date pkixDate; - // Timestamp of the signed JAR file - private final Timestamp jarTimestamp; - private final String variant; - // Named Curve - private final String[] curveStr; - private static final String[] EMPTYLIST = new String[0]; +public interface ConstraintsParameters { - public ConstraintsParameters(X509Certificate c, boolean match, - Date pkixdate, Timestamp jarTime, String variant) { - cert = c; - trustedMatch = match; - pkixDate = pkixdate; - jarTimestamp = jarTime; - this.variant = (variant == null ? Validator.VAR_GENERIC : variant); - algorithm = null; - algParams = null; - key = null; - if (c != null) { - curveStr = getNamedCurveFromKey(c.getPublicKey()); - } else { - curveStr = EMPTYLIST; - } - } + /** + * Returns true if a certificate chains back to a trusted JDK root CA. + */ + boolean anchorIsJdkCA(); - public ConstraintsParameters(String algorithm, AlgorithmParameters params, - Key key, String variant) { - this.algorithm = algorithm; - algParams = params; - this.key = key; - curveStr = getNamedCurveFromKey(key); - cert = null; - trustedMatch = false; - pkixDate = null; - jarTimestamp = null; - this.variant = (variant == null ? Validator.VAR_GENERIC : variant); - } - - - public ConstraintsParameters(X509Certificate c) { - this(c, false, null, null, - Validator.VAR_GENERIC); - } + /** + * Returns the set of keys that should be checked against the + * constraints, or an empty set if there are no keys to be checked. + */ + Set getKeys(); - public ConstraintsParameters(Timestamp jarTime) { - this(null, false, null, jarTime, Validator.VAR_GENERIC); - } - - public String getAlgorithm() { - return algorithm; - } - - public AlgorithmParameters getAlgParams() { - return algParams; - } - - public Key getKey() { - return key; - } - - // Returns if the trust anchor has a match if anchor checking is enabled. - public boolean isTrustedMatch() { - return trustedMatch; - } - - public X509Certificate getCertificate() { - return cert; - } - - public Date getPKIXParamDate() { - return pkixDate; - } - - public Timestamp getJARTimestamp() { - return jarTimestamp; - } - - public String getVariant() { - return variant; - } + /** + * Returns the date that should be checked against the constraints, or + * null if not set. + */ + Date getDate(); - public String[] getNamedCurve() { - return curveStr; - } - - public static String[] getNamedCurveFromKey(Key key) { - if (key instanceof ECKey) { - NamedCurve nc = CurveDB.lookup(((ECKey)key).getParams()); - return (nc == null ? EMPTYLIST : CurveDB.getNamesByOID(nc.getObjectId())); - } else { - return EMPTYLIST; - } - } + /** + * Returns the Validator variant. + */ + String getVariant(); - public String toString() { - StringBuilder s = new StringBuilder(); - s.append("Cert: "); - if (cert != null) { - s.append(cert.toString()); - s.append("\nSigAlgo: "); - s.append(cert.getSigAlgName()); - } else { - s.append("None"); - } - s.append("\nAlgParams: "); - if (getAlgParams() != null) { - getAlgParams().toString(); - } else { - s.append("None"); - } - s.append("\nNamedCurves: "); - for (String c : getNamedCurve()) { - s.append(c + " "); - } - s.append("\nVariant: " + getVariant()); - return s.toString(); - } - + /** + * Returns an extended message used in exceptions. See + * DisabledAlgorithmConstraints for usage. + */ + String extendedExceptionMsg(); } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java --- a/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Fri Apr 23 01:47:38 2021 +0100 @@ -29,14 +29,19 @@ import java.io.ByteArrayOutputStream; import java.io.PrintStream; +import java.security.AlgorithmParameters; import java.security.CryptoPrimitive; -import java.security.AlgorithmParameters; import java.security.Key; import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException.BasicReason; -import java.security.cert.X509Certificate; +import java.security.interfaces.ECKey; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidParameterSpecException; +import java.security.spec.MGF1ParameterSpec; +import java.security.spec.PSSParameterSpec; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -46,6 +51,7 @@ import java.util.Map; import java.util.Set; import java.util.Collection; +import java.util.Collections; import java.util.StringTokenizer; import java.util.TimeZone; import java.util.regex.Pattern; @@ -80,9 +86,27 @@ private static final String PROPERTY_DISABLED_EC_CURVES = "jdk.disabled.namedCurves"; + private static class CertPathHolder { + static final DisabledAlgorithmConstraints CONSTRAINTS = + new DisabledAlgorithmConstraints(PROPERTY_CERTPATH_DISABLED_ALGS); + } + + private static class JarHolder { + static final DisabledAlgorithmConstraints CONSTRAINTS = + new DisabledAlgorithmConstraints(PROPERTY_JAR_DISABLED_ALGS); + } + private final List disabledAlgorithms; private final Constraints algorithmConstraints; + public static DisabledAlgorithmConstraints certPathConstraints() { + return CertPathHolder.CONSTRAINTS; + } + + public static DisabledAlgorithmConstraints jarConstraints() { + return JarHolder.CONSTRAINTS; + } + /** * Initialize algorithm constraints with the specified security property. * @@ -123,7 +147,7 @@ disabledAlgorithms.addAll(ecindex, getAlgorithms(PROPERTY_DISABLED_EC_CURVES)); } - algorithmConstraints = new Constraints(disabledAlgorithms); + algorithmConstraints = new Constraints(propertyName, disabledAlgorithms); } /* @@ -168,32 +192,54 @@ return checkConstraints(primitives, algorithm, key, parameters); } - public final void permits(ConstraintsParameters cp) - throws CertPathValidatorException { - permits(cp.getAlgorithm(), cp); + public final void permits(String algorithm, AlgorithmParameters ap, + ConstraintsParameters cp) throws CertPathValidatorException { + + permits(algorithm, cp); + if (ap != null) { + permits(ap, cp); + } + } + + private void permits(AlgorithmParameters ap, ConstraintsParameters cp) + throws CertPathValidatorException { + + switch (ap.getAlgorithm().toUpperCase(Locale.ENGLISH)) { + case "RSASSA-PSS": + permitsPSSParams(ap, cp); + break; + default: + // unknown algorithm, just ignore + } } - public final void permits(String algorithm, Key key, - AlgorithmParameters params, String variant) - throws CertPathValidatorException { - permits(algorithm, new ConstraintsParameters(algorithm, params, key, - (variant == null) ? Validator.VAR_GENERIC : variant)); - } + private void permitsPSSParams(AlgorithmParameters ap, + ConstraintsParameters cp) throws CertPathValidatorException { - /* - * Check if a x509Certificate object is permitted. Check if all - * algorithms are allowed, certificate constraints, and the - * public key against key constraints. - * - * Uses new style permit() which throws exceptions. - */ + try { + PSSParameterSpec pssParams = + ap.getParameterSpec(PSSParameterSpec.class); + String digestAlg = pssParams.getDigestAlgorithm(); + permits(digestAlg, cp); + AlgorithmParameterSpec mgfParams = pssParams.getMGFParameters(); + if (mgfParams instanceof MGF1ParameterSpec) { + String mgfDigestAlg = + ((MGF1ParameterSpec)mgfParams).getDigestAlgorithm(); + if (!mgfDigestAlg.equalsIgnoreCase(digestAlg)) { + permits(mgfDigestAlg, cp); + } + } + } catch (InvalidParameterSpecException ipse) { + // ignore + } + } public final void permits(String algorithm, ConstraintsParameters cp) throws CertPathValidatorException { - // Check if named curves in the ConstraintParameters are disabled. - if (cp.getNamedCurve() != null) { - for (String curve : cp.getNamedCurve()) { + // Check if named curves in the key are disabled. + for (Key key : cp.getKeys()) { + for (String curve : getNamedCurveFromKey(key)) { if (!checkAlgorithm(disabledAlgorithms, curve, decomposer)) { throw new CertPathValidatorException( "Algorithm constraints check failed on disabled " + @@ -206,15 +252,14 @@ algorithmConstraints.permits(algorithm, cp); } - // Check if a string is contained inside the property - public boolean checkProperty(String param) { - param = param.toLowerCase(Locale.ENGLISH); - for (String block : disabledAlgorithms) { - if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) { - return true; - } + private static List getNamedCurveFromKey(Key key) { + if (key instanceof ECKey) { + NamedCurve nc = CurveDB.lookup(((ECKey)key).getParams()); + return (nc == null ? Collections.emptyList() + : Arrays.asList(CurveDB.getNamesByOID(nc.getObjectId()))); + } else { + return Collections.emptyList(); } - return false; } // Check algorithm constraints with key and algorithm @@ -238,8 +283,8 @@ return false; } - // If this is an elliptic curve, check disabled the named curve. - for (String curve : ConstraintsParameters.getNamedCurveFromKey(key)) { + // If this is an elliptic curve, check if it is disabled + for (String curve : getNamedCurveFromKey(key)) { if (!permits(primitives, curve, null)) { return false; } @@ -276,7 +321,7 @@ "denyAfter\\s+(\\d{4})-(\\d{2})-(\\d{2})"); } - public Constraints(List constraintArray) { + public Constraints(String propertyName, List constraintArray) { for (String constraintEntry : constraintArray) { if (constraintEntry == null || constraintEntry.isEmpty()) { continue; @@ -391,7 +436,7 @@ } } - // Get applicable constraints based off the signature algorithm + // Get applicable constraints based off the algorithm private List getConstraints(String algorithm) { return constraintsMap.get(algorithm.toUpperCase(Locale.ENGLISH)); } @@ -435,13 +480,12 @@ return true; } - // Check if constraints permit this cert. public void permits(String algorithm, ConstraintsParameters cp) throws CertPathValidatorException { - X509Certificate cert = cp.getCertificate(); if (debug != null) { - debug.println("Constraints.permits(): " + cp.toString()); + debug.println("Constraints.permits(): " + algorithm + ", " + + cp.toString()); } // Get all signature algorithms to check for constraints @@ -451,13 +495,10 @@ algorithms.add(algorithm); } - // Attempt to add the public key algorithm if cert provided - if (cert != null) { - algorithms.add(cert.getPublicKey().getAlgorithm()); + for (Key key : cp.getKeys()) { + algorithms.add(key.getAlgorithm()); } - if (cp.getKey() != null) { - algorithms.add(cp.getKey().getAlgorithm()); - } + // Check all applicable constraints for (String alg : algorithms) { List list = getConstraints(alg); @@ -548,7 +589,7 @@ * {@code next()} with the same {@code ConstraintsParameters} * parameter passed if multiple constraints need to be checked. * - * @param cp CertConstraintParameter containing certificate info + * @param cp ConstraintsParameter containing certificate info * @throws CertPathValidatorException if constraint disallows. * */ @@ -597,14 +638,6 @@ boolean next(Key key) { return nextConstraint != null && nextConstraint.permits(key); } - - String extendedMsg(ConstraintsParameters cp) { - return (cp.getCertificate() == null ? "." : - " used with certificate: " + - cp.getCertificate().getSubjectX500Principal() + - (cp.getVariant() != Validator.VAR_GENERIC ? - ". Usage was " + cp.getVariant() : ".")); - } } /* @@ -628,14 +661,15 @@ debug.println("jdkCAConstraints.permits(): " + algorithm); } - // Check chain has a trust anchor in cacerts - if (cp.isTrustedMatch()) { + // Check if any certs chain back to at least one trust anchor in + // cacerts + if (cp.anchorIsJdkCA()) { if (next(cp)) { return; } throw new CertPathValidatorException( "Algorithm constraints check failed on certificate " + - "anchor limits. " + algorithm + extendedMsg(cp), + "anchor limits. " + algorithm + cp.extendedExceptionMsg(), null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } } @@ -700,15 +734,10 @@ Date currentDate; String errmsg; - if (cp.getJARTimestamp() != null) { - currentDate = cp.getJARTimestamp().getTimestamp(); - errmsg = "JAR Timestamp date: "; - } else if (cp.getPKIXParamDate() != null) { - currentDate = cp.getPKIXParamDate(); - errmsg = "PKIXParameter date: "; + if (cp.getDate() != null) { + currentDate = cp.getDate(); } else { currentDate = new Date(); - errmsg = "Current date: "; } if (!denyAfterDate.after(currentDate)) { @@ -718,8 +747,8 @@ throw new CertPathValidatorException( "denyAfter constraint check failed: " + algorithm + " used with Constraint date: " + - dateFormat.format(denyAfterDate) + "; " + errmsg + - dateFormat.format(currentDate) + extendedMsg(cp), + dateFormat.format(denyAfterDate) + "; params date: " + + dateFormat.format(currentDate) + cp.extendedExceptionMsg(), null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } } @@ -756,19 +785,27 @@ @Override public void permits(ConstraintsParameters cp) throws CertPathValidatorException { + String variant = cp.getVariant(); for (String usage : usages) { - String v = null; - if (usage.compareToIgnoreCase("TLSServer") == 0) { - v = Validator.VAR_TLS_SERVER; - } else if (usage.compareToIgnoreCase("TLSClient") == 0) { - v = Validator.VAR_TLS_CLIENT; - } else if (usage.compareToIgnoreCase("SignedJAR") == 0) { - v = Validator.VAR_PLUGIN_CODE_SIGNING; + boolean match = false; + switch (usage.toLowerCase()) { + case "tlsserver": + match = variant.equals(Validator.VAR_TLS_SERVER); + break; + case "tlsclient": + match = variant.equals(Validator.VAR_TLS_CLIENT); + break; + case "signedjar": + match = + variant.equals(Validator.VAR_PLUGIN_CODE_SIGNING) || + variant.equals(Validator.VAR_CODE_SIGNING) || + variant.equals(Validator.VAR_TSA_SERVER); + break; } if (debug != null) { - debug.println("Checking if usage constraint \"" + v + + debug.println("Checking if usage constraint \"" + usage + "\" matches \"" + cp.getVariant() + "\""); // Because usage checking can come from many places // a stack trace is very helpful. @@ -777,13 +814,13 @@ (new Exception()).printStackTrace(ps); debug.println(ba.toString()); } - if (cp.getVariant().compareTo(v) == 0) { + if (match) { if (next(cp)) { return; } throw new CertPathValidatorException("Usage constraint " + usage + " check failed: " + algorithm + - extendedMsg(cp), + cp.extendedExceptionMsg(), null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } } @@ -837,31 +874,25 @@ } /* - * If we are passed a certificate, extract the public key and use it. - * - * Check if each constraint fails and check if there is a linked - * constraint Any permitted constraint will exit the linked list - * to allow the operation. + * For each key, check if each constraint fails and check if there is + * a linked constraint. Any permitted constraint will exit the linked + * list to allow the operation. */ @Override public void permits(ConstraintsParameters cp) throws CertPathValidatorException { - Key key = null; - if (cp.getKey() != null) { - key = cp.getKey(); - } else if (cp.getCertificate() != null) { - key = cp.getCertificate().getPublicKey(); - } - if (key != null && !permitsImpl(key)) { - if (nextConstraint != null) { - nextConstraint.permits(cp); - return; + for (Key key : cp.getKeys()) { + if (!permitsImpl(key)) { + if (nextConstraint != null) { + nextConstraint.permits(cp); + continue; + } + throw new CertPathValidatorException( + "Algorithm constraints check failed on keysize limits: " + + algorithm + " " + KeyUtil.getKeySize(key) + " bit key" + + cp.extendedExceptionMsg(), + null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } - throw new CertPathValidatorException( - "Algorithm constraints check failed on keysize limits. " + - algorithm + " " + KeyUtil.getKeySize(key) + "bit key" + - extendedMsg(cp), - null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } } @@ -938,7 +969,7 @@ throws CertPathValidatorException { throw new CertPathValidatorException( "Algorithm constraints check failed on disabled " + - "algorithm: " + algorithm + extendedMsg(cp), + "algorithm: " + algorithm + cp.extendedExceptionMsg(), null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/util/JarConstraintsParameters.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/security/util/JarConstraintsParameters.java Fri Apr 23 01:47:38 2021 +0100 @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2020, 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.security.CodeSigner; +import java.security.Key; +import java.security.Timestamp; +import java.security.cert.CertPath; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import sun.security.util.AnchorCertificates; +import sun.security.util.ConstraintsParameters; +import sun.security.validator.Validator; + +/** + * This class contains parameters for checking signed JARs against + * constraints specified in the jdk.jar.disabledAlgorithms security + * property. + */ +public class JarConstraintsParameters implements ConstraintsParameters { + + // true if chain is anchored by a JDK root CA + private boolean anchorIsJdkCA; + private boolean anchorIsJdkCASet; + // The timestamp of the signed JAR file, if timestamped + private Date timestamp; + // The keys of the signers + private final Set keys; + // The certs in the signers' chains that are issued by the trust anchor + private final Set certsIssuedByAnchor; + // The extended exception message + private String message; + + /** + * Create a JarConstraintsParameters. + * + * @param signers the CodeSigners that signed the JAR + */ + public JarConstraintsParameters(CodeSigner[] signers) { + this.keys = new HashSet<>(); + this.certsIssuedByAnchor = new HashSet<>(); + Date latestTimestamp = null; + boolean skipTimestamp = false; + + // Iterate over the signers and extract the keys, the latest + // timestamp, and the last certificate of each chain which can be + // used for checking if the signer's certificate chains back to a + // JDK root CA + for (CodeSigner signer : signers) { + init(signer.getSignerCertPath()); + Timestamp timestamp = signer.getTimestamp(); + if (timestamp == null) { + // this means one of the signers doesn't have a timestamp + // and the JAR should be treated as if it isn't timestamped + latestTimestamp = null; + skipTimestamp = true; + } else { + // add the key and last cert of TSA too + init(timestamp.getSignerCertPath()); + if (!skipTimestamp) { + Date timestampDate = timestamp.getTimestamp(); + if (latestTimestamp == null) { + latestTimestamp = timestampDate; + } else { + if (latestTimestamp.before(timestampDate)) { + latestTimestamp = timestampDate; + } + } + } + } + } + this.timestamp = latestTimestamp; + } + + // extract last certificate and key from chain + private void init(CertPath cp) { + @SuppressWarnings("unchecked") + List chain = + (List)cp.getCertificates(); + if (!chain.isEmpty()) { + this.certsIssuedByAnchor.add(chain.get(chain.size() - 1)); + this.keys.add(chain.get(0).getPublicKey()); + } + } + + @Override + public String getVariant() { + return Validator.VAR_GENERIC; + } + + /** + * Since loading the cacerts keystore can be an expensive operation, + * this is only performed if this method is called during a "jdkCA" + * constraints check of a disabled algorithm, and the result is cached. + * + * @return true if at least one of the certificates are issued by a + * JDK root CA + */ + @Override + public boolean anchorIsJdkCA() { + if (anchorIsJdkCASet) { + return anchorIsJdkCA; + } + for (X509Certificate cert : certsIssuedByAnchor) { + if (AnchorCertificates.issuerOf(cert)) { + anchorIsJdkCA = true; + break; + } + } + anchorIsJdkCASet = true; + return anchorIsJdkCA; + } + + @Override + public Date getDate() { + return timestamp; + } + + @Override + public Set getKeys() { + return keys; + } + + /** + * Sets the extended error message. Note: this should be used + * carefully as it is specific to the attribute/entry/file being checked. + * + * @param file the name of the signature related file being verified + * @param target the attribute containing the algorithm that is being + * checked + */ + public void setExtendedExceptionMsg(String file, String target) { + message = " used" + (target != null ? " with " + target : "") + + " in " + file + " file."; + } + + @Override + public String extendedExceptionMsg() { + return message; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("[\n"); + sb.append("\n Variant: ").append(getVariant()); + sb.append("\n Certs Issued by Anchor:"); + for (X509Certificate cert : certsIssuedByAnchor) { + sb.append("\n Cert Issuer: ") + .append(cert.getIssuerX500Principal()); + sb.append("\n Cert Subject: ") + .append(cert.getSubjectX500Principal()); + } + for (Key key : keys) { + sb.append("\n Key: ").append(key.getAlgorithm()); + } + if (timestamp != null) { + sb.append("\n Timestamp: ").append(timestamp); + } + sb.append("\n]"); + return sb.toString(); + } +} diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/util/ManifestEntryVerifier.java --- a/src/share/classes/sun/security/util/ManifestEntryVerifier.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/util/ManifestEntryVerifier.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, 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 @@ -27,13 +27,12 @@ import java.security.*; import java.io.*; -import java.security.CodeSigner; import java.util.*; import java.util.jar.*; -import java.util.Base64; - import sun.security.jca.Providers; +import sun.security.util.DisabledAlgorithmConstraints; +import sun.security.util.JarConstraintsParameters; /** * This class is used to verify each entry in a jar file with its @@ -202,12 +201,29 @@ throw new SecurityException("digest missing for " + name); } - if (signers != null) + if (signers != null) { return signers; + } + + JarConstraintsParameters params = + getParams(verifiedSigners, sigFileSigners); for (int i=0; i < digests.size(); i++) { - MessageDigest digest = digests.get(i); + MessageDigest digest = digests.get(i); + if (params != null) { + try { + params.setExtendedExceptionMsg(JarFile.MANIFEST_NAME, + name + " entry"); + DisabledAlgorithmConstraints.jarConstraints() + .permits(digest.getAlgorithm(), params); + } catch (GeneralSecurityException e) { + if (debug != null) { + debug.println("Digest algorithm is restricted: " + e); + } + return null; + } + } byte [] manHash = manifestHashes.get(i); byte [] theHash = digest.digest(); @@ -232,6 +248,38 @@ return signers; } + /** + * Get constraints parameters for JAR. The constraints should be + * checked against all code signers. Returns the parameters, + * or null if the signers for this entry have already been checked. + */ + private JarConstraintsParameters getParams( + Map verifiedSigners, + Map sigFileSigners) { + + // verifiedSigners is usually preloaded with the Manifest's signers. + // If verifiedSigners contains the Manifest, then it will have all of + // the signers of the JAR. But if it doesn't then we need to fallback + // and check verifiedSigners to see if the signers of this entry have + // been checked already. + if (verifiedSigners.containsKey(JarFile.MANIFEST_NAME)) { + if (verifiedSigners.size() > 1) { + // this means we already checked it previously + return null; + } else { + return new JarConstraintsParameters( + verifiedSigners.get(JarFile.MANIFEST_NAME)); + } + } else { + CodeSigner[] signers = sigFileSigners.get(name); + if (verifiedSigners.containsValue(signers)) { + return null; + } else { + return new JarConstraintsParameters(signers); + } + } + } + // for the toHex function private static final char[] hexc = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/util/SignatureFileVerifier.java --- a/src/share/classes/sun/security/util/SignatureFileVerifier.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/util/SignatureFileVerifier.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, 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 @@ -32,7 +32,6 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; -import java.security.Timestamp; import java.security.cert.CertPath; import java.security.cert.X509Certificate; import java.security.cert.CertificateException; @@ -45,6 +44,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.jar.Attributes; import java.util.jar.JarException; import java.util.jar.JarFile; @@ -59,10 +59,6 @@ /* Are we debugging ? */ private static final Debug debug = Debug.getInstance("jar"); - private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK = - new DisabledAlgorithmConstraints( - DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS); - private ArrayList signerCache; private static final String ATTR_DIGEST = @@ -92,13 +88,13 @@ /* for generating certpath objects */ private CertificateFactory certificateFactory = null; - /** Algorithms that have been checked if they are weak. */ - private Map permittedAlgs= new HashMap<>(); + /** Algorithms that have been previously checked against disabled + * constraints. + */ + private Map permittedAlgs = new HashMap<>(); - /** TSA timestamp of signed jar. The newest timestamp is used. If there - * was no TSA timestamp used when signed, current time is used ("null"). - */ - private Timestamp timestamp = null; + /** ConstraintsParameters for checking disabled algorithms */ + private JarConstraintsParameters params; /** * Create the named SignatureFileVerifier. @@ -291,32 +287,23 @@ name); } - CodeSigner[] newSigners = getSigners(infos, block); // make sure we have something to do all this work for... - if (newSigners == null) + if (newSigners == null) { return; + } - /* - * Look for the latest timestamp in the signature block. If an entry - * has no timestamp, use current time (aka null). - */ - for (CodeSigner s: newSigners) { - if (debug != null) { - debug.println("Gathering timestamp for: " + s.toString()); - } - if (s.getTimestamp() == null) { - timestamp = null; - break; - } else if (timestamp == null) { - timestamp = s.getTimestamp(); - } else { - if (timestamp.getTimestamp().before( - s.getTimestamp().getTimestamp())) { - timestamp = s.getTimestamp(); - } - } + // check if any of the algorithms used to verify the SignerInfos + // are disabled + params = new JarConstraintsParameters(newSigners); + Set notDisabledAlgorithms = + SignerInfo.verifyAlgorithms(infos, params, name + " PKCS7"); + + // add the SignerInfo algorithms that are ok to the permittedAlgs map + // so they are not checked again + for (String algorithm : notDisabledAlgorithms) { + permittedAlgs.put(algorithm, Boolean.TRUE); } Iterator> entries = @@ -367,13 +354,14 @@ * store the result. If the algorithm is in the map use that result. * False is returned for weak algorithm, true for good algorithms. */ - boolean permittedCheck(String key, String algorithm) { + private boolean permittedCheck(String key, String algorithm) { Boolean permitted = permittedAlgs.get(algorithm); if (permitted == null) { try { - JAR_DISABLED_CHECK.permits(algorithm, - new ConstraintsParameters(timestamp)); - } catch(GeneralSecurityException e) { + params.setExtendedExceptionMsg(name + ".SF", key + " attribute"); + DisabledAlgorithmConstraints + .jarConstraints().permits(algorithm, params); + } catch (GeneralSecurityException e) { permittedAlgs.put(algorithm, Boolean.FALSE); permittedAlgs.put(key.toUpperCase(), Boolean.FALSE); if (debug != null) { diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/validator/PKIXValidator.java --- a/src/share/classes/sun/security/validator/PKIXValidator.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/validator/PKIXValidator.java Fri Apr 23 01:47:38 2021 +0100 @@ -239,7 +239,7 @@ // add a new algorithm constraints checker if (constraints != null) { pkixParameters.addCertPathChecker( - new AlgorithmChecker(constraints, null, variant)); + new AlgorithmChecker(constraints, variant)); } // attach it to the PKIXBuilderParameters. diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/validator/SimpleValidator.java --- a/src/share/classes/sun/security/validator/SimpleValidator.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/validator/SimpleValidator.java Fri Apr 23 01:47:38 2021 +0100 @@ -162,7 +162,7 @@ AlgorithmChecker appAlgChecker = null; if (constraints != null) { appAlgChecker = new AlgorithmChecker(anchor, constraints, null, - null, variant); + variant); } // verify top down, starting at the certificate issued by diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/classes/sun/security/x509/AlgorithmId.java --- a/src/share/classes/sun/security/x509/AlgorithmId.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/classes/sun/security/x509/AlgorithmId.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -81,6 +81,7 @@ */ protected DerValue params; + private transient byte[] encodedParams; /** * Constructs an algorithm ID which will be initialized @@ -109,6 +110,18 @@ algid = oid; algParams = algparams; constructedFromDer = false; + if (algParams != null) { + try { + encodedParams = algParams.getEncoded(); + } catch (IOException ioe) { + // It should be safe to ignore this. + // This exception can occur if AlgorithmParameters was not + // initialized (which should not occur), or if it was + // initialized with bogus parameters, which should have + // been detected when init was called. + assert false; + } + } } private AlgorithmId(ObjectIdentifier oid, DerValue params) @@ -116,6 +129,7 @@ this.algid = oid; this.params = params; if (this.params != null) { + encodedParams = params.toByteArray(); decodeParams(); } } @@ -134,7 +148,7 @@ } // Decode (parse) the parameters - algParams.init(params.toByteArray()); + algParams.init(encodedParams.clone()); } /** @@ -153,6 +167,7 @@ * * @exception IOException on encoding error. */ + @Override public void derEncode (OutputStream out) throws IOException { DerOutputStream bytes = new DerOutputStream(); DerOutputStream tmp = new DerOutputStream(); @@ -160,8 +175,8 @@ bytes.putOID(algid); // Setup params from algParams since no DER encoding is given if (constructedFromDer == false) { - if (algParams != null) { - params = new DerValue(algParams.getEncoded()); + if (encodedParams != null) { + params = new DerValue(encodedParams); } else { params = null; } @@ -248,7 +263,7 @@ if ((params != null) && algid.equals((Object)specifiedWithECDSA_oid)) { try { AlgorithmId paramsId = - AlgorithmId.parse(new DerValue(params.toByteArray())); + AlgorithmId.parse(new DerValue(encodedParams)); String paramsName = paramsId.getName(); algName = makeSigAlg(paramsName, "EC"); } catch (IOException e) { @@ -266,6 +281,10 @@ * Returns the DER encoded parameter, which can then be * used to initialize java.security.AlgorithmParameters. * + * Note that this* method should always return a new array as it is called + * directly by the JDK implementation of X509Certificate.getSigAlgParams() + * and X509CRL.getSigAlgParams(). + * * Note: for ecdsa-with-SHA2 plus hash algorithm (Ex: SHA-256), this method * returns null because {@link #getName()} has already returned the "full" * signature algorithm (Ex: SHA256withECDSA). @@ -273,9 +292,9 @@ * @return DER encoded parameters, or null not present. */ public byte[] getEncodedParams() throws IOException { - return (params == null || algid.equals(specifiedWithECDSA_oid)) + return (encodedParams == null || algid.equals(specifiedWithECDSA_oid)) ? null - : params.toByteArray(); + : encodedParams.clone(); } /** @@ -283,9 +302,8 @@ * with the same parameters. */ public boolean equals(AlgorithmId other) { - boolean paramsEqual = - (params == null ? other.params == null : params.equals(other.params)); - return (algid.equals((Object)other.algid) && paramsEqual); + return algid.equals((Object)other.algid) && + Arrays.equals(encodedParams, other.encodedParams); } /** @@ -295,6 +313,7 @@ * * @param other preferably an AlgorithmId, else an ObjectIdentifier */ + @Override public boolean equals(Object other) { if (this == other) { return true; @@ -321,11 +340,11 @@ * * @return a hashcode for this AlgorithmId. */ + @Override public int hashCode() { - StringBuilder sbuf = new StringBuilder(); - sbuf.append(algid.toString()); - sbuf.append(paramsToString()); - return sbuf.toString().hashCode(); + int hashCode = algid.hashCode(); + hashCode = 31 * hashCode + Arrays.hashCode(encodedParams); + return hashCode; } /** @@ -333,10 +352,10 @@ * This may be redefined by subclasses which parse those parameters. */ protected String paramsToString() { - if (params == null) { + if (encodedParams == null) { return ""; } else if (algParams != null) { - return algParams.toString(); + return ", " + algParams.toString(); } else { return ", params unparsed"; } @@ -345,6 +364,7 @@ /** * Returns a string describing the algorithm and its parameters. */ + @Override public String toString() { return getName() + paramsToString(); } diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/lib/security/java.security-aix --- a/src/share/lib/security/java.security-aix Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/lib/security/java.security-aix Fri Apr 23 01:47:38 2021 +0100 @@ -1191,3 +1191,26 @@ # System value prevails. The default value of the property is "false". # #jdk.security.allowNonCaAnchor=true + +# +# JNDI Object Factories Filter +# +# This filter is used by the JNDI runtime to control the set of object factory classes +# which will be allowed to instantiate objects from object references returned by +# naming/directory systems. The factory class named by the reference instance will be +# matched against this filter. The filter property supports pattern-based filter syntax +# with the same format as jdk.serialFilter. +# +# Each pattern is matched against the factory class name to allow or disallow it's +# instantiation. The access to a factory class is allowed unless the filter returns +# REJECTED. +# +# Note: This property is currently used by the JDK Reference implementation. +# It is not guaranteed to be examined and used by other implementations. +# +# If the system property jdk.jndi.object.factoriesFilter is also specified, it supersedes +# the security property value defined here. The default value of the property is "*". +# +# The default pattern value allows any object factory class specified by the reference +# instance to recreate the referenced object. +#jdk.jndi.object.factoriesFilter=* \ No newline at end of file diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/lib/security/java.security-linux --- a/src/share/lib/security/java.security-linux Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/lib/security/java.security-linux Fri Apr 23 01:47:38 2021 +0100 @@ -1197,3 +1197,26 @@ # System value prevails. The default value of the property is "false". # #jdk.security.allowNonCaAnchor=true + +# +# JNDI Object Factories Filter +# +# This filter is used by the JNDI runtime to control the set of object factory classes +# which will be allowed to instantiate objects from object references returned by +# naming/directory systems. The factory class named by the reference instance will be +# matched against this filter. The filter property supports pattern-based filter syntax +# with the same format as jdk.serialFilter. +# +# Each pattern is matched against the factory class name to allow or disallow it's +# instantiation. The access to a factory class is allowed unless the filter returns +# REJECTED. +# +# Note: This property is currently used by the JDK Reference implementation. +# It is not guaranteed to be examined and used by other implementations. +# +# If the system property jdk.jndi.object.factoriesFilter is also specified, it supersedes +# the security property value defined here. The default value of the property is "*". +# +# The default pattern value allows any object factory class specified by the reference +# instance to recreate the referenced object. +#jdk.jndi.object.factoriesFilter=* \ No newline at end of file diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/lib/security/java.security-macosx --- a/src/share/lib/security/java.security-macosx Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/lib/security/java.security-macosx Fri Apr 23 01:47:38 2021 +0100 @@ -1195,3 +1195,26 @@ # System value prevails. The default value of the property is "false". # #jdk.security.allowNonCaAnchor=true + +# +# JNDI Object Factories Filter +# +# This filter is used by the JNDI runtime to control the set of object factory classes +# which will be allowed to instantiate objects from object references returned by +# naming/directory systems. The factory class named by the reference instance will be +# matched against this filter. The filter property supports pattern-based filter syntax +# with the same format as jdk.serialFilter. +# +# Each pattern is matched against the factory class name to allow or disallow it's +# instantiation. The access to a factory class is allowed unless the filter returns +# REJECTED. +# +# Note: This property is currently used by the JDK Reference implementation. +# It is not guaranteed to be examined and used by other implementations. +# +# If the system property jdk.jndi.object.factoriesFilter is also specified, it supersedes +# the security property value defined here. The default value of the property is "*". +# +# The default pattern value allows any object factory class specified by the reference +# instance to recreate the referenced object. +#jdk.jndi.object.factoriesFilter=* \ No newline at end of file diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/lib/security/java.security-solaris --- a/src/share/lib/security/java.security-solaris Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/lib/security/java.security-solaris Fri Apr 23 01:47:38 2021 +0100 @@ -1193,3 +1193,26 @@ # System value prevails. The default value of the property is "false". # #jdk.security.allowNonCaAnchor=true + +# +# JNDI Object Factories Filter +# +# This filter is used by the JNDI runtime to control the set of object factory classes +# which will be allowed to instantiate objects from object references returned by +# naming/directory systems. The factory class named by the reference instance will be +# matched against this filter. The filter property supports pattern-based filter syntax +# with the same format as jdk.serialFilter. +# +# Each pattern is matched against the factory class name to allow or disallow it's +# instantiation. The access to a factory class is allowed unless the filter returns +# REJECTED. +# +# Note: This property is currently used by the JDK Reference implementation. +# It is not guaranteed to be examined and used by other implementations. +# +# If the system property jdk.jndi.object.factoriesFilter is also specified, it supersedes +# the security property value defined here. The default value of the property is "*". +# +# The default pattern value allows any object factory class specified by the reference +# instance to recreate the referenced object. +#jdk.jndi.object.factoriesFilter=* \ No newline at end of file diff -r 1bb0d5a206fe -r 3df509b41e51 src/share/lib/security/java.security-windows --- a/src/share/lib/security/java.security-windows Fri Mar 26 17:13:49 2021 +0000 +++ b/src/share/lib/security/java.security-windows Fri Apr 23 01:47:38 2021 +0100 @@ -1195,3 +1195,26 @@ # System value prevails. The default value of the property is "false". # #jdk.security.allowNonCaAnchor=true + +# +# JNDI Object Factories Filter +# +# This filter is used by the JNDI runtime to control the set of object factory classes +# which will be allowed to instantiate objects from object references returned by +# naming/directory systems. The factory class named by the reference instance will be +# matched against this filter. The filter property supports pattern-based filter syntax +# with the same format as jdk.serialFilter. +# +# Each pattern is matched against the factory class name to allow or disallow it's +# instantiation. The access to a factory class is allowed unless the filter returns +# REJECTED. +# +# Note: This property is currently used by the JDK Reference implementation. +# It is not guaranteed to be examined and used by other implementations. +# +# If the system property jdk.jndi.object.factoriesFilter is also specified, it supersedes +# the security property value defined here. The default value of the property is "*". +# +# The default pattern value allows any object factory class specified by the reference +# instance to recreate the referenced object. +#jdk.jndi.object.factoriesFilter=* \ No newline at end of file diff -r 1bb0d5a206fe -r 3df509b41e51 src/windows/classes/java/lang/ProcessImpl.java --- a/src/windows/classes/java/lang/ProcessImpl.java Fri Mar 26 17:13:49 2021 +0000 +++ b/src/windows/classes/java/lang/ProcessImpl.java Fri Apr 23 01:47:38 2021 +0100 @@ -181,9 +181,9 @@ private static final char ESCAPE_VERIFICATION[][] = { // We guarantee the only command file execution for implicit [cmd.exe] run. // http://technet.microsoft.com/en-us/library/bb490954.aspx - {' ', '\t', '<', '>', '&', '|', '^'}, - {' ', '\t', '<', '>'}, - {' ', '\t', '<', '>'}, + {' ', '\t', '\"', '<', '>', '&', '|', '^'}, + {' ', '\t', '\"', '<', '>'}, + {' ', '\t', '\"', '<', '>'}, {' ', '\t'} }; @@ -243,18 +243,27 @@ } /** - * Return the argument without quotes (1st and last) if present, else the arg. + * Return the argument without quotes (1st and last) if properly quoted, else the arg. + * A properly quoted string has first and last characters as quote and + * the last quote is not escaped. * @param str a string - * @return the string without 1st and last quotes + * @return the string without quotes */ private static String unQuote(String str) { - int len = str.length(); - return (len >= 2 && str.charAt(0) == DOUBLEQUOTE && str.charAt(len - 1) == DOUBLEQUOTE) - ? str.substring(1, len - 1) - : str; + if (!str.startsWith("\"") || !str.endsWith("\"") || str.length() < 2) + return str; // no beginning or ending quote, or too short not quoted + + if (str.endsWith("\\\"")) { + return str; // not properly quoted, treat as unquoted + } + // Strip leading and trailing quotes + return str.substring(1, str.length() - 1); } private static boolean needsEscaping(int verificationType, String arg) { + if (arg.isEmpty()) + return true; // Empty string is to be quoted + // Switch off MS heuristic for internal ["]. // Please, use the explicit [cmd.exe] call // if you need the internal ["]. diff -r 1bb0d5a206fe -r 3df509b41e51 test/java/security/cert/X509Certificate/GetSigAlgParams.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/security/cert/X509Certificate/GetSigAlgParams.java Fri Apr 23 01:47:38 2021 +0100 @@ -0,0 +1,46 @@ +/* + * 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. + */ + +/* + * @test + * @bug 8259428 + * @summary Verify X509Certificate.getSigAlgParams() returns new array each + * time it is called + */ + +import java.security.cert.X509Certificate; +import sun.security.tools.keytool.CertAndKeyGen; +import sun.security.x509.X500Name; + +public class GetSigAlgParams { + + public static void main(String[] args) throws Exception { + + CertAndKeyGen cakg = new CertAndKeyGen("RSASSA-PSS", "RSASSA-PSS"); + cakg.generate(1024); + X509Certificate c = cakg.getSelfCertificate(new X500Name("CN=Me"), 100); + if (c.getSigAlgParams() == c.getSigAlgParams()) { + throw new Exception("Encoded params are the same byte array"); + } + } +} diff -r 1bb0d5a206fe -r 3df509b41e51 test/security/infra/java/security/cert/CertPathValidator/certification/HaricaCA.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/security/infra/java/security/cert/CertPathValidator/certification/HaricaCA.java Fri Apr 23 01:47:38 2021 +0100 @@ -0,0 +1,320 @@ +/* + * 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. + */ + +/* + * @test + * @bug 8256421 + * @summary Interoperability tests with Harica CAs + * @build ValidatePathWithParams + * @run main/othervm -Djava.security.debug=certpath HaricaCA OCSP + * @run main/othervm -Djava.security.debug=certpath HaricaCA CRL + */ + +/* + * Obtain test artifacts for Harica CA from: + * + * CA has no published test sites so we will need to communicate with CA for test. + */ +public class HaricaCA { + + public static void main(String[] args) throws Exception { + + ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); + boolean ocspEnabled = false; + + if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { + pathValidator.enableCRLCheck(); + } else { + // OCSP check by default + pathValidator.enableOCSPCheck(); + ocspEnabled = true; + } + + new Harica_CA().runTest(pathValidator, ocspEnabled); + new Harica_ECC().runTest(pathValidator, ocspEnabled); + } +} + +class Harica_CA { + + // Owner: CN=Hellenic Academic and Research Institutions Code Signing CA R1, + // O=Hellenic Academic and Research Institutions Cert. Authority, L=Athens, C=GR + // Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015, + // O=Hellenic Academic and Research Institutions Cert. Authority, L=Athens, C=GR + // Serial number: 1bc8b59e0cea0b7c + // Valid from: Fri Apr 08 00:37:41 PDT 2016 until: Sat Apr 06 00:37:41 PDT 2024 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIHnjCCBYagAwIBAgIIG8i1ngzqC3wwDQYJKoZIhvcNAQELBQAwgaYxCzAJBgNV\n" + + "BAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFjYWRl\n" + + "bWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAw\n" + + "PgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRp\n" + + "b25zIFJvb3RDQSAyMDE1MB4XDTE2MDQwODA3Mzc0MVoXDTI0MDQwNjA3Mzc0MVow\n" + + "ga0xCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxl\n" + + "bmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0\n" + + "aG9yaXR5MUcwRQYDVQQDEz5IZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2gg\n" + + "SW5zdGl0dXRpb25zIENvZGUgU2lnbmluZyBDQSBSMTCCAiIwDQYJKoZIhvcNAQEB\n" + + "BQADggIPADCCAgoCggIBAJYQhJz8QjfP1wOc1sHxTKe9wy7d3oBScTslX5Yn1IE8\n" + + "j5SzsKilvbu9rp8bd8IKHnPrl1Vnjpvna/Vx/XKlXDxnIxgfLINfmbjJRoEbzj1t\n" + + "fxdTnZSN5c6vHYr5112/XCr2VQ7gIL+2jujXlJQYs/aUzAb9RR35dy4z2tQJQwtA\n" + + "gG/paNGgnOU2ROrcaEYfvG4YQWaHAwqjJ53ZY5HVD7NmLp5SZTA5Q3eHAYae99fq\n" + + "iEgMti3zMejzrAM1h+iVpLUxA7iMFh5nwCOvYJWVYqN3YOEmksxh7HOWlpe1PgDT\n" + + "5SezPCHmOilNizMSRsdW7fE8apYVq/O0yStFW32kS9RQzYiBsdgPvNzDGec7Jj8X\n" + + "SozhS6to+A6RdgfpHccHc2jhIRkFocA63OEde3Eo/NPf/WbFX2tpgDIv+HF/YZV3\n" + + "iaMeKeOKDIxa4c3t3qBsZNtFEGOQyDouVH4g2Y8gHhUCcR7gQrHEYy/9FbtUDviu\n" + + "abBVPFnNbEwT0uKS20aLgldkJ4/b3UzeTVzXVwLB8ruBfZX/e60YFaUJAZbbYRbE\n" + + "mD6KmDOCTfalpBRhXar6U1wf+GRp1wv01Vw88EJ6VEBxXAYrfQ28ER9IuLqVQRlN\n" + + "xpZCP71DRCvWljkXAKvWrs3JAw926n5K7sL+fv6mn+6iGBHrSEcyX8g8EZv6XuLP\n" + + "AgMBAAGjggHFMIIBwTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAT\n" + + "BgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUDyz8Ez5xsy3SqelOr4FBCaaY\n" + + "3UgwRgYDVR0fBD8wPTA7oDmgN4Y1aHR0cDovL2NybHYxLmhhcmljYS5nci9IYXJp\n" + + "Y2FSb290Q0EyMDE1L2NybHYxLmRlci5jcmwwHwYDVR0jBBgwFoAUcRVnyMjJvXVd\n" + + "ctA4GGqd83EkVAswbgYIKwYBBQUHAQEEYjBgMCEGCCsGAQUFBzABhhVodHRwOi8v\n" + + "b2NzcC5oYXJpY2EuZ3IwOwYIKwYBBQUHMAKGL2h0dHA6Ly93d3cuaGFyaWNhLmdy\n" + + "L2NlcnRzL0hhcmljYVJvb3RDQTIwMTUuY3J0MIGQBgNVHSAEgYgwgYUwgYIGBFUd\n" + + "IAAwejAyBggrBgEFBQcCARYmaHR0cDovL3d3dy5oYXJpY2EuZ3IvZG9jdW1lbnRz\n" + + "L0NQUy5waHAwRAYIKwYBBQUHAgIwOAw2VGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJq\n" + + "ZWN0IHRvIEdyZWVrIGxhd3MgYW5kIG91ciBDUFMuMA0GCSqGSIb3DQEBCwUAA4IC\n" + + "AQA2t84B3ImFaWsnaYoPxwYu9njKaDc/QsaxT4AKP8env/Zr+fjD5s0Bjd1gZijC\n" + + "9LRTzIovpldc/yADy7SVboIH0uNEiBC0kc0DaCq0ceCGIe6dw92Mu9DJ3UpMGAuF\n" + + "fLpyearmfX9qzi0KhPGhjTxSTD4vWw3E0nvDVMBG54Im0OUGeVzZ9SpvRRhRnPOk\n" + + "1eplEYRRDVTGYQJ84GdVC4H4U3TjlbO9gppeSnBoVHyCqDDpyd8HhTuY3P5VRWaf\n" + + "dvAkwrW2Vv53zIYpDtcwG7mf4UXKbfYGtOIg/xaqHV82J6MYZHW1RNIlSh7F+1S5\n" + + "XamkPCQZZI87CMt/OZH+RaO87Vr2V02wkYwEeAvjOwq9l7LtOJaOznKS+BlMi009\n" + + "ljgHWUQcA2wk25hOAS3YtvhI1l2UrRHSqmHd7Jah4clskIjURt3b2Ez9nuZh1dC8\n" + + "NfaoPCkpK3leLBezubtq48MRe5jkAgen5UXvxq9zOZSen4pYeBK72ugNyLjzOhY8\n" + + "GrSeE1voLnvyZIguM2hrI8nEjI4rSXL6lsqXyG/ODzDMMdKq4FrjoW3y9KnV/n8t\n" + + "BvKTAlDcXQTqfdTykDWnxwNTp6dU+MOom9LGy6ZNFbei7XuvjrREiXUEJ/I2dGSD\n" + + "3zeNek32BS2BBZNN8jeP4szLs85G5HWql59OyePZfARA6Q==\n" + + "-----END CERTIFICATE-----"; + + // Owner: OID.1.3.6.1.4.1.311.60.2.1.3=GR, OID.2.5.4.15=Private Organization, + // CN=Greek Universities Network (GUnet), SERIALNUMBER=VATGR-099028220, + // OU=Class A - Private Key created and stored in hardware CSP, O=Greek Universities Network, L=Athens, C=GR + // Issuer: CN=Hellenic Academic and Research Institutions Code Signing CA R1, + // O=Hellenic Academic and Research Institutions Cert. Authority, L=Athens, C=GR + // Serial number: 2c9a7af519251c645c1bed40b9d1aeca + // Valid from: Mon Sep 09 01:15:13 PDT 2019 until: Wed Sep 08 01:15:13 PDT 2021 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIGyzCCBLOgAwIBAgIQLJp69RklHGRcG+1AudGuyjANBgkqhkiG9w0BAQsFADCB\n" + + "rTELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVu\n" + + "aWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRo\n" + + "b3JpdHkxRzBFBgNVBAMTPkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJ\n" + + "bnN0aXR1dGlvbnMgQ29kZSBTaWduaW5nIENBIFIxMB4XDTE5MDkwOTA4MTUxM1oX\n" + + "DTIxMDkwODA4MTUxM1owggEBMQswCQYDVQQGEwJHUjEPMA0GA1UEBwwGQXRoZW5z\n" + + "MSMwIQYDVQQKDBpHcmVlayBVbml2ZXJzaXRpZXMgTmV0d29yazFBMD8GA1UECww4\n" + + "Q2xhc3MgQSAtIFByaXZhdGUgS2V5IGNyZWF0ZWQgYW5kIHN0b3JlZCBpbiBoYXJk\n" + + "d2FyZSBDU1AxGDAWBgNVBAUTD1ZBVEdSLTA5OTAyODIyMDErMCkGA1UEAwwiR3Jl\n" + + "ZWsgVW5pdmVyc2l0aWVzIE5ldHdvcmsgKEdVbmV0KTEdMBsGA1UEDwwUUHJpdmF0\n" + + "ZSBPcmdhbml6YXRpb24xEzARBgsrBgEEAYI3PAIBAxMCR1IwggEiMA0GCSqGSIb3\n" + + "DQEBAQUAA4IBDwAwggEKAoIBAQDdkvuJzgjD3Hr1RoDtPZPp5ZelMl6Xh5vnKVuG\n" + + "KX9gwHbDaXpLkp2bF2497R3olBaeYcEgappsWLPvLMEA75BSRopFQmhX3PAsjfAG\n" + + "JZGM3A53n4NAQscCmtD6echJi4P6RThRcpfqObfe0vqZUVzSWRC8fU1P4lt/KzJj\n" + + "DGSJtOP/SJfgp3M7hEp54fn+15DlYp+0e4aa5HF2HpGIy2ghPbRvkMJWbHmp3KZG\n" + + "NOXViQdr/ogpqRsbdP7kN78WLhwrLu+xRUmf9A845jxyNO7269jOQHztfPAcgvDw\n" + + "NbZouGtN3IIWoXWMLipNgzC9CYdqgLsLI9lXV9oQrXaICQ27AgMBAAGjggGOMIIB\n" + + "ijAfBgNVHSMEGDAWgBQPLPwTPnGzLdKp6U6vgUEJppjdSDB0BggrBgEFBQcBAQRo\n" + + "MGYwQQYIKwYBBQUHMAKGNWh0dHA6Ly9yZXBvLmhhcmljYS5nci9jZXJ0cy9IYXJp\n" + + "Y2FDb2RlU2lnbmluZ0NBUjEuY3J0MCEGCCsGAQUFBzABhhVodHRwOi8vb2NzcC5o\n" + + "YXJpY2EuZ3IwYAYDVR0gBFkwVzAHBgVngQwBAzAIBgYEAI96AQIwQgYMKwYBBAGB\n" + + "zxEBAQMDMDIwMAYIKwYBBQUHAgEWJGh0dHBzOi8vcmVwby5oYXJpY2EuZ3IvZG9j\n" + + "dW1lbnRzL0NQUzATBgNVHSUEDDAKBggrBgEFBQcDAzBLBgNVHR8ERDBCMECgPqA8\n" + + "hjpodHRwOi8vY3JsdjEuaGFyaWNhLmdyL0hhcmljYUNvZGVTaWduaW5nQ0FSMS9j\n" + + "cmx2MS5kZXIuY3JsMB0GA1UdDgQWBBR0K0c/UEGkfRtqAEwoONenOUa0WTAOBgNV\n" + + "HQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggIBAHXVdzMwKeZSWmXZu/MyoyH8\n" + + "yTHYi/yvaPpR88/Q/j5wxzuceECZJgH74xgePCIXx74IKTADUyIj7eWuTkzEnZF9\n" + + "yqJyG+tArrIH7zdnjC0OgbJVFeUUY45rS24u8n/+46LnXy4A+bRa0qX/QikHxMvj\n" + + "0I0/RTZpdQFjhnmhZyZzUWReFlAEG1fUz9TNwcCfGrv3z6YHCNAh/HWFtM7te6H7\n" + + "LNjoRw0fC5edqI16ca2VrOLObbg64zdk7Ll/fu3Ll5UcAthve/PTez6R1wm47ETT\n" + + "ItjinmQI3vRhIls/UwvF4ey5Linz80rnzIlrrMgn3G2gRpfJ55CxsXOZDGS9iy8C\n" + + "jU8EiKkjbdDH6mOdQO11+FlwhBwSxVbr004RDPJJqKHKtKTWx6mEbW+ZrMXaEUNZ\n" + + "mSPwDCUgDzrFfSspYJL0UW7zV+SbK9u5nf09m6qOpkZ5OE91IEpkotTWqMe/yOJu\n" + + "Yey5wvAmEqQM6fcQCTfV5JBtzU5LOsm5Uwg728DcHfal21dJWtY3fi7+CgDRutU3\n" + + "Ee8uZUmCd/KCSQgP8B/QTu7wLXHd4IQz2EP2tmN9Zrv/MsDjpSHgRrU6Hwi49bPQ\n" + + "R43rmXHC7e2GZpBdPsfG0VDnpzgCx5Kogi5nJwwUevbvC2CT11AAlaOmTQPflqQj\n" + + "w2LPatMDMTAga/l+CE8j\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Greek Universities Network (GUnet), SERIALNUMBER=VATGR-099028220, + // OU=Class B - Private Key created and stored in software CSP, O=Greek Universities Network, L=Athens, C=GR + // Issuer: CN=Hellenic Academic and Research Institutions Code Signing CA R1, + // O=Hellenic Academic and Research Institutions Cert. Authority, L=Athens, C=GR + // Serial number: 29c4a7abf35bd0acb1638abbf22da1d3 + // Valid from: Mon Feb 17 01:47:19 PST 2020 until: Mon Feb 15 16:00:00 PST 2021 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIGmDCCBICgAwIBAgIQKcSnq/Nb0KyxY4q78i2h0zANBgkqhkiG9w0BAQsFADCB\n" + + "rTELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVu\n" + + "aWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRo\n" + + "b3JpdHkxRzBFBgNVBAMTPkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJ\n" + + "bnN0aXR1dGlvbnMgQ29kZSBTaWduaW5nIENBIFIxMB4XDTIwMDIxNzA5NDcxOVoX\n" + + "DTIxMDIxNjAwMDAwMFowgc0xCzAJBgNVBAYTAkdSMQ8wDQYDVQQHDAZBdGhlbnMx\n" + + "IzAhBgNVBAoMGkdyZWVrIFVuaXZlcnNpdGllcyBOZXR3b3JrMUEwPwYDVQQLDDhD\n" + + "bGFzcyBCIC0gUHJpdmF0ZSBLZXkgY3JlYXRlZCBhbmQgc3RvcmVkIGluIHNvZnR3\n" + + "YXJlIENTUDEYMBYGA1UEBRMPVkFUR1ItMDk5MDI4MjIwMSswKQYDVQQDDCJHcmVl\n" + + "ayBVbml2ZXJzaXRpZXMgTmV0d29yayAoR1VuZXQpMIIBIjANBgkqhkiG9w0BAQEF\n" + + "AAOCAQ8AMIIBCgKCAQEArSBfy0xwIHpFxFrAHiYpMOkILjOvlhRCBmfzrJFSILou\n" + + "8vc1wxZw/olBa38khtIybE0GJnzZqoFTsalAcLg0CzfqucDoWL+uVLURmEmYZExj\n" + + "ngYfjrpB7ypjWqxfBVqqLgxugY1XV3oaQRNWgFEn/mrQhv+0azySJdRSiW0BH4rP\n" + + "wXp9LHgzHc7oxVOHsOKApwRN7TRVKz0/EoPhyUzdk5xoRTQMRalwZ0/E24v+CyoF\n" + + "bPl/v+dlRK5n9It8yjCtqOMZ1z7l8sKmJ7q9iLvzAF58a8B5lPueC+opHPEy4VD0\n" + + "7xZHYgdHliDsVIcWDXAzfcfo7l9EUX17onEXKMWKDwIDAQABo4IBkDCCAYwwHwYD\n" + + "VR0jBBgwFoAUDyz8Ez5xsy3SqelOr4FBCaaY3UgwdAYIKwYBBQUHAQEEaDBmMEEG\n" + + "CCsGAQUFBzAChjVodHRwOi8vcmVwby5oYXJpY2EuZ3IvY2VydHMvSGFyaWNhQ29k\n" + + "ZVNpZ25pbmdDQVIxLmNydDAhBggrBgEFBQcwAYYVaHR0cDovL29jc3AuaGFyaWNh\n" + + "LmdyMGIGA1UdIARbMFkwCAYGZ4EMAQQBMAgGBgQAj3oBATBDBg0rBgEEAYHPEQEB\n" + + "AwEBMDIwMAYIKwYBBQUHAgEWJGh0dHBzOi8vcmVwby5oYXJpY2EuZ3IvZG9jdW1l\n" + + "bnRzL0NQUzATBgNVHSUEDDAKBggrBgEFBQcDAzBLBgNVHR8ERDBCMECgPqA8hjpo\n" + + "dHRwOi8vY3JsdjEuaGFyaWNhLmdyL0hhcmljYUNvZGVTaWduaW5nQ0FSMS9jcmx2\n" + + "MS5kZXIuY3JsMB0GA1UdDgQWBBTj6v8Qkmosm+VNGsd/prwylbsM7TAOBgNVHQ8B\n" + + "Af8EBAMCB4AwDQYJKoZIhvcNAQELBQADggIBADYBQvc68KwX28UFeE/nXcowBTSd\n" + + "z+tQexloeBa4Z5G0yRr9URPc95H1R4SJiGQxb/KKqX2LqZtowc5rOXFBchI3da24\n" + + "kn8pmoi4/U2o8iS+DSlAMsn4ZW2lyDd0jyNeRiuZXvkdpqxa9u/x0TyXJ6qUxSYM\n" + + "oUC/H7RI1rxA+NgQ+otLHVs4ye53qzO44mXJv5Qq4dQ+GEdD+dShrYs69WMC0mV0\n" + + "mVs//R1qp8G3tThAiJJF55kV8w1JH2+yv8RXAdQ2cRpN2W6wsnm2DxldHKM4Kel4\n" + + "ON0TXlARGjoGqfEjFyZYtvpjzIPGoj3MHgCdiVb+zQJavYZJfLymlnIXajVb80Hh\n" + + "9xSar/uZ0NwtZgX8EwOrBiDUuCjyvlYrcbpSN26Q4fuUfPdIJQXMQDLTFMQLQ/o4\n" + + "5dn9FLLaJF7CA8VFeyJYi9pWEiIIpmPzIibd2+CAEQ43Q87GAvLpC09Rf6yggRh5\n" + + "by/FAOOzfbEQMhvJfGcJrPeG8JdzG95N5ycAeeyb/iboYptRwsLWwurASmUEKn0y\n" + + "BHlQPhut0mqNJQsoxvW6yIipFAQPBxfRHeLG71UO1kRxCleDTMsb3Zzt8hv1G4+m\n" + + "Nsm3ZMOV8TMdlBxYO/xA9dqwAxMuPvShx6LdiiyQhdeEmIFvKZeTD22cIOVLDsrd\n" + + "D2GbhbvPInvh21Qz\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Mon Feb 17 02:00:10 PST 2020", System.out); + } +} + +class Harica_ECC { + + // Owner: CN=HARICA Code Signing ECC SubCA R2, + // O=Hellenic Academic and Research Institutions Cert. Authority, L=Athens, C=GR + // Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015, + // O=Hellenic Academic and Research Institutions Cert. Authority, L=Athens, C=GR + // Serial number: 1f6ea9c2f4d7f80ee6a046d8b822dd3f + // Valid from: Wed Mar 06 02:49:26 PST 2019 until: Thu Mar 02 02:49:26 PST 2034 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIDxzCCA02gAwIBAgIQH26pwvTX+A7moEbYuCLdPzAKBggqhkjOPQQDAzCBqjEL\n" + + "MAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg\n" + + "QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3Jp\n" + + "dHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0\n" + + "aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE5MDMwNjEwNDkyNloXDTM0MDMw\n" + + "MjEwNDkyNlowgY8xCzAJBgNVBAYTAkdSMQ8wDQYDVQQHDAZBdGhlbnMxRDBCBgNV\n" + + "BAoMO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMg\n" + + "Q2VydC4gQXV0aG9yaXR5MSkwJwYDVQQDDCBIQVJJQ0EgQ29kZSBTaWduaW5nIEVD\n" + + "QyBTdWJDQSBSMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABKPWDfLT76KnCZ7dujms\n" + + "bFYFLTvCWTyk8l0JqdhvZ+Tk6dWYAViIX90fc8+3HPAdHvkofNWvI/PW0qlZoRn3\n" + + "De/Nrp+ZCWjg7UrUrmKH2z/N3A7lgZFqrwlWPxHSPSYVkqOCAU8wggFLMBIGA1Ud\n" + + "EwEB/wQIMAYBAf8CAQAwHwYDVR0jBBgwFoAUtCILgpkkAQ6cu+QO/b/7lyCTmSow\n" + + "cgYIKwYBBQUHAQEEZjBkMD8GCCsGAQUFBzAChjNodHRwOi8vcmVwby5oYXJpY2Eu\n" + + "Z3IvY2VydHMvSGFyaWNhRUNDUm9vdENBMjAxNS5jcnQwIQYIKwYBBQUHMAGGFWh0\n" + + "dHA6Ly9vY3NwLmhhcmljYS5ncjARBgNVHSAECjAIMAYGBFUdIAAwEwYDVR0lBAww\n" + + "CgYIKwYBBQUHAwMwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NybHYxLmhhcmlj\n" + + "YS5nci9IYXJpY2FFQ0NSb290Q0EyMDE1L2NybHYxLmRlci5jcmwwHQYDVR0OBBYE\n" + + "FMdgA8SpJhybKTZTnW4Xu3NWRKZeMA4GA1UdDwEB/wQEAwIBhjAKBggqhkjOPQQD\n" + + "AwNoADBlAjAcJj7q9ujC+87/b81QowGo87VJhn9XWzRtpwjQFbIilqEfO3ot1d5F\n" + + "MWT1Xn2Qg3sCMQCoM+eV2KkQluHn2N6+GMImJqVObVUyZv0E+BvvszdJubo1cAM0\n" + + "SUImVT1t2wZpJKg=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Dimitrios Zacharopoulos, GIVENNAME=Dimitrios, SURNAME=Zacharopoulos, + // OU=Class B - Private Key created and stored in software CSP, + // O=Hellenic Academic and Research Institutions Cert. Authority, L=Athens, C=GR + // Issuer: CN=HARICA Code Signing ECC SubCA R2, O=Hellenic Academic and Research Institutions Cert. Authority, + // L=Athens, C=GR + // Serial number: 11a187e3b5b0eabea4ba4987e76cd09d + // Valid from: Fri Jul 31 02:11:08 PDT 2020 until: Sun Jul 31 02:11:08 PDT 2022 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIENTCCA7ugAwIBAgIQEaGH47Ww6r6kukmH52zQnTAKBggqhkjOPQQDAzCBjzEL\n" + + "MAkGA1UEBhMCR1IxDzANBgNVBAcMBkF0aGVuczFEMEIGA1UECgw7SGVsbGVuaWMg\n" + + "QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3Jp\n" + + "dHkxKTAnBgNVBAMMIEhBUklDQSBDb2RlIFNpZ25pbmcgRUNDIFN1YkNBIFIyMB4X\n" + + "DTIwMDczMTA5MTEwOFoXDTIyMDczMTA5MTEwOFowgfUxCzAJBgNVBAYTAkdSMQ8w\n" + + "DQYDVQQHDAZBdGhlbnMxRDBCBgNVBAoMO0hlbGxlbmljIEFjYWRlbWljIGFuZCBS\n" + + "ZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUEwPwYDVQQLDDhD\n" + + "bGFzcyBCIC0gUHJpdmF0ZSBLZXkgY3JlYXRlZCBhbmQgc3RvcmVkIGluIHNvZnR3\n" + + "YXJlIENTUDEWMBQGA1UEBAwNWmFjaGFyb3BvdWxvczESMBAGA1UEKgwJRGltaXRy\n" + + "aW9zMSAwHgYDVQQDDBdEaW1pdHJpb3MgWmFjaGFyb3BvdWxvczBZMBMGByqGSM49\n" + + "AgEGCCqGSM49AwEHA0IABOzRSqoI9HoxXjWerBBw8Croi1bJlUzoFXGjdszJIThf\n" + + "UG3YOiR1whG7wY5H5v8v4IIB5pJanArJk4CzxBLKob6jggGPMIIBizAfBgNVHSME\n" + + "GDAWgBTHYAPEqSYcmyk2U51uF7tzVkSmXjB6BggrBgEFBQcBAQRuMGwwRwYIKwYB\n" + + "BQUHMAKGO2h0dHA6Ly9yZXBvLmhhcmljYS5nci9jZXJ0cy9IYXJpY2FFQ0NDb2Rl\n" + + "U2lnbmluZ1N1YkNBUjIuY3J0MCEGCCsGAQUFBzABhhVodHRwOi8vb2NzcC5oYXJp\n" + + "Y2EuZ3IwYQYDVR0gBFowWDAIBgZngQwBBAEwCAYGBACPegEBMEIGDCsGAQQBgc8R\n" + + "AQMCATAyMDAGCCsGAQUFBwIBFiRodHRwczovL3JlcG8uaGFyaWNhLmdyL2RvY3Vt\n" + + "ZW50cy9DUFMwEwYDVR0lBAwwCgYIKwYBBQUHAwMwRQYDVR0fBD4wPDA6oDigNoY0\n" + + "aHR0cDovL2NybC5oYXJpY2EuZ3IvSGFyaWNhRUNDQ29kZVNpZ25pbmdTdWJDQVIy\n" + + "LmNybDAdBgNVHQ4EFgQUpNjChUi9LGgwz7E18N1EwXooEFcwDgYDVR0PAQH/BAQD\n" + + "AgeAMAoGCCqGSM49BAMDA2gAMGUCMQCDvQIjqgssTRHqp+gu7l21XmAQ4EMqr4+B\n" + + "05iU/edLxxV+z5roTswxnPnr43+EbvkCMHq4aFW1u1+RvPBQJNRnYmdXCnj0lUw4\n" + + "Ug7JnsEYMffLakDudzgsNv5ByJf9SO84Lw==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Greek Universities Network (GUnet), SERIALNUMBER=VATGR-099028220, + // OU=Class B - Private Key created and stored in software CSP, O=Greek Universities Network, L=Athens, C=GR + // Issuer: CN=HARICA Code Signing ECC SubCA R2, O=Hellenic Academic and Research Institutions Cert. Authority, + // L=Athens, C=GR + // Serial number: 4b14719c7195c96de8a5663724454205 + // Valid from: Mon Feb 17 01:48:32 PST 2020 until: Mon Feb 15 16:00:00 PST 2021 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIEDjCCA5SgAwIBAgIQSxRxnHGVyW3opWY3JEVCBTAKBggqhkjOPQQDAzCBjzEL\n" + + "MAkGA1UEBhMCR1IxDzANBgNVBAcMBkF0aGVuczFEMEIGA1UECgw7SGVsbGVuaWMg\n" + + "QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3Jp\n" + + "dHkxKTAnBgNVBAMMIEhBUklDQSBDb2RlIFNpZ25pbmcgRUNDIFN1YkNBIFIyMB4X\n" + + "DTIwMDIxNzA5NDgzMloXDTIxMDIxNjAwMDAwMFowgc0xCzAJBgNVBAYTAkdSMQ8w\n" + + "DQYDVQQHDAZBdGhlbnMxIzAhBgNVBAoMGkdyZWVrIFVuaXZlcnNpdGllcyBOZXR3\n" + + "b3JrMUEwPwYDVQQLDDhDbGFzcyBCIC0gUHJpdmF0ZSBLZXkgY3JlYXRlZCBhbmQg\n" + + "c3RvcmVkIGluIHNvZnR3YXJlIENTUDEYMBYGA1UEBRMPVkFUR1ItMDk5MDI4MjIw\n" + + "MSswKQYDVQQDDCJHcmVlayBVbml2ZXJzaXRpZXMgTmV0d29yayAoR1VuZXQpMFkw\n" + + "EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECC+lD6hphUDLSGs/Vw4Tvj8RAuCQAyi+\n" + + "MUiXXXzGSp5e6ksBVlRlawluNR+BUtY93BRCjjNr3OuvSVALyrH7HKOCAZAwggGM\n" + + "MB8GA1UdIwQYMBaAFMdgA8SpJhybKTZTnW4Xu3NWRKZeMHoGCCsGAQUFBwEBBG4w\n" + + "bDBHBggrBgEFBQcwAoY7aHR0cDovL3JlcG8uaGFyaWNhLmdyL2NlcnRzL0hhcmlj\n" + + "YUVDQ0NvZGVTaWduaW5nU3ViQ0FSMi5jcnQwIQYIKwYBBQUHMAGGFWh0dHA6Ly9v\n" + + "Y3NwLmhhcmljYS5ncjBiBgNVHSAEWzBZMAgGBmeBDAEEATAIBgYEAI96AQEwQwYN\n" + + "KwYBBAGBzxEBAQMBATAyMDAGCCsGAQUFBwIBFiRodHRwczovL3JlcG8uaGFyaWNh\n" + + "LmdyL2RvY3VtZW50cy9DUFMwEwYDVR0lBAwwCgYIKwYBBQUHAwMwRQYDVR0fBD4w\n" + + "PDA6oDigNoY0aHR0cDovL2NybC5oYXJpY2EuZ3IvSGFyaWNhRUNDQ29kZVNpZ25p\n" + + "bmdTdWJDQVIyLmNybDAdBgNVHQ4EFgQUT4+WfQu125tLqla60vhK7ijBBWkwDgYD\n" + + "VR0PAQH/BAQDAgeAMAoGCCqGSM49BAMDA2gAMGUCMQDADGDAxKpUkyEKBLzpX+88\n" + + "ONLYDgFSie5W2ULWk02sDRO/k5xcSSjTf0FFa4+l6E8CME/b27e7NUGHPVYTLTWL\n" + + "5yPiboyNsT8QpV+hZiWh/Qqiw1E/bR2SPIGEwYUrOV61fA==\n" + + "-----END CERTIFICATE-----"; + + public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { + // Validate valid + pathValidator.validate(new String[]{VALID, INT}, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(new String[]{REVOKED, INT}, + ValidatePathWithParams.Status.REVOKED, + "Mon Feb 17 02:00:57 PST 2020", System.out); + } +} diff -r 1bb0d5a206fe -r 3df509b41e51 test/sun/security/pkcs/pkcs8/PKCS8Test.java --- a/test/sun/security/pkcs/pkcs8/PKCS8Test.java Fri Mar 26 17:13:49 2021 +0000 +++ b/test/sun/security/pkcs/pkcs8/PKCS8Test.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -53,7 +53,7 @@ static final DerOutputStream derOutput = new DerOutputStream(); static final String FORMAT = "PKCS#8"; - static final String EXPECTED_ALG_ID_CHRS = "DSA\n\tp: 02\n\tq: 03\n" + static final String EXPECTED_ALG_ID_CHRS = "DSA, \n\tp: 02\n\tq: 03\n" + "\tg: 04\n"; static final String ALGORITHM = "DSA"; static final String EXCEPTION_MESSAGE = "version mismatch: (supported: " diff -r 1bb0d5a206fe -r 3df509b41e51 test/sun/security/tools/jarsigner/TimestampCheck.java --- a/test/sun/security/tools/jarsigner/TimestampCheck.java Fri Mar 26 17:13:49 2021 +0000 +++ b/test/sun/security/tools/jarsigner/TimestampCheck.java Fri Apr 23 01:47:38 2021 +0100 @@ -450,7 +450,7 @@ sign("tsdisabled", "-digestalg", "MD5", "-sigalg", "MD5withRSA", "-tsadigestalg", "MD5") .shouldHaveExitValue(68) - .shouldContain("The timestamp is invalid. Without a valid timestamp") + .shouldContain("TSA certificate chain is invalid") .shouldMatch("MD5.*-digestalg.*is disabled") .shouldMatch("MD5.*-tsadigestalg.*is disabled") .shouldMatch("MD5withRSA.*-sigalg.*is disabled"); @@ -458,7 +458,6 @@ signVerbose("tsdisabled", "unsigned.jar", "tsdisabled2.jar", "signer") .shouldHaveExitValue(64) - .shouldContain("The timestamp is invalid. Without a valid timestamp") .shouldContain("TSA certificate chain is invalid"); // Disabled timestamp is an error and jar treated unsigned @@ -771,7 +770,7 @@ .shouldMatch("Timestamp signature algorithm: .*key.*(disabled)"); verify(file, "-J-Djava.security.debug=jar") .shouldHaveExitValue(16) - .shouldMatch("SignatureException:.*disabled"); + .shouldMatch("SignatureException:.*keysize"); } static void checkHalfWeak(String file) throws Exception { diff -r 1bb0d5a206fe -r 3df509b41e51 test/sun/security/x509/AlgorithmId/AlgorithmIdEqualsHashCode.java --- a/test/sun/security/x509/AlgorithmId/AlgorithmIdEqualsHashCode.java Fri Mar 26 17:13:49 2021 +0000 +++ b/test/sun/security/x509/AlgorithmId/AlgorithmIdEqualsHashCode.java Fri Apr 23 01:47:38 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -24,12 +24,16 @@ /* * @test * @author Gary Ellison - * @bug 4170635 + * @bug 4170635 8258247 * @summary Verify equals()/hashCode() contract honored */ import java.io.*; +import java.security.AlgorithmParameters; +import java.security.spec.MGF1ParameterSpec; +import java.security.spec.PSSParameterSpec; +import sun.security.util.DerValue; import sun.security.x509.*; public class AlgorithmIdEqualsHashCode { @@ -40,7 +44,6 @@ AlgorithmId ai2 = AlgorithmId.get("DH"); AlgorithmId ai3 = AlgorithmId.get("DH"); - // supposedly transitivity is broken // System.out.println(ai1.equals(ai2)); // System.out.println(ai2.equals(ai3)); @@ -56,5 +59,42 @@ else throw new Exception("Failed equals()/hashCode() contract"); + // check that AlgorithmIds with same name but different params + // are not equal + AlgorithmParameters algParams1 = + AlgorithmParameters.getInstance("RSASSA-PSS"); + AlgorithmParameters algParams2 = + AlgorithmParameters.getInstance("RSASSA-PSS"); + algParams1.init(new PSSParameterSpec("SHA-1", "MGF1", + MGF1ParameterSpec.SHA1, 20, PSSParameterSpec.TRAILER_FIELD_BC)); + algParams2.init(new PSSParameterSpec("SHA-256", "MGF1", + MGF1ParameterSpec.SHA1, 20, PSSParameterSpec.TRAILER_FIELD_BC)); + ai1 = new AlgorithmId(AlgorithmId.RSASSA_PSS_oid, algParams1); + ai2 = new AlgorithmId(AlgorithmId.RSASSA_PSS_oid, algParams2); + if (ai1.equals(ai2)) { + throw new Exception("Failed equals() contract"); + } else { + System.out.println("PASSED equals() test"); + } + + // check that two AlgorithmIds created with the same parameters but + // one with DER encoded parameters and the other with + // AlgorithmParameters are equal + byte[] encoded = ai1.encode(); + ai3 = AlgorithmId.parse(new DerValue(encoded)); + if (!ai1.equals(ai3)) { + throw new Exception("Failed equals() contract"); + } else { + System.out.println("PASSED equals() test"); + } + + // check that two AlgorithmIds created with different parameters but + // one with DER encoded parameters and the other with + // AlgorithmParameters are not equal + if (ai2.equals(ai3)) { + throw new Exception("Failed equals() contract"); + } else { + System.out.println("PASSED equals() test"); + } } } diff -r 1bb0d5a206fe -r 3df509b41e51 test/sun/util/calendar/zi/tzdata/VERSION --- a/test/sun/util/calendar/zi/tzdata/VERSION Fri Mar 26 17:13:49 2021 +0000 +++ b/test/sun/util/calendar/zi/tzdata/VERSION Fri Apr 23 01:47:38 2021 +0100 @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2020f +tzdata2021a diff -r 1bb0d5a206fe -r 3df509b41e51 test/sun/util/calendar/zi/tzdata/africa --- a/test/sun/util/calendar/zi/tzdata/africa Fri Mar 26 17:13:49 2021 +0000 +++ b/test/sun/util/calendar/zi/tzdata/africa Fri Apr 23 01:47:38 2021 +0100 @@ -1550,11 +1550,17 @@ 3:00 - EAT 2017 Nov 1 2:00 - CAT +# From Steffen Thorsen (2021-01-18): +# "South Sudan will change its time zone by setting the clock back 1 +# hour on February 1, 2021...." +# from https://eyeradio.org/south-sudan-adopts-new-time-zone-makuei/ + # South Sudan # Zone NAME STDOFF RULES FORMAT [UNTIL] Zone Africa/Juba 2:06:28 - LMT 1931 2:00 Sudan CA%sT 2000 Jan 15 12:00 - 3:00 - EAT + 3:00 - EAT 2021 Feb 1 00:00 + 2:00 - CAT # Tanzania # See Africa/Nairobi. diff -r 1bb0d5a206fe -r 3df509b41e51 test/sun/util/calendar/zi/tzdata/leapseconds --- a/test/sun/util/calendar/zi/tzdata/leapseconds Fri Mar 26 17:13:49 2021 +0000 +++ b/test/sun/util/calendar/zi/tzdata/leapseconds Fri Apr 23 01:47:38 2021 +0100 @@ -95,11 +95,11 @@ # Any additional leap seconds will come after this. # This Expires line is commented out for now, # so that pre-2020a zic implementations do not reject this file. -#Expires 2021 Jun 28 00:00:00 +#Expires 2021 Dec 28 00:00:00 # POSIX timestamps for the data in this file: #updated 1467936000 (2016-07-08 00:00:00 UTC) -#expires 1624838400 (2021-06-28 00:00:00 UTC) +#expires 1640649600 (2021-12-28 00:00:00 UTC) -# Updated through IERS Bulletin C60 -# File expires on: 28 June 2021 +# Updated through IERS Bulletin C61 +# File expires on: 28 December 2021