changeset 10004:b8b51d9e706f icedtea-2.6.24 icedtea-2.6.25pre00

Merge jdk7u281-ga
author Andrew John Hughes <gnu.andrew@redhat.com>
date Mon, 02 Nov 2020 02:26:27 +0000
parents 1a9e79164f5e (current diff) 56d605a52388 (diff)
children acd1283303a8
files .hgtags src/share/classes/com/sun/jndi/ldap/Connection.java src/share/classes/com/sun/jndi/ldap/LdapClient.java src/share/classes/com/sun/jndi/ldap/LdapCtx.java src/share/native/sun/awt/image/jpeg/jpeg-6b/jdhuff.c src/share/native/sun/awt/image/jpeg/jpeg-6b/jdinput.c src/share/native/sun/awt/image/jpeg/jpeg-6b/jdmarker.c src/share/native/sun/awt/image/jpeg/jpeg-6b/jmemnobs.c src/share/native/sun/awt/image/jpeg/jpeg-6b/jpeglib.h
diffstat 20 files changed, 432 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Sat Sep 26 19:05:32 2020 +0100
+++ b/.hgtags	Mon Nov 02 02:26:27 2020 +0000
@@ -725,3 +725,6 @@
 5b06aa7a2fcc0e17cafbcce2456978da85677c56 jdk7u271-ga
 6d1d19e80aa0dab8aa3e9b53549b0c91d3f2798d icedtea-2.6.23
 6d1d19e80aa0dab8aa3e9b53549b0c91d3f2798d icedtea-2.6.24pre00
+5b06aa7a2fcc0e17cafbcce2456978da85677c56 jdk7u281-b00
+963d6ac6635a93e024892a977b7cf31974c820be jdk7u281-b01
+963d6ac6635a93e024892a977b7cf31974c820be jdk7u281-ga
--- a/src/share/classes/com/sun/jndi/ldap/Connection.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/classes/com/sun/jndi/ldap/Connection.java	Mon Nov 02 02:26:27 2020 +0000
@@ -158,6 +158,13 @@
 
     int readTimeout;
     int connectTimeout;
+
+    // Is connection upgraded to SSL via STARTTLS extended operation
+    private volatile boolean isUpgradedToStartTls;
+
+    // Lock to maintain isUpgradedToStartTls state
+    final Object startTlsLock = new Object();
+
     private static final boolean IS_HOSTNAME_VERIFICATION_DISABLED
             = hostnameVerificationDisabledValue();
 
@@ -745,6 +752,23 @@
         outStream = newOut;
     }
 
+    /*
+     * Replace streams and set isUpdradedToStartTls flag to the provided value
+     */
+    synchronized public void replaceStreams(InputStream newIn, OutputStream newOut, boolean isStartTls) {
+        synchronized (startTlsLock) {
+            replaceStreams(newIn, newOut);
+            isUpgradedToStartTls = isStartTls;
+        }
+    }
+
+    /*
+     * Returns true if connection was upgraded to SSL with STARTTLS extended operation
+     */
+    public boolean isUpgradedToStartTls() {
+        return isUpgradedToStartTls;
+    }
+
     /**
      * Used by Connection thread to read inStream into a local variable.
      * This ensures that there is no contention between the main thread
@@ -899,6 +923,11 @@
                     // is equal to & 0x80 (i.e. length byte with high bit off).
                     if ((seqlen & 0x80) == 0x80) {
                         seqlenlen = seqlen & 0x7f;  // number of length bytes
+                        // Check the length of length field, since seqlen is int
+                        // the number of bytes can't be greater than 4
+                        if (seqlenlen > 4) {
+                            throw new IOException("Length coded with too many bytes: " + seqlenlen);
+                        }
 
                         bytesread = 0;
                         eos = false;
@@ -926,6 +955,13 @@
                         offset += bytesread;
                     }
 
+                    if (seqlenlen > bytesread) {
+                        throw new IOException("Unexpected EOF while reading length");
+                    }
+
+                    if (seqlen < 0) {
+                        throw new IOException("Length too big: " + (((long) seqlen) & 0xFFFFFFFFL));
+                    }
                     // read in seqlen bytes
                     byte[] left = readFully(in, seqlen);
                     inbuf = Arrays.copyOf(inbuf, offset + left.length);
--- a/src/share/classes/com/sun/jndi/ldap/LdapClient.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/classes/com/sun/jndi/ldap/LdapClient.java	Mon Nov 02 02:26:27 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, 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
@@ -396,6 +396,12 @@
         return (conn.inStream instanceof SaslInputStream);
     }
 
+    // Returns true if client connection was upgraded
+    // with STARTTLS extended operation on the server side
+    boolean isUpgradedToStartTls() {
+        return conn.isUpgradedToStartTls();
+    }
+
     synchronized void incRefCount() {
         ++referenceCount;
         if (debug > 1) {
--- a/src/share/classes/com/sun/jndi/ldap/LdapCtx.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/classes/com/sun/jndi/ldap/LdapCtx.java	Mon Nov 02 02:26:27 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2017, 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
@@ -33,13 +33,19 @@
 import javax.naming.ldap.LdapName;
 import javax.naming.ldap.Rdn;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
 import java.util.Locale;
+import java.util.Set;
 import java.util.Vector;
 import java.util.Hashtable;
+import java.util.HashSet;
 import java.util.List;
 import java.util.StringTokenizer;
 import java.util.Enumeration;
 
+
 import java.io.IOException;
 import java.io.OutputStream;
 
@@ -200,6 +206,27 @@
     private static final String REPLY_QUEUE_SIZE =
         "com.sun.jndi.ldap.search.replyQueueSize";
 
+    // System and environment property name to control allowed list of
+    // authentication mechanisms: "all" or "" or "mech1,mech2,...,mechN"
+    //  "all": allow all mechanisms,
+    //  "": allow none
+    //  or comma separated list of allowed authentication mechanisms
+    // Note: "none" or "anonymous" are always allowed.
+    private static final String ALLOWED_MECHS_SP =
+            "jdk.jndi.ldap.mechsAllowedToSendCredentials";
+
+    // System property value
+    private static final String ALLOWED_MECHS_SP_VALUE =
+            getMechsAllowedToSendCredentials();
+
+    // Set of authentication mechanisms allowed by the system property
+    private static final Set<String> MECHS_ALLOWED_BY_SP =
+            getMechsFromPropertyValue(ALLOWED_MECHS_SP_VALUE);
+
+    // The message to use in NamingException if the transmission of plain credentials are not allowed
+    private static final String UNSECURED_CRED_TRANSMIT_MSG =
+                "Transmission of credentials over unsecured connection is not allowed";
+
     // ----------------- Fields that don't change -----------------------
     private static final NameParser parser = new LdapNameParser();
 
@@ -235,7 +262,8 @@
     Name currentParsedDN;               // DN of this context
     Vector<Control> respCtls = null;    // Response controls read
     Control[] reqCtls = null;           // Controls to be sent with each request
-
+    // Used to track if context was seen to be secured with STARTTLS extended operation
+    volatile boolean contextSeenStartTlsEnabled;
 
     // ------------- Private instance variables ------------------------
 
@@ -2669,6 +2697,82 @@
         ensureOpen();      // open or reauthenticated
     }
 
+    // Load 'mechsAllowedToSendCredentials' system property value
+    private static String getMechsAllowedToSendCredentials() {
+        return AccessController.doPrivileged(
+            new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(ALLOWED_MECHS_SP);
+                }
+            }
+        );
+    }
+
+    // Get set of allowed authentication mechanism names from the property value
+    private static Set<String> getMechsFromPropertyValue(String propValue) {
+        if (propValue == null || propValue.isEmpty()) {
+            return Collections.emptySet();
+        }
+
+        Set<String> s = new HashSet<>();
+        for (String part : propValue.split("\\s*,\\s*")) {
+            if (!part.isEmpty()) {
+                s.add(part.toLowerCase(Locale.ROOT));
+            }
+        }
+        return s;
+    }
+
+    // Returns true if TLS connection opened using "ldaps" scheme, or using "ldap" and then upgraded with
+    // startTLS extended operation, and startTLS is still active.
+    private boolean isConnectionEncrypted() {
+        return hasLdapsScheme || clnt.isUpgradedToStartTls();
+    }
+
+    // Ensure connection and context are in a safe state to transmit credentials
+    private void ensureCanTransmitCredentials(String authMechanism) throws NamingException {
+
+        // "none" and "anonumous" authentication mechanisms are allowed unconditionally
+        if ("none".equalsIgnoreCase(authMechanism) || "anonymous".equalsIgnoreCase(authMechanism)) {
+            return;
+        }
+
+        // Check environment first
+        String allowedMechanismsOrTrue = (String) envprops.get(ALLOWED_MECHS_SP);
+        boolean useSpMechsCache = false;
+        boolean anyPropertyIsSet = ALLOWED_MECHS_SP_VALUE != null || allowedMechanismsOrTrue != null;
+
+        // If current connection is not encrypted, and context seen to be secured with STARTTLS
+        // or 'mechsAllowedToSendCredentials' is set to any value via system/context environment properties
+        if (!isConnectionEncrypted() && (contextSeenStartTlsEnabled || anyPropertyIsSet)) {
+            // First, check if security principal is provided in context environment for "simple"
+            // authentication mechanism. There is no check for other SASL mechanisms since the credentials
+            // can be specified via other properties
+            if ("simple".equalsIgnoreCase(authMechanism) && !envprops.containsKey(SECURITY_PRINCIPAL)) {
+                return;
+            }
+
+            // If null - will use mechanism name cached from system property
+            if (allowedMechanismsOrTrue == null) {
+                useSpMechsCache = true;
+                allowedMechanismsOrTrue = ALLOWED_MECHS_SP_VALUE;
+            }
+
+            // If the property value (system or environment) is 'all':
+            // any kind of authentication is allowed unconditionally - no check is needed
+            if ("all".equalsIgnoreCase(allowedMechanismsOrTrue)) {
+                return;
+            }
+
+            // Get the set with allowed authentication mechanisms and check current mechanism
+            Set<String> allowedAuthMechs = useSpMechsCache ?
+                    MECHS_ALLOWED_BY_SP : getMechsFromPropertyValue(allowedMechanismsOrTrue);
+            if (!allowedAuthMechs.contains(authMechanism)) {
+                throw new NamingException(UNSECURED_CRED_TRANSMIT_MSG);
+            }
+        }
+    }
+
     private void ensureOpen() throws NamingException {
         ensureOpen(false);
     }
@@ -2770,6 +2874,9 @@
                     // Required for SASL client identity
                     envprops);
 
+                // Mark current context as secure if the connection is acquired
+                // from the pool and it is secure.
+                contextSeenStartTlsEnabled |= clnt.isUpgradedToStartTls();
 
                 /**
                  * Pooled connections are preauthenticated;
@@ -2788,8 +2895,12 @@
                 ldapVersion = LdapClient.LDAP_VERSION3;
             }
 
-            LdapResult answer = clnt.authenticate(initial,
-                user, passwd, ldapVersion, authMechanism, bindCtls, envprops);
+            LdapResult answer;
+            synchronized (clnt.conn.startTlsLock) {
+                ensureCanTransmitCredentials(authMechanism);
+                answer = clnt.authenticate(initial, user, passwd, ldapVersion,
+                        authMechanism, bindCtls, envprops);
+            }
 
             respCtls = answer.resControls; // retrieve (bind) response controls
 
@@ -3293,6 +3404,7 @@
                 String domainName = (String)
                     (envprops != null ? envprops.get(DOMAIN_NAME) : null);
                 ((StartTlsResponseImpl)er).setConnection(clnt.conn, domainName);
+                contextSeenStartTlsEnabled |= startTLS;
             }
             return er;
 
--- a/src/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/classes/com/sun/jndi/ldap/ext/StartTlsResponseImpl.java	Mon Nov 02 02:26:27 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, 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
@@ -266,7 +266,7 @@
 
         // Replace SSL streams with the original streams
         ldapConnection.replaceStreams(
-                        originalInputStream, originalOutputStream);
+                originalInputStream, originalOutputStream, false);
 
         if (debug) {
             System.out.println("StartTLS: closing SSL Socket");
@@ -356,7 +356,7 @@
 
             // Replace original streams with the new SSL streams
             ldapConnection.replaceStreams(sslSocket.getInputStream(),
-                sslSocket.getOutputStream());
+                    sslSocket.getOutputStream(), true);
             if (debug) {
                 System.out.println("StartTLS: Replaced IO Streams");
             }
--- a/src/share/classes/java/io/ObjectInputStream.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/classes/java/io/ObjectInputStream.java	Mon Nov 02 02:26:27 2020 +0000
@@ -28,6 +28,7 @@
 import java.io.ObjectStreamClass.WeakClassKey;
 import java.lang.ref.ReferenceQueue;
 import java.lang.reflect.Array;
+import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
 import java.security.AccessControlContext;
@@ -50,6 +51,7 @@
 import sun.reflect.misc.ReflectUtil;
 import sun.util.logging.PlatformLogger;
 import sun.security.action.GetBooleanAction;
+import sun.security.action.GetIntegerAction;
 
 /**
  * An ObjectInputStream deserializes primitive data and objects previously
@@ -252,6 +254,15 @@
         static final boolean SET_FILTER_AFTER_READ =
                 privilegedGetProperty("jdk.serialSetFilterAfterRead");
 
+        /**
+         * Property to override the implementation limit on the number
+         * of interfaces allowed for Proxies. The property value is clamped to 0..65535.
+         * The maximum number of interfaces allowed for a proxy is limited to 65535 by
+         * {@link java.lang.reflect.Proxy#newProxyInstance(ClassLoader, Class[], InvocationHandler)}
+         */
+        static final int PROXY_INTERFACE_LIMIT = Math.max(0, Math.min(65535,
+                privilegedGetIntegerProperty("jdk.serialProxyInterfaceLimit", 65535)));
+
         private static boolean privilegedGetProperty(String theProp) {
             if (System.getSecurityManager() == null) {
                 return Boolean.getBoolean(theProp);
@@ -260,6 +271,15 @@
                         new GetBooleanAction(theProp));
             }
         }
+
+        private static int privilegedGetIntegerProperty(String theProp, int defaultValue) {
+            if (System.getSecurityManager() == null) {
+                return Integer.getInteger(theProp, defaultValue);
+            } else {
+                return AccessController.doPrivileged(
+                        new GetIntegerAction(theProp, defaultValue));
+            }
+        }
     }
 
     static {
@@ -1862,14 +1882,23 @@
 
         int numIfaces = bin.readInt();
         if (numIfaces > 65535) {
-            throw new InvalidObjectException("interface limit exceeded: "
-                    + numIfaces);
+            // Report specification limit exceeded
+            throw new InvalidObjectException("interface limit exceeded: " +
+                    numIfaces +
+                    ", limit: " + Caches.PROXY_INTERFACE_LIMIT);
         }
         String[] ifaces = new String[numIfaces];
         for (int i = 0; i < numIfaces; i++) {
             ifaces[i] = bin.readUTF();
         }
 
+        // Recheck against implementation limit and throw with interface names
+        if (numIfaces > Caches.PROXY_INTERFACE_LIMIT) {
+            throw new InvalidObjectException("interface limit exceeded: " +
+                    numIfaces +
+                    ", limit: " + Caches.PROXY_INTERFACE_LIMIT +
+                    "; " + Arrays.toString(ifaces));
+        }
         Class cl = null;
         ClassNotFoundException resolveEx = null;
         bin.setBlockDataMode(true);
@@ -1892,6 +1921,11 @@
             }
         } catch (ClassNotFoundException ex) {
             resolveEx = ex;
+        } catch (OutOfMemoryError memerr) {
+            IOException ex = new InvalidObjectException("Proxy interface limit exceeded: " +
+                    Arrays.toString(ifaces));
+            ex.initCause(memerr);
+            throw ex;
         }
 
         // Call filterCheck on the class before reading anything else
@@ -1903,6 +1937,11 @@
             totalObjectRefs++;
             depth++;
             desc.initProxy(cl, resolveEx, readClassDesc(false));
+        } catch (OutOfMemoryError memerr) {
+            IOException ex = new InvalidObjectException("Proxy interface limit exceeded: " +
+                    Arrays.toString(ifaces));
+            ex.initCause(memerr);
+            throw ex;
         } finally {
             depth--;
         }
--- a/src/share/classes/java/nio/X-Buffer.java.template	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/classes/java/nio/X-Buffer.java.template	Mon Nov 02 02:26:27 2020 +0000
@@ -411,11 +411,11 @@
     public int read(CharBuffer target) throws IOException {
         // Determine the number of bytes n that can be transferred
         int targetRemaining = target.remaining();
-        int remaining = remaining();
+        int limit = limit();
+        int remaining = limit - position();
         if (remaining == 0)
             return -1;
         int n = Math.min(remaining, targetRemaining);
-        int limit = limit();
         // Set source limit to prevent target overflow
         if (targetRemaining < remaining)
             limit(position() + n);
@@ -1130,10 +1130,15 @@
         if (!(ob instanceof $Type$Buffer))
             return false;
         $Type$Buffer that = ($Type$Buffer)ob;
-        if (this.remaining() != that.remaining())
+        int thisPos = this.position();
+        int thisLim = this.limit();
+        int thatPos = that.position();
+        int thatLim = that.limit();
+        int thisRem = thisLim - thisPos;
+        int thatRem = thatLim - thatPos;
+        if (thisRem < 0 || thisRem != thatRem)
             return false;
-        int p = this.position();
-        for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+        for (int i = thisLim - 1, j = thatLim - 1; i >= thisPos; i--, j--)
             if (!equals(this.get(i), that.get(j)))
                 return false;
         return true;
@@ -1171,13 +1176,20 @@
      *          is less than, equal to, or greater than the given buffer
      */
     public int compareTo($Type$Buffer that) {
-        int n = this.position() + Math.min(this.remaining(), that.remaining());
-        for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+        int thisPos = this.position();
+        int thisRem = this.limit() - thisPos;
+        int thatPos = that.position();
+        int thatRem = that.limit() - thatPos;
+        int length = Math.min(thisRem, thatRem);
+        if (length < 0)
+            return -1;
+        int n = thisPos + Math.min(thisRem, thatRem);
+        for (int i = thisPos, j = thatPos; i < n; i++, j++) {
             int cmp = compare(this.get(i), that.get(j));
             if (cmp != 0)
                 return cmp;
         }
-        return this.remaining() - that.remaining();
+        return thisRem - thatRem;
     }
 
     private static int compare($type$ x, $type$ y) {
--- a/src/share/classes/java/util/Calendar.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/classes/java/util/Calendar.java	Mon Nov 02 02:26:27 2020 +0000
@@ -1912,7 +1912,9 @@
                 lenient == that.lenient &&
                 firstDayOfWeek == that.firstDayOfWeek &&
                 minimalDaysInFirstWeek == that.minimalDaysInFirstWeek &&
-                zone.equals(that.zone);
+                (zone instanceof ZoneInfo ?
+                    zone.equals(that.zone) :
+                    zone.equals(that.getTimeZone()));
         } catch (Exception e) {
             // Note: GregorianCalendar.computeTime throws
             // IllegalArgumentException if the ERA value is invalid
--- a/src/share/classes/sun/security/ssl/HandshakeMessage.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/classes/sun/security/ssl/HandshakeMessage.java	Mon Nov 02 02:26:27 2020 +0000
@@ -45,6 +45,7 @@
 
 import javax.net.ssl.*;
 
+import sun.security.action.GetIntegerAction;
 import sun.security.internal.spec.TlsPrfParameterSpec;
 import sun.security.ssl.CipherSuite.*;
 import static sun.security.ssl.CipherSuite.PRF.*;
@@ -433,6 +434,10 @@
 
     private int messageLength;
 
+    // Set the max certificate chain length to 10
+    static final int maxCertificateChainLength = AccessController.doPrivileged(
+            new GetIntegerAction("jdk.tls.maxCertificateChainLength", 10)).intValue();
+
     CertificateMsg(X509Certificate[] certs) {
         chain = certs;
     }
@@ -450,6 +455,15 @@
                     cf = CertificateFactory.getInstance("X.509");
                 }
                 v.add(cf.generateCertificate(new ByteArrayInputStream(cert)));
+
+                if (v.size() > maxCertificateChainLength) {
+                    throw new SSLProtocolException(
+                            "The certificate chain length ("
+                                    + v.size()
+                                    + ") exceeds the maximum allowed length ("
+                                    + maxCertificateChainLength
+                                    + ")");
+                }
             } catch (CertificateException e) {
                 throw (SSLProtocolException)new SSLProtocolException(
                     e.getMessage()).initCause(e);
--- a/src/share/classes/sun/security/ssl/Handshaker.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/classes/sun/security/ssl/Handshaker.java	Mon Nov 02 02:26:27 2020 +0000
@@ -36,6 +36,7 @@
 import javax.net.ssl.*;
 import sun.misc.HexDumpEncoder;
 
+import sun.security.action.GetIntegerAction;
 import sun.security.internal.spec.*;
 import sun.security.internal.interfaces.TlsMasterSecret;
 
@@ -186,6 +187,10 @@
     static final boolean allowLegacyMasterSecret =
             Debug.getBooleanProperty("jdk.tls.allowLegacyMasterSecret", true);
 
+    // Set the max size limit for Handshake Message to 2^15
+    static final int maxHandshakeMessageSize = AccessController.doPrivileged(
+            new GetIntegerAction("jdk.tls.maxHandshakeMessageSize", 32768)).intValue();
+
     // Is it requested to use extended master secret extension?
     boolean requestedToUseEMS = false;
 
@@ -936,6 +941,15 @@
             messageType = (byte)input.getInt8();
             messageLen = input.getInt24();
 
+            if (messageLen > maxHandshakeMessageSize) {
+                throw new SSLProtocolException(
+                        "The size of the handshake message ("
+                        + messageLen
+                        + ") exceeds the maximum allowed size ("
+                        + maxHandshakeMessageSize
+                        + ")");
+            }
+
             if (input.available() < messageLen) {
                 input.reset();
                 return;
--- a/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Mon Nov 02 02:26:27 2020 +0000
@@ -252,10 +252,10 @@
                 int space = constraintEntry.indexOf(' ');
                 String algorithm = AlgorithmDecomposer.hashName(
                         ((space > 0 ? constraintEntry.substring(0, space) :
-                                constraintEntry).
-                                toUpperCase(Locale.ENGLISH)));
+                                constraintEntry)));
 
-                List<Constraint> constraintList = constraintsMap.get(algorithm);
+                List<Constraint> constraintList = constraintsMap.get(
+                    algorithm.toUpperCase(Locale.ENGLISH));
                 if (constraintList == null) {
                     constraintList = new ArrayList<>(1);
                 }
@@ -264,7 +264,8 @@
                 for (String alias : AlgorithmDecomposer.getAliases(algorithm)) {
                     List<Constraint> aliasList = constraintsMap.get(alias);
                     if (aliasList == null) {
-                        constraintsMap.put(alias, constraintList);
+                        constraintsMap.put(
+                            alias.toUpperCase(Locale.ENGLISH), constraintList);
                     }
                 }
                 if (space <= 0) {
@@ -354,7 +355,7 @@
 
         // Get applicable constraints based off the signature algorithm
         private List<Constraint> getConstraints(String algorithm) {
-            return constraintsMap.get(algorithm);
+            return constraintsMap.get(algorithm.toUpperCase(Locale.ENGLISH));
         }
 
         // Check if KeySizeConstraints permit the specified key
@@ -410,6 +411,7 @@
             Set<String> algorithms = new HashSet<>();
             if (algorithm != null) {
                 algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm));
+                algorithms.add(algorithm);
             }
 
             // Attempt to add the public key algorithm if cert provided
--- a/src/share/classes/sun/security/util/UntrustedCertificates.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/classes/sun/security/util/UntrustedCertificates.java	Mon Nov 02 02:26:27 2020 +0000
@@ -31,7 +31,7 @@
 import java.security.PrivilegedAction;
 import java.security.cert.X509Certificate;
 import java.security.cert.CertificateException;
-import java.util.*;
+import java.util.Properties;
 import sun.security.x509.X509CertImpl;
 
 /**
@@ -58,10 +58,6 @@
                         "lib/security/blacklisted.certs");
                 try (FileInputStream fin = new FileInputStream(f)) {
                     props.load(fin);
-                    // It's said that the fingerprint could contain colons
-                    for (Map.Entry<Object,Object> e: props.entrySet()) {
-                        e.setValue(stripColons(e.getValue()));
-                    }
                 } catch (IOException fnfe) {
                     if (debug != null) {
                         debug.println("Error parsing blacklisted.certs");
@@ -73,21 +69,6 @@
         algorithm = props.getProperty(ALGORITHM_KEY);
     }
 
-    private static String stripColons(Object input) {
-        String s = (String)input;
-        char[] letters = s.toCharArray();
-        int pos = 0;
-        for (int i = 0; i < letters.length; i++) {
-            if (letters[i] != ':') {
-                if (i != pos) {
-                    letters[pos] = letters[i];
-                }
-                pos++;
-            }
-        }
-        if (pos == letters.length) return s;
-        else return new String(letters, 0, pos);
-    }
     /**
      * Checks if a certificate is untrusted.
      *
--- a/src/share/lib/security/BlacklistedCertsConverter.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/lib/security/BlacklistedCertsConverter.java	Mon Nov 02 02:26:27 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -21,13 +21,26 @@
  * questions.
  */
 
+import java.io.IOException;
+import java.math.BigInteger;
 import java.security.MessageDigest;
+import java.security.PublicKey;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPublicKey;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import sun.security.util.DerInputStream;
+import sun.security.util.DerOutputStream;
+import sun.security.util.DerValue;
 
 /**
  * This is the tool to convert blacklisted.certs.pem to blacklisted.certs.
@@ -48,9 +61,14 @@
         Collection<? extends Certificate> certs
                 = cf.generateCertificates(System.in);
         System.out.println("Algorithm=" + mdAlg);
+        Set<String> fingerprints = new TreeSet<>();
         for (Certificate cert: certs) {
-            System.out.println(
-                    getCertificateFingerPrint(mdAlg, (X509Certificate)cert));
+            fingerprints.addAll(
+                    getCertificateFingerPrints(mdAlg, (X509Certificate)cert));
+        }
+
+        for (String s: fingerprints) {
+            System.out.println(s);
         }
     }
 
@@ -67,23 +85,90 @@
     }
 
     /**
-     * Gets the requested finger print of the certificate.
+     * Gets the requested fingerprints of the certificate.
      */
-    private static String getCertificateFingerPrint(String mdAlg,
-                                                    X509Certificate cert) {
-        String fingerPrint = "";
-        try {
-            byte[] encCertInfo = cert.getEncoded();
+    private static List<String> getCertificateFingerPrints(
+            String mdAlg, X509Certificate cert) throws Exception {
+        List<String> fingerprints = new ArrayList<>();
+        for (byte[] encoding : altEncodings(cert)) {
             MessageDigest md = MessageDigest.getInstance(mdAlg);
-            byte[] digest = md.digest(encCertInfo);
+            byte[] digest = md.digest(encoding);
             StringBuffer buf = new StringBuffer();
             for (int i = 0; i < digest.length; i++) {
                 byte2hex(digest[i], buf);
             }
-            fingerPrint = buf.toString();
-        } catch (NoSuchAlgorithmException | CertificateEncodingException e) {
-            // ignored
+            fingerprints.add(buf.toString());
+        }
+        return fingerprints;
+    }
+
+    private static List<byte[]> altEncodings(X509Certificate c)
+            throws Exception {
+        List<byte[]> result = new ArrayList<>();
+
+        DerValue d = new DerValue(c.getEncoded());
+        DerValue[] seq = new DerValue[3];
+        // tbsCertificate
+        seq[0] = d.data.getDerValue();
+        // signatureAlgorithm
+        seq[1] = d.data.getDerValue();
+        // signature
+        seq[2] = d.data.getDerValue();
+
+        List<DerValue> algIds = Arrays.asList(seq[1], altAlgId(seq[1]));
+
+        List<DerValue> sigs;
+        PublicKey p = c.getPublicKey();
+        if (p instanceof ECPublicKey) {
+            ECPublicKey ep = (ECPublicKey) p;
+            BigInteger mod = ep.getParams().getOrder();
+            sigs = Arrays.asList(seq[2], altSig(mod, seq[2]));
+        } else {
+            sigs = Arrays.asList(seq[2]);
         }
-        return fingerPrint;
+
+        for (DerValue algId : algIds) {
+            for (DerValue sig : sigs) {
+                DerOutputStream tmp = new DerOutputStream();
+                tmp.putDerValue(seq[0]);
+                tmp.putDerValue(algId);
+                tmp.putDerValue(sig);
+                DerOutputStream tmp2 = new DerOutputStream();
+                tmp2.write(DerValue.tag_Sequence, tmp);
+                result.add(tmp2.toByteArray());
+            }
+        }
+        return result;
+    }
+
+    private static DerValue altSig(BigInteger mod, DerValue sig)
+            throws IOException {
+        byte[] sigBits = sig.getBitString();
+        DerInputStream in =
+            new DerInputStream(sigBits, 0, sigBits.length, false);
+        DerValue[] values = in.getSequence(2);
+        BigInteger r = values[0].getBigInteger();
+        BigInteger s = values[1].getBigInteger();
+        BigInteger s2 = s.negate().mod(mod);
+        DerOutputStream out = new DerOutputStream();
+        out.putInteger(r);
+        out.putInteger(s2);
+        DerOutputStream tmp = new DerOutputStream();
+        tmp.putBitString(new DerValue(DerValue.tag_Sequence,
+                out.toByteArray()).toByteArray());
+        return new DerValue(tmp.toByteArray());
+    }
+
+    private static DerValue altAlgId(DerValue algId) throws IOException {
+        DerInputStream in = algId.toDerInputStream();
+        DerOutputStream bytes = new DerOutputStream();
+        bytes.putOID(in.getOID());
+        // encode parameters as NULL if not present or omit if NULL
+        if (in.available() == 0) {
+            bytes.putNull();
+        }
+        DerOutputStream tmp = new DerOutputStream();
+        tmp.write(DerValue.tag_Sequence, bytes);
+        return new DerValue(tmp.toByteArray());
     }
 }
--- a/src/share/lib/security/blacklisted.certs	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/lib/security/blacklisted.certs	Mon Nov 02 02:26:27 2020 +0000
@@ -1,20 +1,39 @@
-Algorithm=SHA-256
-76A45A496031E4DD2D7ED23E8F6FF97DBDEA980BAAC8B0BA94D7EDB551348645
-4CBBF8256BC9888A8007B2F386940A2E394378B0D903CBB3863C5A6394B889CE
-D24566BF315F4E597D6E381C87119FB4198F5E9E2607F5F4AB362EF7E2E7672F
-14E6D2764A4B06701C6CBC376A253775F79C782FBCB6C0EE6F99DE4BA1024ADD
-D3A936E1A7775A45217C8296A1F22AC5631DCDEC45594099E78EEEBBEDCBA967
-5E83124D68D24E8E177E306DF643D5EA99C5A94D6FC34B072F7544A1CABB7C7B
-9ED8F9B0E8E42A1656B8E1DD18F42BA42DC06FE52686173BA2FC70E756F207DC
-FDEDB5BDFCB67411513A61AEE5CB5B5D7C52AF06028EFC996CC1B05B1D6CEA2B
-A686FEE577C88AB664D0787ECDFFF035F4806F3DE418DC9E4D516324FFF02083
-4FEE0163686ECBD65DB968E7494F55D84B25486D438E9DE558D629D28CD4D176
-8A1BD21661C60015065212CC98B1ABB50DFD14C872A208E66BAE890F25C448AF
-B8686723E415534BC0DBD16326F9486F85B0B0799BF6639334E61DAAE67F36CD
-3946901F46B0071E90D78279E82FABABCA177231A704BE72C5B0E8918566EA66
-31C8FD37DB9B56E708B03D1F01848B068C6DA66F36FB5D82C008C6040FA3E133
-450F1B421BB05C8609854884559C323319619E8B06B001EA2DCBB74A23AA3BE2
-FC02FD48DB92D4DCE6F11679D38354CF750CFC7F584A520EB90BDE80E241F2BD
-DF21016B00FC54F9FE3BC8B039911BB216E9162FAD2FD14D990AB96E951B49BE
-F5B6F88F75D391A4B1EB336F9E201239FB6B1377DB8CFA7B84736216E5AFFFD7
-EC30C9C3065A06BB07DC5B1C6B497F370C1CA65C0F30C08E042BA6BCECC78F2C
+Algorithm=SHA-256
+03DB9E5E79FE6117177F81C11595AF598CB176AF766290DBCEB2C318B32E39A2
+08C396C006A21055D00826A5781A5CCFCE2C8D053AB3C197637A4A7A5BB9A650
+14E6D2764A4B06701C6CBC376A253775F79C782FBCB6C0EE6F99DE4BA1024ADD
+1C5E6985ACC09221DBD1A4B7BBC6D3A8C3F8540D19F20763A9537FDD42B4FFE7
+1F6BF8A3F2399AF7FD04516C2719C566CBAD51F412738F66D0457E1E6BDE6F2D
+2A464E4113141352C7962FBD1706ED4B88533EF24D7BBA6CCC5D797FD202F1C4
+31C8FD37DB9B56E708B03D1F01848B068C6DA66F36FB5D82C008C6040FA3E133
+3946901F46B0071E90D78279E82FABABCA177231A704BE72C5B0E8918566EA66
+3E11CF90719F6FB44D94EAC9A156B89BEBE7B8598F28EC58913F2BFCAF91D0C0
+423279423B9FC8CB06F1BB7C3B247522B948D5F18939F378ECC901126DE40BFB
+450F1B421BB05C8609854884559C323319619E8B06B001EA2DCBB74A23AA3BE2
+4CBBF8256BC9888A8007B2F386940A2E394378B0D903CBB3863C5A6394B889CE
+4FEE0163686ECBD65DB968E7494F55D84B25486D438E9DE558D629D28CD4D176
+535D04DFCE027C70BD5F8A9E0AD4F218E9AFDCF5BBCF9B6DE0D81E148E2E3172
+568FAF38D9F155F624838E2181B1CEB4D8459305EE652B0F810C97C3611BFE19
+585CFE6B7436CBD4E732763A2137D7F49599BA9B1790E688FCEC799C58EB84A6
+5E83124D68D24E8E177E306DF643D5EA99C5A94D6FC34B072F7544A1CABB7C7B
+71CB00749B9130FB2707A2664BFF958D0FCC8E161D9674C7450BA0FC2BEAF9D3
+76A45A496031E4DD2D7ED23E8F6FF97DBDEA980BAAC8B0BA94D7EDB551348645
+8A1BD21661C60015065212CC98B1ABB50DFD14C872A208E66BAE890F25C448AF
+9ED8F9B0E8E42A1656B8E1DD18F42BA42DC06FE52686173BA2FC70E756F207DC
+9FADCE80D62A959F9930D748488C1E22E821F4E1E4A43584B848C2FC11E04D77
+A686FEE577C88AB664D0787ECDFFF035F4806F3DE418DC9E4D516324FFF02083
+A90132CEA1D4F7185E4F688EFFD16F6AC14DFD78356A807599A5DABBEEF3333E
+B8686723E415534BC0DBD16326F9486F85B0B0799BF6639334E61DAAE67F36CD
+C0D1F42B9F4BF7ACC045B7BB5D4805E10737F67B6310CE505248D543D0D5FE07
+D0156949F1381943442C6974E9B5B49EF441BB799EF20477B90A89C3F33620CE
+D151962D954970501C60079258EBCFA38502E0A9F03CD640322B08C0A3117FE5
+D24566BF315F4E597D6E381C87119FB4198F5E9E2607F5F4AB362EF7E2E7672F
+D3A936E1A7775A45217C8296A1F22AC5631DCDEC45594099E78EEEBBEDCBA967
+D6CEAE5D9E047FAF7D797858D229AC991AD44316D1E2A37A21926D763153593A
+DF21016B00FC54F9FE3BC8B039911BB216E9162FAD2FD14D990AB96E951B49BE
+E0E740E4B0F8B3548181FF75B5372FAF4C70B99EC995D694ED0FB91B03FF8D21
+EC30C9C3065A06BB07DC5B1C6B497F370C1CA65C0F30C08E042BA6BCECC78F2C
+F5B6F88F75D391A4B1EB336F9E201239FB6B1377DB8CFA7B84736216E5AFFFD7
+FBB12938ABD86C125796EDF4162D291028890A7D6C0C1CCA75FD4B95EBFA7A1A
+FC02FD48DB92D4DCE6F11679D38354CF750CFC7F584A520EB90BDE80E241F2BD
+FDEDB5BDFCB67411513A61AEE5CB5B5D7C52AF06028EFC996CC1B05B1D6CEA2B
--- a/src/share/native/sun/awt/image/jpeg/jpeg-6b/jmemnobs.c	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/share/native/sun/awt/image/jpeg/jpeg-6b/jmemnobs.c	Mon Nov 02 02:26:27 2020 +0000
@@ -70,13 +70,16 @@
 
 /*
  * This routine computes the total memory space available for allocation.
- * Here we always say, "we got all you want bud!"
  */
 
 GLOBAL(size_t)
 jpeg_mem_available (j_common_ptr cinfo, size_t min_bytes_needed,
                     size_t max_bytes_needed, size_t already_allocated)
 {
+  if (cinfo->mem->max_memory_to_use)
+    return cinfo->mem->max_memory_to_use - already_allocated;
+
+  /* Here we say, "we got all you want bud!" */
   return max_bytes_needed;
 }
 
--- a/src/solaris/classes/sun/nio/fs/UnixUriUtils.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/solaris/classes/sun/nio/fs/UnixUriUtils.java	Mon Nov 02 02:26:27 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -83,7 +83,8 @@
                 if (b == 0)
                     throw new IllegalArgumentException("Nul character not allowed");
             } else {
-                assert c < 0x80;
+                if (c == 0 || c >= 0x80)
+                    throw new IllegalArgumentException("Bad escape");
                 b = (byte)c;
             }
             result[rlen++] = b;
@@ -115,9 +116,10 @@
         // trailing slash if directory
         if (sb.charAt(sb.length()-1) != '/') {
             try {
+                 up.checkRead();
                  if (UnixFileAttributes.get(up, true).isDirectory())
                      sb.append('/');
-            } catch (UnixException x) {
+            } catch (SecurityException | UnixException x) {
                 // ignore
             }
         }
--- a/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/windows/classes/sun/nio/fs/RegistryFileTypeDetector.java	Mon Nov 02 02:26:27 2020 +0000
@@ -57,10 +57,15 @@
 
         // query HKEY_CLASSES_ROOT\<ext>
         String key = filename.substring(dot);
-        NativeBuffer keyBuffer = WindowsNativeDispatcher.asNativeBuffer(key);
-        NativeBuffer nameBuffer = WindowsNativeDispatcher.asNativeBuffer("Content Type");
+        NativeBuffer keyBuffer = null;
+        NativeBuffer nameBuffer = null;
         try {
+            keyBuffer = WindowsNativeDispatcher.asNativeBuffer(key);
+            nameBuffer = WindowsNativeDispatcher.asNativeBuffer("Content Type");
             return queryStringValue(keyBuffer.address(), nameBuffer.address());
+        } catch (WindowsException we) {
+            we.rethrowAsIOException(file.toString());
+            return null; // keep compiler happy
         } finally {
             nameBuffer.release();
             keyBuffer.release();
--- a/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java	Mon Nov 02 02:26:27 2020 +0000
@@ -1093,7 +1093,12 @@
 
     private static final Unsafe unsafe = Unsafe.getUnsafe();
 
-    static NativeBuffer asNativeBuffer(String s) {
+    static NativeBuffer asNativeBuffer(String s) throws WindowsException {
+        if (s.length() > (Integer.MAX_VALUE - 2)/2) {
+            throw new WindowsException
+                ("String too long to convert to native buffer");
+        }
+
         int stringLengthInBytes = s.length() << 1;
         int sizeInBytes = stringLengthInBytes + 2;  // char terminator
 
--- a/src/windows/classes/sun/nio/fs/WindowsUriSupport.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/src/windows/classes/sun/nio/fs/WindowsUriSupport.java	Mon Nov 02 02:26:27 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -104,8 +104,9 @@
         boolean addSlash = false;
         if (!s.endsWith("\\")) {
             try {
+                 path.checkRead();
                  addSlash = WindowsFileAttributes.get(path, true).isDirectory();
-            } catch (WindowsException x) {
+            } catch (SecurityException | WindowsException x) {
             }
         }
 
--- a/test/lib/security/CheckBlacklistedCerts.java	Sat Sep 26 19:05:32 2020 +0100
+++ b/test/lib/security/CheckBlacklistedCerts.java	Mon Nov 02 02:26:27 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8011402
+ * @bug 8011402 8237995
  * @summary Move blacklisting certificate logic from hard code to data
  */
 
@@ -115,7 +115,8 @@
                 System.out.println("There are " + acount + " algorithms");
                 failed = true;
             }
-            if (ccount != blacklisted.size()
+            // There are two unique fingerprints for each RSA certificate
+            if (ccount != blacklisted.size() * 2
                     && !blacklisted.isEmpty()) {
                 System.out.println("Wrong blacklisted.certs size: "
                         + ccount + " fingerprints, "