changeset 47426:7d5509425e4a

Merge
author henryjen
date Fri, 20 Oct 2017 09:49:02 -0700
parents fb677b3f0888 96179f26139e
children 251676148c62
files src/java.base/share/classes/com/sun/crypto/provider/PBECipherCore.java src/java.base/share/classes/jdk/internal/misc/ObjectStreamClassValidator.java
diffstat 108 files changed, 2493 insertions(+), 1429 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/interpreter/linkResolver.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/hotspot/share/interpreter/linkResolver.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -1074,11 +1074,7 @@
                                         const LinkInfo& link_info,
                                         TRAPS) {
   methodHandle resolved_method = linktime_resolve_special_method(link_info, CHECK);
-  runtime_resolve_special_method(result, resolved_method,
-                                 link_info.resolved_klass(),
-                                 link_info.current_klass(),
-                                 recv,
-                                 link_info.check_access(), CHECK);
+  runtime_resolve_special_method(result, link_info, resolved_method, recv, CHECK);
 }
 
 // throws linktime exceptions
@@ -1162,11 +1158,11 @@
 
 // throws runtime exceptions
 void LinkResolver::runtime_resolve_special_method(CallInfo& result,
+                                                  const LinkInfo& link_info,
                                                   const methodHandle& resolved_method,
-                                                  Klass* resolved_klass,
-                                                  Klass* current_klass,
-                                                  Handle recv,
-                                                  bool check_access, TRAPS) {
+                                                  Handle recv, TRAPS) {
+
+  Klass* resolved_klass = link_info.resolved_klass();
 
   // resolved method is selected method unless we have an old-style lookup
   // for a superclass method
@@ -1174,12 +1170,13 @@
   // no checks for shadowing
   methodHandle sel_method(THREAD, resolved_method());
 
-  if (check_access &&
+  if (link_info.check_access() &&
       // check if the method is not <init>
       resolved_method->name() != vmSymbols::object_initializer_name()) {
 
-  // check if this is an old-style super call and do a new lookup if so
+     // check if this is an old-style super call and do a new lookup if so
         // a) check if ACC_SUPER flag is set for the current class
+    Klass* current_klass = link_info.current_klass();
     if ((current_klass->is_super() || !AllowNonVirtualCalls) &&
         // b) check if the class of the resolved_klass is a superclass
         // (not supertype in order to exclude interface classes) of the current class.
@@ -1199,6 +1196,9 @@
                   Method::name_and_sig_as_C_string(resolved_klass,
                                             resolved_method->name(),
                                             resolved_method->signature()));
+      // check loader constraints if found a different method
+      } else if (sel_method() != resolved_method()) {
+        check_method_loader_constraints(link_info, sel_method, "method", CHECK);
       }
     }
 
--- a/src/hotspot/share/interpreter/linkResolver.hpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/hotspot/share/interpreter/linkResolver.hpp	Fri Oct 20 09:49:02 2017 -0700
@@ -233,11 +233,10 @@
   static methodHandle linktime_resolve_interface_method (const LinkInfo& link_info, TRAPS);
 
   static void runtime_resolve_special_method    (CallInfo& result,
+                                                 const LinkInfo& link_info,
                                                  const methodHandle& resolved_method,
-                                                 Klass* resolved_klass,
-                                                 Klass* current_klass,
-                                                 Handle recv,
-                                                 bool check_access, TRAPS);
+                                                 Handle recv, TRAPS);
+
   static void runtime_resolve_virtual_method    (CallInfo& result,
                                                  const methodHandle& resolved_method,
                                                  Klass* resolved_klass,
--- a/src/java.base/share/classes/com/sun/crypto/provider/AESCipher.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/AESCipher.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -156,7 +156,7 @@
                 throw new InvalidKeyException("Key encoding must not be null");
             } else if (value.length != fixedKeySize) {
                 throw new InvalidKeyException("The key must be " +
-                    fixedKeySize*8 + " bits");
+                    fixedKeySize + " bytes");
             }
         }
     }
@@ -509,7 +509,7 @@
             throw new InvalidKeyException("Invalid AES key length: " +
                                           encoded.length + " bytes");
         }
-        return encoded.length * 8;
+        return Math.multiplyExact(encoded.length, 8);
     }
 
     /**
@@ -628,9 +628,9 @@
         }
         if (src != null) {
             int aadLen = src.limit() - src.position();
-            if (aadLen != 0) {
+            if (aadLen > 0) {
                 if (src.hasArray()) {
-                    int aadOfs = src.arrayOffset() + src.position();
+                    int aadOfs = Math.addExact(src.arrayOffset(), src.position());
                     core.updateAAD(src.array(), aadOfs, aadLen);
                     src.position(src.limit());
                 } else {
--- a/src/java.base/share/classes/com/sun/crypto/provider/AESWrapCipher.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/AESWrapCipher.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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
@@ -156,7 +156,7 @@
         if (decrypting) {
             result = inputLen - 8;
         } else {
-            result = inputLen + 8;
+            result = Math.addExact(inputLen, 8);
         }
         return (result < 0? 0:result);
     }
@@ -378,7 +378,7 @@
             throw new InvalidKeyException("Invalid key length: " +
                                           encoded.length + " bytes");
         }
-        return encoded.length * 8;
+        return Math.multiplyExact(encoded.length, 8);
     }
 
     /**
@@ -404,7 +404,7 @@
             throw new InvalidKeyException("Cannot get an encoding of " +
                                           "the key to be wrapped");
         }
-        byte[] out = new byte[keyVal.length + 8];
+        byte[] out = new byte[Math.addExact(keyVal.length, 8)];
 
         if (keyVal.length == 8) {
             System.arraycopy(IV, 0, out, 0, IV.length);
--- a/src/java.base/share/classes/com/sun/crypto/provider/ARCFOURCipher.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/ARCFOURCipher.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -257,7 +257,7 @@
     // see JCE spec
     protected int engineGetKeySize(Key key) throws InvalidKeyException {
         byte[] encodedKey = getEncodedKey(key);
-        return encodedKey.length << 3;
+        return Math.multiplyExact(encodedKey.length, 8);
     }
 
 }
--- a/src/java.base/share/classes/com/sun/crypto/provider/BlowfishCipher.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/BlowfishCipher.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -373,7 +373,7 @@
      * @exception InvalidKeyException if <code>key</code> is invalid.
      */
     protected int engineGetKeySize(Key key) throws InvalidKeyException {
-        return (key.getEncoded().length * 8);
+        return Math.multiplyExact(key.getEncoded().length, 8);
     }
 
     /**
--- a/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -324,13 +324,14 @@
     }
 
     private int getOutputSizeByOperation(int inputLen, boolean isDoFinal) {
-        int totalLen = buffered + inputLen + cipher.getBufferedLength();
+        int totalLen = Math.addExact(buffered, cipher.getBufferedLength());
+        totalLen = Math.addExact(totalLen, inputLen);
         switch (cipherMode) {
         case GCM_MODE:
             if (isDoFinal) {
                 int tagLen = ((GaloisCounterMode) cipher).getTagLen();
                 if (!decrypting) {
-                    totalLen += tagLen;
+                    totalLen = Math.addExact(totalLen, tagLen);
                 } else {
                     totalLen -= tagLen;
                 }
@@ -346,10 +347,10 @@
                         totalLen = diffBlocksize;
                     } else {
                         int residue = (totalLen - diffBlocksize) % blockSize;
-                        totalLen += (blockSize - residue);
+                        totalLen = Math.addExact(totalLen, (blockSize - residue));
                     }
                 } else {
-                    totalLen += padding.padLength(totalLen);
+                    totalLen = Math.addExact(totalLen, padding.padLength(totalLen));
                 }
             }
             break;
@@ -711,7 +712,8 @@
         }
 
         // figure out how much can be sent to crypto function
-        int len = buffered + inputLen - minBytes;
+        int len = Math.addExact(buffered, inputLen);
+        len -= minBytes;
         if (padding != null && decrypting) {
             // do not include the padding bytes when decrypting
             len -= blockSize;
@@ -730,12 +732,12 @@
         int outLen = 0;
         if (len != 0) { // there is some work to do
             if ((input == output)
-                 && (outputOffset < (inputOffset + inputLen))
-                 && (inputOffset < (outputOffset + buffer.length))) {
+                 && (outputOffset - inputOffset < inputLen)
+                 && (inputOffset - outputOffset < buffer.length)) {
                 // copy 'input' out to avoid its content being
                 // overwritten prematurely.
                 input = Arrays.copyOfRange(input, inputOffset,
-                    inputOffset + inputLen);
+                    Math.addExact(inputOffset, inputLen));
                 inputOffset = 0;
             }
             if (len <= buffered) {
@@ -757,13 +759,13 @@
                     if (bufferCapacity != 0) {
                         temp = Math.min(bufferCapacity, inputConsumed);
                         if (unitBytes != blockSize) {
-                            temp -= ((buffered + temp) % unitBytes);
+                            temp -= (Math.addExact(buffered, temp) % unitBytes);
                         }
                         System.arraycopy(input, inputOffset, buffer, buffered, temp);
-                        inputOffset += temp;
+                        inputOffset = Math.addExact(inputOffset, temp);
                         inputConsumed -= temp;
                         inputLen -= temp;
-                        buffered += temp;
+                        buffered = Math.addExact(buffered, temp);
                     }
                     // process 'buffer'
                     if (decrypting) {
@@ -771,7 +773,7 @@
                     } else {
                          outLen = cipher.encrypt(buffer, 0, buffered, output, outputOffset);
                     }
-                    outputOffset += outLen;
+                    outputOffset = Math.addExact(outputOffset, outLen);
                     buffered = 0;
                 }
                 if (inputConsumed > 0) { // still has input to process
@@ -802,7 +804,7 @@
         if (inputLen > 0) {
             System.arraycopy(input, inputOffset, buffer, buffered,
                              inputLen);
-            buffered += inputLen;
+            buffered = Math.addExact(buffered, inputLen);
         }
         return outLen;
     }
@@ -912,10 +914,10 @@
         }
 
         // calculate total input length
-        int len = buffered + inputLen;
+        int len = Math.addExact(buffered, inputLen);
 
         // calculate padding length
-        int totalLen = len + cipher.getBufferedLength();
+        int totalLen = Math.addExact(len, cipher.getBufferedLength());
         int paddingLen = 0;
         // will the total input length be a multiple of blockSize?
         if (unitBytes != blockSize) {
@@ -948,12 +950,12 @@
         int finalBufLen = inputLen;
         if ((buffered != 0) || (!decrypting && padding != null) ||
             ((input == output)
-              && (outputOffset < (inputOffset + inputLen))
-              && (inputOffset < (outputOffset + buffer.length)))) {
+              && (outputOffset - inputOffset < inputLen)
+              && (inputOffset - outputOffset < buffer.length))) {
             if (decrypting || padding == null) {
                 paddingLen = 0;
             }
-            finalBuf = new byte[len + paddingLen];
+            finalBuf = new byte[Math.addExact(len, paddingLen)];
             finalOffset = 0;
             if (buffered != 0) {
                 System.arraycopy(buffer, 0, finalBuf, 0, buffered);
@@ -963,7 +965,7 @@
                                  buffered, inputLen);
             }
             if (paddingLen != 0) {
-                padding.padWithLen(finalBuf, (buffered+inputLen), paddingLen);
+                padding.padWithLen(finalBuf, Math.addExact(buffered, inputLen), paddingLen);
             }
             finalBufLen = finalBuf.length;
         }
--- a/src/java.base/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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
@@ -140,7 +140,7 @@
         if (decrypting) {
             result = inputLen - 16; // CHECKSUM_LEN + IV_LEN;
         } else {
-            result = inputLen + 16;
+            result = Math.addExact(inputLen, 16);
         }
         return (result < 0? 0:result);
     }
@@ -449,11 +449,11 @@
         }
 
         byte[] cks = getChecksum(keyVal);
-        byte[] in = new byte[keyVal.length + CHECKSUM_LEN];
+        byte[] in = new byte[Math.addExact(keyVal.length, CHECKSUM_LEN)];
         System.arraycopy(keyVal, 0, in, 0, keyVal.length);
         System.arraycopy(cks, 0, in, keyVal.length, CHECKSUM_LEN);
 
-        byte[] out = new byte[iv.length + in.length];
+        byte[] out = new byte[Math.addExact(iv.length, in.length)];
         System.arraycopy(iv, 0, out, 0, iv.length);
 
         cipher.encrypt(in, 0, in.length, out, iv.length);
--- a/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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.crypto.spec.DHGenParameterSpec;
 
 import sun.security.provider.ParameterCache;
+import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
 
 /**
  * This class represents the key pair generator for Diffie-Hellman key pairs.
@@ -42,8 +43,7 @@
  * <ul>
  * <li>By providing the size in bits of the prime modulus -
  * This will be used to create a prime modulus and base generator, which will
- * then be used to create the Diffie-Hellman key pair. The default size of the
- * prime modulus is 2048 bits.
+ * then be used to create the Diffie-Hellman key pair.
  * <li>By providing a prime modulus and base generator
  * </ul>
  *
@@ -68,7 +68,7 @@
 
     public DHKeyPairGenerator() {
         super();
-        initialize(2048, null);
+        initialize(DEF_DH_KEY_SIZE, null);
     }
 
     private static void checkKeySize(int keysize)
--- a/src/java.base/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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,6 +31,8 @@
 import javax.crypto.spec.DHParameterSpec;
 import javax.crypto.spec.DHGenParameterSpec;
 
+import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE;
+
 /*
  * This class generates parameters for the Diffie-Hellman algorithm.
  * The parameters are a prime, a base, and optionally the length in bits of
@@ -38,7 +40,6 @@
  *
  * <p>The Diffie-Hellman parameter generation accepts the size in bits of the
  * prime modulus and the size in bits of the random exponent as input.
- * The size of the prime modulus defaults to 2048 bits.
  *
  * @author Jan Luehe
  *
@@ -50,7 +51,7 @@
 public final class DHParameterGenerator extends AlgorithmParameterGeneratorSpi {
 
     // The size in bits of the prime modulus
-    private int primeSize = 2048;
+    private int primeSize = DEF_DH_KEY_SIZE;
 
     // The size in bits of the random exponent (private value)
     private int exponentSize = 0;
--- a/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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,7 +63,8 @@
         if (in == null)
             return;
 
-        if ((off + len) > in.length) {
+        int idx = Math.addExact(off, len);
+        if (idx > in.length) {
             throw new ShortBufferException("Buffer too small to hold padding");
         }
 
@@ -71,7 +72,7 @@
         byte[] padding = new byte[len - 1];
         SunJCE.getRandom().nextBytes(padding);
         System.arraycopy(padding, 0, in, off, len - 1);
-        in[off + len - 1] = paddingOctet;
+        in[idx - 1] = paddingOctet;
         return;
     }
 
@@ -94,14 +95,15 @@
             return 0;
         }
 
-        byte lastByte = in[off + len - 1];
+        int idx = Math.addExact(off, len);
+        byte lastByte = in[idx - 1];
         int padValue = (int)lastByte & 0x0ff;
         if ((padValue < 0x01)
             || (padValue > blockSize)) {
             return -1;
         }
 
-        int start = off + len - padValue;
+        int start = idx - padValue;
         if (start < off) {
             return -1;
         }
--- a/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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,12 +27,14 @@
 
 import java.io.*;
 import java.util.*;
+import java.security.AccessController;
 import java.security.DigestInputStream;
 import java.security.DigestOutputStream;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.Key;
 import java.security.PrivateKey;
+import java.security.PrivilegedAction;
 import java.security.KeyStoreSpi;
 import java.security.KeyStoreException;
 import java.security.UnrecoverableKeyException;
@@ -835,11 +837,21 @@
                         // read the sealed key
                         try {
                             ois = new ObjectInputStream(dis);
+                            final ObjectInputStream ois2 = ois;
+                            // Set a deserialization checker
+                            AccessController.doPrivileged(
+                                (PrivilegedAction<Void>)() -> {
+                                    ois2.setObjectInputFilter(
+                                        new DeserializationChecker());
+                                    return null;
+                            });
                             entry.sealedKey = (SealedObject)ois.readObject();
                             // NOTE: don't close ois here since we are still
                             // using dis!!!
                         } catch (ClassNotFoundException cnfe) {
                             throw new IOException(cnfe.getMessage());
+                        } catch (InvalidClassException ice) {
+                            throw new IOException("Invalid secret key format");
                         }
 
                         // Add the entry to the list
@@ -916,4 +928,34 @@
 
         return JCEKS_MAGIC == dataStream.readInt();
     }
+
+    /*
+     * An ObjectInputFilter that checks the format of the secret key being
+     * deserialized.
+     */
+    private static class DeserializationChecker implements ObjectInputFilter {
+        private static final int MAX_NESTED_DEPTH = 2;
+
+        @Override
+        public ObjectInputFilter.Status
+            checkInput(ObjectInputFilter.FilterInfo info) {
+
+            // First run a custom filter
+            long nestedDepth = info.depth();
+            if ((nestedDepth == 1 &&
+                info.serialClass() != SealedObjectForKeyProtector.class) ||
+                nestedDepth > MAX_NESTED_DEPTH) {
+                return Status.REJECTED;
+            }
+
+            // Next run the default filter, if available
+            ObjectInputFilter defaultFilter =
+                ObjectInputFilter.Config.getSerialFilter();
+            if (defaultFilter != null) {
+                return defaultFilter.checkInput(info);
+            }
+
+            return Status.UNDECIDED;
+        }
+    }
 }
--- a/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -38,6 +38,7 @@
 import java.security.NoSuchProviderException;
 import java.security.UnrecoverableKeyException;
 import java.security.AlgorithmParameters;
+import java.security.spec.InvalidParameterSpecException;
 import java.security.spec.PKCS8EncodedKeySpec;
 
 import javax.crypto.Cipher;
@@ -74,6 +75,8 @@
     // keys in the keystore implementation that comes with JDK 1.2)
     private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1";
 
+    private static final int MAX_ITERATION_COUNT = 5000000;
+    private static final int ITERATION_COUNT = 200000;
     private static final int SALT_LEN = 20; // the salt length
     private static final int DIGEST_LEN = 20;
 
@@ -100,7 +103,7 @@
         SunJCE.getRandom().nextBytes(salt);
 
         // create PBE parameters from salt and iteration count
-        PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
+        PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, ITERATION_COUNT);
 
         // create PBE key from password
         PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
@@ -155,6 +158,9 @@
                 pbeParams.init(encodedParams);
                 PBEParameterSpec pbeSpec =
                         pbeParams.getParameterSpec(PBEParameterSpec.class);
+                if (pbeSpec.getIterationCount() > MAX_ITERATION_COUNT) {
+                    throw new IOException("PBE iteration count too large");
+                }
 
                 // create PBE key from password
                 PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
@@ -285,7 +291,7 @@
         SunJCE.getRandom().nextBytes(salt);
 
         // create PBE parameters from salt and iteration count
-        PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
+        PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, ITERATION_COUNT);
 
         // create PBE key from password
         PBEKeySpec pbeKeySpec = new PBEKeySpec(this.password);
@@ -326,6 +332,15 @@
                 throw new UnrecoverableKeyException("Cannot get " +
                                                     "algorithm parameters");
             }
+            PBEParameterSpec pbeSpec;
+            try {
+                pbeSpec = params.getParameterSpec(PBEParameterSpec.class);
+            } catch (InvalidParameterSpecException ipse) {
+                throw new IOException("Invalid PBE algorithm parameters");
+            }
+            if (pbeSpec.getIterationCount() > MAX_ITERATION_COUNT) {
+                throw new IOException("PBE iteration count too large");
+            }
             PBEWithMD5AndTripleDESCipher cipherSpi;
             cipherSpi = new PBEWithMD5AndTripleDESCipher();
             Cipher cipher = new CipherForKeyProtector(cipherSpi,
--- a/src/java.base/share/classes/com/sun/crypto/provider/PBECipherCore.java	Fri Oct 20 17:16:05 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,535 +0,0 @@
-/*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.crypto.provider;
-
-import java.security.*;
-import java.security.spec.*;
-import javax.crypto.*;
-import javax.crypto.spec.*;
-
-/**
- * This class represents password-based encryption as defined by the PKCS #5
- * standard.
- *
- * @author Jan Luehe
- *
- *
- * @see javax.crypto.Cipher
- */
-final class PBECipherCore {
-
-    // the encapsulated DES cipher
-    private CipherCore cipher;
-    private MessageDigest md;
-    private int blkSize;
-    private String algo = null;
-    private byte[] salt = null;
-    private int iCount = 10;
-
-    /**
-     * Creates an instance of PBE Cipher using the specified CipherSpi
-     * instance.
-     *
-     */
-    PBECipherCore(String cipherAlg) throws NoSuchAlgorithmException,
-        NoSuchPaddingException {
-        algo = cipherAlg;
-        if (algo.equals("DES")) {
-            cipher = new CipherCore(new DESCrypt(),
-                                    DESConstants.DES_BLOCK_SIZE);
-        } else if (algo.equals("DESede")) {
-
-            cipher = new CipherCore(new DESedeCrypt(),
-                                    DESConstants.DES_BLOCK_SIZE);
-        } else {
-            throw new NoSuchAlgorithmException("No Cipher implementation " +
-                                               "for PBEWithMD5And" + algo);
-        }
-        cipher.setMode("CBC");
-        cipher.setPadding("PKCS5Padding");
-        // get instance of MD5
-        md = MessageDigest.getInstance("MD5");
-    }
-
-    /**
-     * Sets the mode of this cipher. This algorithm can only be run in CBC
-     * mode.
-     *
-     * @param mode the cipher mode
-     *
-     * @exception NoSuchAlgorithmException if the requested cipher mode is
-     * invalid
-     */
-    void setMode(String mode) throws NoSuchAlgorithmException {
-        cipher.setMode(mode);
-    }
-
-     /**
-     * Sets the padding mechanism of this cipher. This algorithm only uses
-     * PKCS #5 padding.
-     *
-     * @param padding the padding mechanism
-     *
-     * @exception NoSuchPaddingException if the requested padding mechanism
-     * is invalid
-     */
-    void setPadding(String paddingScheme) throws NoSuchPaddingException {
-        cipher.setPadding(paddingScheme);
-    }
-
-    /**
-     * Returns the block size (in bytes).
-     *
-     * @return the block size (in bytes)
-     */
-    int getBlockSize() {
-        return DESConstants.DES_BLOCK_SIZE;
-    }
-
-    /**
-     * Returns the length in bytes that an output buffer would need to be in
-     * order to hold the result of the next <code>update</code> or
-     * <code>doFinal</code> operation, given the input length
-     * <code>inputLen</code> (in bytes).
-     *
-     * <p>This call takes into account any unprocessed (buffered) data from a
-     * previous <code>update</code> call, and padding.
-     *
-     * <p>The actual output length of the next <code>update</code> or
-     * <code>doFinal</code> call may be smaller than the length returned by
-     * this method.
-     *
-     * @param inputLen the input length (in bytes)
-     *
-     * @return the required output buffer size (in bytes)
-     *
-     */
-    int getOutputSize(int inputLen) {
-        return cipher.getOutputSize(inputLen);
-    }
-
-    /**
-     * Returns the initialization vector (IV) in a new buffer.
-     *
-     * <p> This is useful in the case where a random IV has been created
-     * (see <a href = "#init">init</a>),
-     * or in the context of password-based encryption or
-     * decryption, where the IV is derived from a user-supplied password.
-     *
-     * @return the initialization vector in a new buffer, or null if the
-     * underlying algorithm does not use an IV, or if the IV has not yet
-     * been set.
-     */
-    byte[] getIV() {
-        return cipher.getIV();
-    }
-
-    /**
-     * Returns the parameters used with this cipher.
-     *
-     * <p>The returned parameters may be the same that were used to initialize
-     * this cipher, or may contain the default set of parameters or a set of
-     * randomly generated parameters used by the underlying cipher
-     * implementation (provided that the underlying cipher implementation
-     * uses a default set of parameters or creates new parameters if it needs
-     * parameters but was not initialized with any).
-     *
-     * @return the parameters used with this cipher, or null if this cipher
-     * does not use any parameters.
-     */
-    AlgorithmParameters getParameters() {
-        AlgorithmParameters params = null;
-        if (salt == null) {
-            salt = new byte[8];
-            SunJCE.getRandom().nextBytes(salt);
-        }
-        PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
-        try {
-            params = AlgorithmParameters.getInstance("PBEWithMD5And" +
-                (algo.equalsIgnoreCase("DES")? "DES":"TripleDES"),
-                    SunJCE.getInstance());
-            params.init(pbeSpec);
-        } catch (NoSuchAlgorithmException nsae) {
-            // should never happen
-            throw new RuntimeException("SunJCE called, but not configured");
-        } catch (InvalidParameterSpecException ipse) {
-            // should never happen
-            throw new RuntimeException("PBEParameterSpec not supported");
-        }
-        return params;
-    }
-
-    /**
-     * Initializes this cipher with a key, a set of
-     * algorithm parameters, and a source of randomness.
-     * The cipher is initialized for one of the following four operations:
-     * encryption, decryption, key wrapping or key unwrapping, depending on
-     * the value of <code>opmode</code>.
-     *
-     * <p>If this cipher (including its underlying feedback or padding scheme)
-     * requires any random bytes, it will get them from <code>random</code>.
-     *
-     * @param opmode the operation mode of this cipher (this is one of
-     * the following:
-     * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>),
-     * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
-     * @param key the encryption key
-     * @param params the algorithm parameters
-     * @param random the source of randomness
-     *
-     * @exception InvalidKeyException if the given key is inappropriate for
-     * initializing this cipher
-     * @exception InvalidAlgorithmParameterException if the given algorithm
-     * parameters are inappropriate for this cipher
-     */
-    void init(int opmode, Key key, AlgorithmParameterSpec params,
-              SecureRandom random)
-        throws InvalidKeyException, InvalidAlgorithmParameterException {
-        if (((opmode == Cipher.DECRYPT_MODE) ||
-             (opmode == Cipher.UNWRAP_MODE)) && (params == null)) {
-            throw new InvalidAlgorithmParameterException("Parameters "
-                                                         + "missing");
-        }
-        if ((key == null) ||
-            (key.getEncoded() == null) ||
-            !(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3))) {
-            throw new InvalidKeyException("Missing password");
-        }
-
-        if (params == null) {
-            // create random salt and use default iteration count
-            salt = new byte[8];
-            random.nextBytes(salt);
-        } else {
-            if (!(params instanceof PBEParameterSpec)) {
-                throw new InvalidAlgorithmParameterException
-                    ("Wrong parameter type: PBE expected");
-            }
-            salt = ((PBEParameterSpec) params).getSalt();
-            // salt must be 8 bytes long (by definition)
-            if (salt.length != 8) {
-                throw new InvalidAlgorithmParameterException
-                    ("Salt must be 8 bytes long");
-            }
-            iCount = ((PBEParameterSpec) params).getIterationCount();
-            if (iCount <= 0) {
-                throw new InvalidAlgorithmParameterException
-                    ("IterationCount must be a positive number");
-            }
-        }
-
-        byte[] derivedKey = deriveCipherKey(key);
-        // use all but the last 8 bytes as the key value
-        SecretKeySpec cipherKey = new SecretKeySpec(derivedKey, 0,
-                                                    derivedKey.length-8, algo);
-        // use the last 8 bytes as the IV
-        IvParameterSpec ivSpec = new IvParameterSpec(derivedKey,
-                                                     derivedKey.length-8,
-                                                     8);
-        // initialize the underlying cipher
-        cipher.init(opmode, cipherKey, ivSpec, random);
-    }
-
-    private byte[] deriveCipherKey(Key key) {
-
-        byte[] result = null;
-        byte[] passwdBytes = key.getEncoded();
-
-        if (algo.equals("DES")) {
-            // P || S (password concatenated with salt)
-            byte[] concat = new byte[passwdBytes.length + salt.length];
-            System.arraycopy(passwdBytes, 0, concat, 0, passwdBytes.length);
-            java.util.Arrays.fill(passwdBytes, (byte)0x00);
-            System.arraycopy(salt, 0, concat, passwdBytes.length, salt.length);
-
-            // digest P || S with c iterations
-            byte[] toBeHashed = concat;
-            for (int i = 0; i < iCount; i++) {
-                md.update(toBeHashed);
-                toBeHashed = md.digest(); // this resets the digest
-            }
-            java.util.Arrays.fill(concat, (byte)0x00);
-            result = toBeHashed;
-        } else if (algo.equals("DESede")) {
-            // if the 2 salt halves are the same, invert one of them
-            int i;
-            for (i=0; i<4; i++) {
-                if (salt[i] != salt[i+4])
-                    break;
-            }
-            if (i==4) { // same, invert 1st half
-                for (i=0; i<2; i++) {
-                    byte tmp = salt[i];
-                    salt[i] = salt[3-i];
-                    salt[3-1] = tmp;
-                }
-            }
-
-            // Now digest each half (concatenated with password). For each
-            // half, go through the loop as many times as specified by the
-            // iteration count parameter (inner for loop).
-            // Concatenate the output from each digest round with the
-            // password, and use the result as the input to the next digest
-            // operation.
-            byte[] kBytes = null;
-            IvParameterSpec iv = null;
-            byte[] toBeHashed = null;
-            result = new byte[DESedeKeySpec.DES_EDE_KEY_LEN +
-                              DESConstants.DES_BLOCK_SIZE];
-            for (i = 0; i < 2; i++) {
-                toBeHashed = new byte[salt.length/2];
-                System.arraycopy(salt, i*(salt.length/2), toBeHashed, 0,
-                                 toBeHashed.length);
-                for (int j=0; j < iCount; j++) {
-                    md.update(toBeHashed);
-                    md.update(passwdBytes);
-                    toBeHashed = md.digest(); // this resets the digest
-                }
-                System.arraycopy(toBeHashed, 0, result, i*16,
-                                 toBeHashed.length);
-            }
-        }
-        return result;
-    }
-
-    void init(int opmode, Key key, AlgorithmParameters params,
-              SecureRandom random)
-        throws InvalidKeyException, InvalidAlgorithmParameterException {
-        PBEParameterSpec pbeSpec = null;
-        if (params != null) {
-            try {
-                pbeSpec = params.getParameterSpec(PBEParameterSpec.class);
-            } catch (InvalidParameterSpecException ipse) {
-                throw new InvalidAlgorithmParameterException("Wrong parameter "
-                                                             + "type: PBE "
-                                                             + "expected");
-            }
-        }
-        init(opmode, key, pbeSpec, random);
-    }
-
-    /**
-     * Continues a multiple-part encryption or decryption operation
-     * (depending on how this cipher was initialized), processing another data
-     * part.
-     *
-     * <p>The first <code>inputLen</code> bytes in the <code>input</code>
-     * buffer, starting at <code>inputOffset</code>, are processed, and the
-     * result is stored in a new buffer.
-     *
-     * @param input the input buffer
-     * @param inputOffset the offset in <code>input</code> where the input
-     * starts
-     * @param inputLen the input length
-     *
-     * @return the new buffer with the result
-     *
-     */
-    byte[] update(byte[] input, int inputOffset, int inputLen) {
-        return cipher.update(input, inputOffset, inputLen);
-    }
-
-    /**
-     * Continues a multiple-part encryption or decryption operation
-     * (depending on how this cipher was initialized), processing another data
-     * part.
-     *
-     * <p>The first <code>inputLen</code> bytes in the <code>input</code>
-     * buffer, starting at <code>inputOffset</code>, are processed, and the
-     * result is stored in the <code>output</code> buffer, starting at
-     * <code>outputOffset</code>.
-     *
-     * @param input the input buffer
-     * @param inputOffset the offset in <code>input</code> where the input
-     * starts
-     * @param inputLen the input length
-     * @param output the buffer for the result
-     * @param outputOffset the offset in <code>output</code> where the result
-     * is stored
-     *
-     * @return the number of bytes stored in <code>output</code>
-     *
-     * @exception ShortBufferException if the given output buffer is too small
-     * to hold the result
-     */
-    int update(byte[] input, int inputOffset, int inputLen,
-               byte[] output, int outputOffset)
-        throws ShortBufferException {
-        return cipher.update(input, inputOffset, inputLen,
-                             output, outputOffset);
-    }
-
-    /**
-     * Encrypts or decrypts data in a single-part operation,
-     * or finishes a multiple-part operation.
-     * The data is encrypted or decrypted, depending on how this cipher was
-     * initialized.
-     *
-     * <p>The first <code>inputLen</code> bytes in the <code>input</code>
-     * buffer, starting at <code>inputOffset</code>, and any input bytes that
-     * may have been buffered during a previous <code>update</code> operation,
-     * are processed, with padding (if requested) being applied.
-     * The result is stored in a new buffer.
-     *
-     * <p>The cipher is reset to its initial state (uninitialized) after this
-     * call.
-     *
-     * @param input the input buffer
-     * @param inputOffset the offset in <code>input</code> where the input
-     * starts
-     * @param inputLen the input length
-     *
-     * @return the new buffer with the result
-     *
-     * @exception IllegalBlockSizeException if this cipher is a block cipher,
-     * no padding has been requested (only in encryption mode), and the total
-     * input length of the data processed by this cipher is not a multiple of
-     * block size
-     * @exception BadPaddingException if decrypting and padding is chosen,
-     * but the last input data does not have proper padding bytes.
-     */
-    byte[] doFinal(byte[] input, int inputOffset, int inputLen)
-        throws IllegalBlockSizeException, BadPaddingException {
-        return cipher.doFinal(input, inputOffset, inputLen);
-    }
-
-    /**
-     * Encrypts or decrypts data in a single-part operation,
-     * or finishes a multiple-part operation.
-     * The data is encrypted or decrypted, depending on how this cipher was
-     * initialized.
-     *
-     * <p>The first <code>inputLen</code> bytes in the <code>input</code>
-     * buffer, starting at <code>inputOffset</code>, and any input bytes that
-     * may have been buffered during a previous <code>update</code> operation,
-     * are processed, with padding (if requested) being applied.
-     * The result is stored in the <code>output</code> buffer, starting at
-     * <code>outputOffset</code>.
-     *
-     * <p>The cipher is reset to its initial state (uninitialized) after this
-     * call.
-     *
-     * @param input the input buffer
-     * @param inputOffset the offset in <code>input</code> where the input
-     * starts
-     * @param inputLen the input length
-     * @param output the buffer for the result
-     * @param outputOffset the offset in <code>output</code> where the result
-     * is stored
-     *
-     * @return the number of bytes stored in <code>output</code>
-     *
-     * @exception IllegalBlockSizeException if this cipher is a block cipher,
-     * no padding has been requested (only in encryption mode), and the total
-     * input length of the data processed by this cipher is not a multiple of
-     * block size
-     * @exception ShortBufferException if the given output buffer is too small
-     * to hold the result
-     * @exception BadPaddingException if decrypting and padding is chosen,
-     * but the last input data does not have proper padding bytes.
-     */
-    int doFinal(byte[] input, int inputOffset, int inputLen,
-                byte[] output, int outputOffset)
-        throws ShortBufferException, IllegalBlockSizeException,
-               BadPaddingException {
-        return cipher.doFinal(input, inputOffset, inputLen,
-                                    output, outputOffset);
-    }
-
-    /**
-     * Wrap a key.
-     *
-     * @param key the key to be wrapped.
-     *
-     * @return the wrapped key.
-     *
-     * @exception IllegalBlockSizeException if this cipher is a block
-     * cipher, no padding has been requested, and the length of the
-     * encoding of the key to be wrapped is not a
-     * multiple of the block size.
-     *
-     * @exception InvalidKeyException if it is impossible or unsafe to
-     * wrap the key with this cipher (e.g., a hardware protected key is
-     * being passed to a software only cipher).
-     */
-    byte[] wrap(Key key)
-        throws IllegalBlockSizeException, InvalidKeyException {
-        byte[] result = null;
-
-        try {
-            byte[] encodedKey = key.getEncoded();
-            if ((encodedKey == null) || (encodedKey.length == 0)) {
-                throw new InvalidKeyException("Cannot get an encoding of " +
-                                              "the key to be wrapped");
-            }
-
-            result = doFinal(encodedKey, 0, encodedKey.length);
-        } catch (BadPaddingException e) {
-            // Should never happen
-        }
-
-        return result;
-    }
-
-    /**
-     * Unwrap a previously wrapped key.
-     *
-     * @param wrappedKey the key to be unwrapped.
-     *
-     * @param wrappedKeyAlgorithm the algorithm the wrapped key is for.
-     *
-     * @param wrappedKeyType the type of the wrapped key.
-     * This is one of <code>Cipher.SECRET_KEY</code>,
-     * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.
-     *
-     * @return the unwrapped key.
-     *
-     * @exception NoSuchAlgorithmException if no installed providers
-     * can create keys of type <code>wrappedKeyType</code> for the
-     * <code>wrappedKeyAlgorithm</code>.
-     *
-     * @exception InvalidKeyException if <code>wrappedKey</code> does not
-     * represent a wrapped key of type <code>wrappedKeyType</code> for
-     * the <code>wrappedKeyAlgorithm</code>.
-     */
-    Key unwrap(byte[] wrappedKey,
-               String wrappedKeyAlgorithm,
-               int wrappedKeyType)
-        throws InvalidKeyException, NoSuchAlgorithmException {
-        byte[] encodedKey;
-        try {
-            encodedKey = doFinal(wrappedKey, 0, wrappedKey.length);
-        } catch (BadPaddingException ePadding) {
-            throw new InvalidKeyException("The wrapped key is not padded " +
-                                          "correctly");
-        } catch (IllegalBlockSizeException eBlockSize) {
-            throw new InvalidKeyException("The wrapped key does not have " +
-                                          "the correct length");
-        }
-        return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
-                                          wrappedKeyType);
-    }
-}
--- a/src/java.base/share/classes/com/sun/crypto/provider/PBES1Core.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/PBES1Core.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -260,7 +260,7 @@
 
         if (algo.equals("DES")) {
             // P || S (password concatenated with salt)
-            byte[] concat = new byte[passwdBytes.length + salt.length];
+            byte[] concat = new byte[Math.addExact(passwdBytes.length, salt.length)];
             System.arraycopy(passwdBytes, 0, concat, 0, passwdBytes.length);
             java.util.Arrays.fill(passwdBytes, (byte)0x00);
             System.arraycopy(salt, 0, concat, passwdBytes.length, salt.length);
@@ -284,7 +284,7 @@
                 for (i=0; i<2; i++) {
                     byte tmp = salt[i];
                     salt[i] = salt[3-i];
-                    salt[3-1] = tmp;
+                    salt[3-i] = tmp;
                 }
             }
 
--- a/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -26,6 +26,7 @@
 package com.sun.crypto.provider;
 
 import javax.crypto.ShortBufferException;
+import java.util.Arrays;
 
 /**
  * This class implements padding as specified in the PKCS#5 standard.
@@ -63,14 +64,13 @@
         if (in == null)
             return;
 
-        if ((off + len) > in.length) {
+        int idx = Math.addExact(off, len);
+        if (idx > in.length) {
             throw new ShortBufferException("Buffer too small to hold padding");
         }
 
         byte paddingOctet = (byte) (len & 0xff);
-        for (int i = 0; i < len; i++) {
-            in[i + off] = paddingOctet;
-        }
+        Arrays.fill(in, off, idx, paddingOctet);
         return;
     }
 
@@ -92,25 +92,24 @@
             (len == 0)) { // this can happen if input is really a padded buffer
             return 0;
         }
-
-        byte lastByte = in[off + len - 1];
+        int idx = Math.addExact(off, len);
+        byte lastByte = in[idx - 1];
         int padValue = (int)lastByte & 0x0ff;
         if ((padValue < 0x01)
             || (padValue > blockSize)) {
             return -1;
         }
 
-        int start = off + len - ((int)lastByte & 0x0ff);
+        int start = idx - padValue;
         if (start < off) {
             return -1;
         }
 
-        for (int i = 0; i < ((int)lastByte & 0x0ff); i++) {
-            if (in[start+i] != lastByte) {
+        for (int i = start; i < idx; i++) {
+            if (in[i] != lastByte) {
                 return -1;
             }
         }
-
         return start;
     }
 
--- a/src/java.base/share/classes/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnectionOldImpl.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnectionOldImpl.java	Fri Oct 20 09:49:02 2017 -0700
@@ -38,6 +38,7 @@
 import java.net.URL;
 import java.net.Proxy;
 import java.net.ProtocolException;
+import java.net.MalformedURLException;
 import java.io.*;
 import java.net.Authenticator;
 import javax.net.ssl.*;
@@ -78,10 +79,18 @@
         this(u, null, handler);
     }
 
+    static URL checkURL(URL u) throws IOException {
+        if (u != null) {
+            if (u.toExternalForm().indexOf('\n') > -1) {
+                throw new MalformedURLException("Illegal character in URL");
+            }
+        }
+        return u;
+    }
 // For both copies of the file, uncomment one line and comment the other
 //    HttpsURLConnectionImpl(URL u, Handler handler) throws IOException {
     HttpsURLConnectionOldImpl(URL u, Proxy p, Handler handler) throws IOException {
-        super(u);
+        super(checkURL(u));
         delegate = new DelegateHttpsURLConnection(url, p, handler, this);
     }
 
--- a/src/java.base/share/classes/java/io/ObjectInputStream.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/io/ObjectInputStream.java	Fri Oct 20 09:49:02 2017 -0700
@@ -44,7 +44,6 @@
 
 import static java.io.ObjectStreamClass.processQueue;
 
-import jdk.internal.misc.ObjectStreamClassValidator;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.Unsafe;
 import sun.reflect.misc.ReflectUtil;
@@ -1283,6 +1282,33 @@
     }
 
     /**
+     * Checks the given array type and length to ensure that creation of such
+     * an array is permitted by this ObjectInputStream. The arrayType argument
+     * must represent an actual array type.
+     *
+     * This private method is called via SharedSecrets.
+     *
+     * @param arrayType the array type
+     * @param arrayLength the array length
+     * @throws NullPointerException if arrayType is null
+     * @throws IllegalArgumentException if arrayType isn't actually an array type
+     * @throws NegativeArraySizeException if arrayLength is negative
+     * @throws InvalidClassException if the filter rejects creation
+     */
+    private void checkArray(Class<?> arrayType, int arrayLength) throws InvalidClassException {
+        Objects.requireNonNull(arrayType);
+        if (! arrayType.isArray()) {
+            throw new IllegalArgumentException("not an array type");
+        }
+
+        if (arrayLength < 0) {
+            throw new NegativeArraySizeException();
+        }
+
+        filterCheck(arrayType, arrayLength);
+    }
+
+    /**
      * Provide access to the persistent fields read from the input stream.
      */
     public abstract static class GetField {
@@ -1740,9 +1766,6 @@
                 throw new StreamCorruptedException(
                     String.format("invalid type code: %02X", tc));
         }
-        if (descriptor != null) {
-            validateDescriptor(descriptor);
-        }
         return descriptor;
     }
 
@@ -1770,6 +1793,10 @@
         passHandle = NULL_HANDLE;
 
         int numIfaces = bin.readInt();
+        if (numIfaces > 65535) {
+            throw new InvalidObjectException("interface limit exceeded: "
+                    + numIfaces);
+        }
         String[] ifaces = new String[numIfaces];
         for (int i = 0; i < numIfaces; i++) {
             ifaces[i] = bin.readUTF();
@@ -3978,20 +4005,8 @@
         }
     }
 
-    private void validateDescriptor(ObjectStreamClass descriptor) {
-        ObjectStreamClassValidator validating = validator;
-        if (validating != null) {
-            validating.validateDescriptor(descriptor);
-        }
+    static {
+        SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::checkArray);
     }
 
-    // controlled access to ObjectStreamClassValidator
-    private volatile ObjectStreamClassValidator validator;
-
-    private static void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator) {
-        ois.validator = validator;
-    }
-    static {
-        SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
-    }
 }
--- a/src/java.base/share/classes/java/io/ObjectStreamClass.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/io/ObjectStreamClass.java	Fri Oct 20 09:49:02 2017 -0700
@@ -32,14 +32,19 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
+import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.security.PermissionCollection;
+import java.security.Permissions;
 import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -53,7 +58,8 @@
 import jdk.internal.reflect.Reflection;
 import jdk.internal.reflect.ReflectionFactory;
 import sun.reflect.misc.ReflectUtil;
-
+import jdk.internal.misc.SharedSecrets;
+import jdk.internal.misc.JavaSecurityAccess;
 import static java.io.ObjectStreamField.*;
 
 /**
@@ -176,6 +182,9 @@
 
     /** serialization-appropriate constructor, or null if none */
     private Constructor<?> cons;
+    /** protection domains that need to be checked when calling the constructor */
+    private ProtectionDomain[] domains;
+
     /** class-defined writeObject method, or null if none */
     private Method writeObjectMethod;
     /** class-defined readObject method, or null if none */
@@ -508,6 +517,7 @@
                             cl, "readObjectNoData", null, Void.TYPE);
                         hasWriteObjectData = (writeObjectMethod != null);
                     }
+                    domains = getProtectionDomains(cons, cl);
                     writeReplaceMethod = getInheritableMethod(
                         cl, "writeReplace", null, Object.class);
                     readResolveMethod = getInheritableMethod(
@@ -551,6 +561,65 @@
     }
 
     /**
+     * Creates a PermissionDomain that grants no permission.
+     */
+    private ProtectionDomain noPermissionsDomain() {
+        PermissionCollection perms = new Permissions();
+        perms.setReadOnly();
+        return new ProtectionDomain(null, perms);
+    }
+
+    /**
+     * Aggregate the ProtectionDomains of all the classes that separate
+     * a concrete class {@code cl} from its ancestor's class declaring
+     * a constructor {@code cons}.
+     *
+     * If {@code cl} is defined by the boot loader, or the constructor
+     * {@code cons} is declared by {@code cl}, or if there is no security
+     * manager, then this method does nothing and {@code null} is returned.
+     *
+     * @param cons A constructor declared by {@code cl} or one of its
+     *             ancestors.
+     * @param cl A concrete class, which is either the class declaring
+     *           the constructor {@code cons}, or a serializable subclass
+     *           of that class.
+     * @return An array of ProtectionDomain representing the set of
+     *         ProtectionDomain that separate the concrete class {@code cl}
+     *         from its ancestor's declaring {@code cons}, or {@code null}.
+     */
+    private ProtectionDomain[] getProtectionDomains(Constructor<?> cons,
+                                                    Class<?> cl) {
+        ProtectionDomain[] domains = null;
+        if (cons != null && cl.getClassLoader() != null
+                && System.getSecurityManager() != null) {
+            Class<?> cls = cl;
+            Class<?> fnscl = cons.getDeclaringClass();
+            Set<ProtectionDomain> pds = null;
+            while (cls != fnscl) {
+                ProtectionDomain pd = cls.getProtectionDomain();
+                if (pd != null) {
+                    if (pds == null) pds = new HashSet<>();
+                    pds.add(pd);
+                }
+                cls = cls.getSuperclass();
+                if (cls == null) {
+                    // that's not supposed to happen
+                    // make a ProtectionDomain with no permission.
+                    // should we throw instead?
+                    if (pds == null) pds = new HashSet<>();
+                    else pds.clear();
+                    pds.add(noPermissionsDomain());
+                    break;
+                }
+            }
+            if (pds != null) {
+                domains = pds.toArray(new ProtectionDomain[0]);
+            }
+        }
+        return domains;
+    }
+
+    /**
      * Initializes class descriptor representing a proxy class.
      */
     void initProxy(Class<?> cl,
@@ -580,6 +649,7 @@
             writeReplaceMethod = localDesc.writeReplaceMethod;
             readResolveMethod = localDesc.readResolveMethod;
             deserializeEx = localDesc.deserializeEx;
+            domains = localDesc.domains;
             cons = localDesc.cons;
         }
         fieldRefl = getReflector(fields, localDesc);
@@ -666,6 +736,7 @@
             if (deserializeEx == null) {
                 deserializeEx = localDesc.deserializeEx;
             }
+            domains = localDesc.domains;
             cons = localDesc.cons;
         }
 
@@ -1006,7 +1077,35 @@
         requireInitialized();
         if (cons != null) {
             try {
-                return cons.newInstance();
+                if (domains == null || domains.length == 0) {
+                    return cons.newInstance();
+                } else {
+                    JavaSecurityAccess jsa = SharedSecrets.getJavaSecurityAccess();
+                    PrivilegedAction<?> pea = () -> {
+                        try {
+                            return cons.newInstance();
+                        } catch (InstantiationException
+                                 | InvocationTargetException
+                                 | IllegalAccessException x) {
+                            throw new UndeclaredThrowableException(x);
+                        }
+                    }; // Can't use PrivilegedExceptionAction with jsa
+                    try {
+                        return jsa.doIntersectionPrivilege(pea,
+                                   AccessController.getContext(),
+                                   new AccessControlContext(domains));
+                    } catch (UndeclaredThrowableException x) {
+                        Throwable cause = x.getCause();
+                        if (cause instanceof InstantiationException)
+                            throw (InstantiationException) cause;
+                        if (cause instanceof InvocationTargetException)
+                            throw (InvocationTargetException) cause;
+                        if (cause instanceof IllegalAccessException)
+                            throw (IllegalAccessException) cause;
+                        // not supposed to happen
+                        throw x;
+                    }
+                }
             } catch (IllegalAccessException ex) {
                 // should not occur, as access checks have been suppressed
                 throw new InternalError(ex);
--- a/src/java.base/share/classes/java/security/CodeSource.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/security/CodeSource.java	Fri Oct 20 09:49:02 2017 -0700
@@ -35,6 +35,7 @@
 import java.io.IOException;
 import java.security.cert.*;
 import sun.net.util.URLUtil;
+import sun.security.util.IOUtils;
 
 /**
  *
@@ -571,6 +572,8 @@
             // could all be present in the stream at the same time
             cfs = new Hashtable<>(3);
             certList = new ArrayList<>(size > 20 ? 20 : size);
+        } else if (size < 0) {
+            throw new IOException("size cannot be negative");
         }
 
         for (int i = 0; i < size; i++) {
@@ -592,13 +595,7 @@
                 cfs.put(certType, cf);
             }
             // parse the certificate
-            byte[] encoded = null;
-            try {
-                encoded = new byte[ois.readInt()];
-            } catch (OutOfMemoryError oome) {
-                throw new IOException("Certificate too big");
-            }
-            ois.readFully(encoded);
+            byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
             ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
             try {
                 certList.add(cf.generateCertificate(bais));
--- a/src/java.base/share/classes/java/security/UnresolvedPermission.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/security/UnresolvedPermission.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -25,12 +25,16 @@
 
 package java.security;
 
+import sun.security.util.IOUtils;
+
 import java.io.IOException;
 import java.io.ByteArrayInputStream;
+import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.lang.reflect.*;
 import java.security.cert.*;
+import java.util.List;
 
 /**
  * The UnresolvedPermission class is used to hold Permissions that
@@ -550,6 +554,7 @@
     {
         CertificateFactory cf;
         Hashtable<String, CertificateFactory> cfs = null;
+        List<Certificate> certList = null;
 
         ois.defaultReadObject();
 
@@ -562,7 +567,9 @@
             // we know of 3 different cert types: X.509, PGP, SDSI, which
             // could all be present in the stream at the same time
             cfs = new Hashtable<>(3);
-            this.certs = new java.security.cert.Certificate[size];
+            certList = new ArrayList<>(size > 20 ? 20 : size);
+        } else if (size < 0) {
+            throw new IOException("size cannot be negative");
         }
 
         for (int i=0; i<size; i++) {
@@ -584,20 +591,18 @@
                 cfs.put(certType, cf);
             }
             // parse the certificate
-            byte[] encoded=null;
-            try {
-                encoded = new byte[ois.readInt()];
-            } catch (OutOfMemoryError oome) {
-                throw new IOException("Certificate too big");
-            }
-            ois.readFully(encoded);
+            byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
             ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
             try {
-                this.certs[i] = cf.generateCertificate(bais);
+                certList.add(cf.generateCertificate(bais));
             } catch (CertificateException ce) {
                 throw new IOException(ce.getMessage());
             }
             bais.close();
         }
+        if (certList != null) {
+            this.certs = certList.toArray(
+                    new java.security.cert.Certificate[size]);
+        }
     }
 }
--- a/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2017, 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
@@ -34,6 +34,7 @@
 import java.util.Map;
 import javax.security.auth.x500.X500Principal;
 
+import sun.security.util.IOUtils;
 import sun.security.util.ObjectIdentifier;
 import sun.security.x509.InvalidityDateExtension;
 
@@ -230,17 +231,17 @@
         int size = ois.readInt();
         if (size == 0) {
             extensions = Collections.emptyMap();
+        } else if (size < 0) {
+            throw new IOException("size cannot be negative");
         } else {
-            extensions = new HashMap<>(size);
+            extensions = new HashMap<>(size > 20 ? 20 : size);
         }
 
         // Read in the extensions and put the mappings in the extensions map
         for (int i = 0; i < size; i++) {
             String oid = (String) ois.readObject();
             boolean critical = ois.readBoolean();
-            int length = ois.readInt();
-            byte[] extVal = new byte[length];
-            ois.readFully(extVal);
+            byte[] extVal = IOUtils.readNBytes(ois, ois.readInt());
             Extension ext = sun.security.x509.Extension.newExtension
                 (new ObjectIdentifier(oid), critical, extVal);
             extensions.put(oid, ext);
--- a/src/java.base/share/classes/java/util/ArrayDeque.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/util/ArrayDeque.java	Fri Oct 20 09:49:02 2017 -0700
@@ -38,6 +38,7 @@
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
+import jdk.internal.misc.SharedSecrets;
 
 /**
  * Resizable-array implementation of the {@link Deque} interface.  Array
@@ -1194,6 +1195,7 @@
 
         // Read in size and allocate array
         int size = s.readInt();
+        SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size + 1);
         elements = new Object[size + 1];
         this.tail = size;
 
--- a/src/java.base/share/classes/java/util/ArrayList.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/util/ArrayList.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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,6 +28,7 @@
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
+import jdk.internal.misc.SharedSecrets;
 
 /**
  * Resizable-array implementation of the {@code List} interface.  Implements
@@ -814,6 +815,7 @@
 
         if (size > 0) {
             // like clone(), allocate array based upon size not capacity
+            SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
             Object[] elements = new Object[size];
 
             // Read in all elements in the proper order.
--- a/src/java.base/share/classes/java/util/HashMap.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/util/HashMap.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -34,6 +34,7 @@
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
+import jdk.internal.misc.SharedSecrets;
 
 /**
  * Hash table based implementation of the {@code Map} interface.  This
@@ -1448,6 +1449,10 @@
             float ft = (float)cap * lf;
             threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
                          (int)ft : Integer.MAX_VALUE);
+
+            // Check Map.Entry[].class since it's the nearest public type to
+            // what we're actually creating.
+            SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, cap);
             @SuppressWarnings({"rawtypes","unchecked"})
             Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
             table = tab;
--- a/src/java.base/share/classes/java/util/HashSet.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/util/HashSet.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -26,6 +26,7 @@
 package java.util;
 
 import java.io.InvalidObjectException;
+import jdk.internal.misc.SharedSecrets;
 
 /**
  * This class implements the {@code Set} interface, backed by a hash table
@@ -322,6 +323,13 @@
         capacity = (int) Math.min(size * Math.min(1 / loadFactor, 4.0f),
                 HashMap.MAXIMUM_CAPACITY);
 
+        // Constructing the backing map will lazily create an array when the first element is
+        // added, so check it before construction. Call HashMap.tableSizeFor to compute the
+        // actual allocation size. Check Map.Entry[].class since it's the nearest public type to
+        // what is actually created.
+        SharedSecrets.getJavaObjectInputStreamAccess()
+                     .checkArray(s, Map.Entry[].class, HashMap.tableSizeFor(capacity));
+
         // Create backing HashMap
         map = (((HashSet<?>)this) instanceof LinkedHashSet ?
                new LinkedHashMap<>(capacity, loadFactor) :
--- a/src/java.base/share/classes/java/util/Hashtable.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/util/Hashtable.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2017, 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
@@ -29,6 +29,7 @@
 import java.util.function.BiConsumer;
 import java.util.function.Function;
 import java.util.function.BiFunction;
+import jdk.internal.misc.SharedSecrets;
 
 /**
  * This class implements a hash table, which maps keys to values. Any
@@ -1291,6 +1292,10 @@
         if (length > elements && (length & 1) == 0)
             length--;
         length = Math.min(length, origlength);
+
+        // Check Map.Entry[].class since it's the nearest public type to
+        // what we're actually creating.
+        SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, length);
         table = new Entry<?,?>[length];
         threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
         count = 0;
--- a/src/java.base/share/classes/java/util/IdentityHashMap.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/util/IdentityHashMap.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -29,6 +29,7 @@
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
+import jdk.internal.misc.SharedSecrets;
 
 /**
  * This class implements the {@code Map} interface with a hash table, using
@@ -1304,7 +1305,9 @@
         if (size < 0)
             throw new java.io.StreamCorruptedException
                 ("Illegal mappings count: " + size);
-        init(capacity(size));
+        int cap = capacity(size);
+        SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, cap);
+        init(cap);
 
         // Read the keys and values, and put the mappings in the table
         for (int i=0; i<size; i++) {
--- a/src/java.base/share/classes/java/util/ImmutableCollections.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/util/ImmutableCollections.java	Fri Oct 20 09:49:02 2017 -0700
@@ -35,6 +35,7 @@
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
+import jdk.internal.misc.SharedSecrets;
 import jdk.internal.vm.annotation.Stable;
 
 /**
@@ -885,6 +886,7 @@
             throw new InvalidObjectException("negative length " + len);
         }
 
+        SharedSecrets.getJavaObjectInputStreamAccess().checkArray(ois, Object[].class, len);
         Object[] a = new Object[len];
         for (int i = 0; i < len; i++) {
             a[i] = ois.readObject();
--- a/src/java.base/share/classes/java/util/PriorityQueue.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/util/PriorityQueue.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -26,6 +26,7 @@
 package java.util;
 
 import java.util.function.Consumer;
+import jdk.internal.misc.SharedSecrets;
 
 /**
  * An unbounded priority {@linkplain Queue queue} based on a priority heap.
@@ -795,6 +796,7 @@
         // Read in (and discard) array length
         s.readInt();
 
+        SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
         queue = new Object[size];
 
         // Read in all elements.
--- a/src/java.base/share/classes/java/util/Properties.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/util/Properties.java	Fri Oct 20 09:49:02 2017 -0700
@@ -42,6 +42,7 @@
 import java.util.function.BiFunction;
 import java.util.function.Function;
 
+import jdk.internal.misc.SharedSecrets;
 import jdk.internal.util.xml.PropertiesDefaultHandler;
 
 /**
@@ -1441,6 +1442,16 @@
             throw new StreamCorruptedException("Illegal # of Elements: " + elements);
         }
 
+        // Constructing the backing map will lazily create an array when the first element is
+        // added, so check it before construction. Note that CHM's constructor takes a size
+        // that is the number of elements to be stored -- not the table size -- so it must be
+        // inflated by the default load factor of 0.75, then inflated to the next power of two.
+        // (CHM uses the same power-of-two computation as HashMap, and HashMap.tableSizeFor is
+        // accessible here.) Check Map.Entry[].class since it's the nearest public type to
+        // what is actually created.
+        SharedSecrets.getJavaObjectInputStreamAccess()
+                     .checkArray(s, Map.Entry[].class, HashMap.tableSizeFor((int)(elements / 0.75)));
+
         // create CHM of appropriate capacity
         map = new ConcurrentHashMap<>(elements);
 
--- a/src/java.base/share/classes/java/util/SimpleTimeZone.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/util/SimpleTimeZone.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -41,6 +41,7 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.IOException;
+import java.io.InvalidObjectException;
 import sun.util.calendar.CalendarSystem;
 import sun.util.calendar.CalendarUtils;
 import sun.util.calendar.BaseCalendar;
@@ -1278,6 +1279,9 @@
      */
     private int serialVersionOnStream = currentSerialVersion;
 
+    // Maximum number of rules.
+    private static final int MAX_RULE_NUM = 6;
+
     private synchronized void invalidateCache() {
         cacheYear = startYear - 1;
         cacheStart = cacheEnd = 0;
@@ -1569,7 +1573,7 @@
      */
     private byte[] packRules()
     {
-        byte[] rules = new byte[6];
+        byte[] rules = new byte[MAX_RULE_NUM];
         rules[0] = (byte)startDay;
         rules[1] = (byte)startDayOfWeek;
         rules[2] = (byte)endDay;
@@ -1594,7 +1598,7 @@
         endDayOfWeek   = rules[3];
 
         // As of serial version 2, include time modes
-        if (rules.length >= 6) {
+        if (rules.length >= MAX_RULE_NUM) {
             startTimeMode = rules[4];
             endTimeMode   = rules[5];
         }
@@ -1691,9 +1695,13 @@
             // store the actual rules (which have not be made compatible with 1.1)
             // in the optional area.  Read them in here and parse them.
             int length = stream.readInt();
-            byte[] rules = new byte[length];
-            stream.readFully(rules);
-            unpackRules(rules);
+            if (length <= MAX_RULE_NUM) {
+                byte[] rules = new byte[length];
+                stream.readFully(rules);
+                unpackRules(rules);
+            } else {
+                throw new InvalidObjectException("Too many rules: " + length);
+            }
         }
 
         if (serialVersionOnStream >= 2) {
--- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Fri Oct 20 09:49:02 2017 -0700
@@ -51,6 +51,7 @@
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
+import jdk.internal.misc.SharedSecrets;
 
 /**
  * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
@@ -933,6 +934,7 @@
 
         // Read in array length and allocate array
         int len = s.readInt();
+        SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, len);
         Object[] elements = new Object[len];
 
         // Read in all elements in the proper order.
--- a/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputStreamAccess.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/jdk/internal/misc/JavaObjectInputStreamAccess.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -25,17 +25,14 @@
 
 package jdk.internal.misc;
 
+import java.io.InvalidClassException;
 import java.io.ObjectInputStream;
 
 /**
- * The interface to specify methods for accessing {@code ObjectInputStream}
- * @author sjiang
+ * Interface to specify methods for accessing {@code ObjectInputStream}.
  */
+@FunctionalInterface
 public interface JavaObjectInputStreamAccess {
-    /**
-     * Sets a descriptor validating.
-     * @param ois stream to have the descriptors validated
-     * @param validator validator used to validate a descriptor.
-     */
-    public void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator);
+    void checkArray(ObjectInputStream ois, Class<?> arrayType, int arrayLength)
+        throws InvalidClassException;
 }
--- a/src/java.base/share/classes/jdk/internal/misc/ObjectStreamClassValidator.java	Fri Oct 20 17:16:05 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 jdk.internal.misc;
-
-import java.io.ObjectStreamClass;
-
-/**
- * A callback used by {@code ObjectInputStream} to do descriptor validation.
- *
- * @author sjiang
- */
-public interface ObjectStreamClassValidator {
-    /**
-     * This method will be called by ObjectInputStream to
-     * check a descriptor just before creating an object described by this descriptor.
-     * The object will not be created if this method throws a {@code RuntimeException}.
-     * @param descriptor descriptor to be checked.
-     */
-    public void validateDescriptor(ObjectStreamClass descriptor);
-}
--- a/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java	Fri Oct 20 09:49:02 2017 -0700
@@ -115,8 +115,8 @@
                 new PrivilegedAction<Object>() {
 
                     public Object run() {
-                        vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue();
-                        vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue();
+                        vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 300_000).intValue();
+                        vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 300_000).intValue();
                         encs[0] = System.getProperty("file.encoding", "ISO8859_1");
                         return null;
                     }
--- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Fri Oct 20 09:49:02 2017 -0700
@@ -843,18 +843,36 @@
         this(u, null, handler);
     }
 
-    public HttpURLConnection(URL u, String host, int port) {
-        this(u, new Proxy(Proxy.Type.HTTP, InetSocketAddress.createUnresolved(host, port)));
+    private static String checkHost(String h) throws IOException {
+        if (h != null) {
+            if (h.indexOf('\n') > -1) {
+                throw new MalformedURLException("Illegal character in host");
+            }
+        }
+        return h;
+    }
+    public HttpURLConnection(URL u, String host, int port) throws IOException {
+        this(u, new Proxy(Proxy.Type.HTTP,
+                InetSocketAddress.createUnresolved(checkHost(host), port)));
     }
 
     /** this constructor is used by other protocol handlers such as ftp
         that want to use http to fetch urls on their behalf.*/
-    public HttpURLConnection(URL u, Proxy p) {
+    public HttpURLConnection(URL u, Proxy p) throws IOException {
         this(u, p, new Handler());
     }
 
-    protected HttpURLConnection(URL u, Proxy p, Handler handler) {
-        super(u);
+    private static URL checkURL(URL u) throws IOException {
+        if (u != null) {
+            if (u.toExternalForm().indexOf('\n') > -1) {
+                throw new MalformedURLException("Illegal character in URL");
+            }
+        }
+        return u;
+    }
+    protected HttpURLConnection(URL u, Proxy p, Handler handler)
+            throws IOException {
+        super(checkURL(u));
         requests = new MessageHeader();
         responses = new MessageHeader();
         userHeaders = new MessageHeader();
--- a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsURLConnectionImpl.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsURLConnectionImpl.java	Fri Oct 20 09:49:02 2017 -0700
@@ -38,6 +38,7 @@
 import java.net.URL;
 import java.net.Proxy;
 import java.net.ProtocolException;
+import java.net.MalformedURLException;
 import java.io.*;
 import java.net.Authenticator;
 import javax.net.ssl.*;
@@ -80,10 +81,18 @@
         this(u, null, handler);
     }
 
+    static URL checkURL(URL u) throws IOException {
+        if (u != null) {
+            if (u.toExternalForm().indexOf('\n') > -1) {
+                throw new MalformedURLException("Illegal character in URL");
+            }
+        }
+        return u;
+    }
 // For both copies of the file, uncomment one line and comment the other
     HttpsURLConnectionImpl(URL u, Proxy p, Handler handler) throws IOException {
 //    HttpsURLConnectionOldImpl(URL u, Proxy p, Handler handler) throws IOException {
-        super(u);
+        super(checkURL(u));
         delegate = new DelegateHttpsURLConnection(url, p, handler, this);
     }
 
--- a/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Fri Oct 20 09:49:02 2017 -0700
@@ -46,6 +46,7 @@
 import java.security.cert.X509Certificate;
 import java.security.cert.CertificateException;
 import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
 import java.security.spec.KeySpec;
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.*;
@@ -147,6 +148,11 @@
         "keystore.PKCS12.keyProtectionAlgorithm"
     };
 
+    private static final int MAX_ITERATION_COUNT = 5000000;
+    private static final int PBE_ITERATION_COUNT = 50000; // default
+    private static final int MAC_ITERATION_COUNT = 100000; // default
+    private static final int SALT_LEN = 20;
+
     // friendlyName, localKeyId, trustedKeyUsage
     private static final String[] CORE_ATTRIBUTES = {
         "1.2.840.113549.1.9.20",
@@ -192,8 +198,6 @@
     private static ObjectIdentifier[] AnyUsage;
 
     private int counter = 0;
-    private static final int iterationCount = 1024;
-    private static final int SALT_LEN = 20;
 
     // private key count
     // Note: This is a workaround to allow null localKeyID attribute
@@ -327,6 +331,7 @@
         byte[] encryptedKey;
         AlgorithmParameters algParams;
         ObjectIdentifier algOid;
+
         try {
             // get the encrypted private key
             EncryptedPrivateKeyInfo encrInfo =
@@ -347,7 +352,24 @@
             throw uke;
         }
 
-        try {
+       try {
+            PBEParameterSpec pbeSpec;
+            int ic = 0;
+
+            if (algParams != null) {
+                try {
+                    pbeSpec =
+                        algParams.getParameterSpec(PBEParameterSpec.class);
+                } catch (InvalidParameterSpecException ipse) {
+                    throw new IOException("Invalid PBE algorithm parameters");
+                }
+                ic = pbeSpec.getIterationCount();
+
+                if (ic > MAX_ITERATION_COUNT) {
+                    throw new IOException("PBE iteration count too large");
+                }
+            }
+
             byte[] keyInfo;
             while (true) {
                 try {
@@ -387,9 +409,10 @@
                 key = kfac.generatePrivate(kspec);
 
                 if (debug != null) {
-                    debug.println("Retrieved a protected private key (" +
-                        key.getClass().getName() + ") at alias '" + alias +
-                        "'");
+                    debug.println("Retrieved a protected private key at alias" +
+                        " '" + alias + "' (" +
+                        new AlgorithmId(algOid).getName() +
+                        " iterations: " + ic + ")");
                 }
 
             // decode secret key
@@ -410,9 +433,10 @@
                 }
 
                 if (debug != null) {
-                    debug.println("Retrieved a protected secret key (" +
-                        key.getClass().getName() + ") at alias '" + alias +
-                        "'");
+                    debug.println("Retrieved a protected secret key at alias " +
+                        "'" + alias + "' (" +
+                        new AlgorithmId(algOid).getName() +
+                        " iterations: " + ic + ")");
                 }
             }
         } catch (Exception e) {
@@ -590,9 +614,9 @@
                     (key.getFormat().equals("PKCS8"))) {
 
                     if (debug != null) {
-                        debug.println("Setting a protected private key (" +
-                            key.getClass().getName() + ") at alias '" + alias +
-                            "'");
+                        debug.println(
+                            "Setting a protected private key at alias '" +
+                            alias + "'");
                         }
 
                     // Encrypt the private key
@@ -638,9 +662,8 @@
                     encryptPrivateKey(pkcs8.toByteArray(), passwordProtection);
 
                 if (debug != null) {
-                    debug.println("Setting a protected secret key (" +
-                        key.getClass().getName() + ") at alias '" + alias +
-                        "'");
+                    debug.println("Setting a protected secret key at alias '" +
+                        alias + "'");
                 }
                 secretKeyCount++;
                 entry = keyEntry;
@@ -761,19 +784,19 @@
     /*
      * Generate PBE Algorithm Parameters
      */
-    private AlgorithmParameters getAlgorithmParameters(String algorithm)
+    private AlgorithmParameters getPBEAlgorithmParameters(String algorithm)
         throws IOException
     {
         AlgorithmParameters algParams = null;
 
         // create PBE parameters from salt and iteration count
         PBEParameterSpec paramSpec =
-                new PBEParameterSpec(getSalt(), iterationCount);
+                new PBEParameterSpec(getSalt(), PBE_ITERATION_COUNT);
         try {
            algParams = AlgorithmParameters.getInstance(algorithm);
            algParams.init(paramSpec);
         } catch (Exception e) {
-           throw new IOException("getAlgorithmParameters failed: " +
+           throw new IOException("getPBEAlgorithmParameters failed: " +
                                  e.getMessage(), e);
         }
         return algParams;
@@ -859,7 +882,7 @@
                     algParams = AlgorithmParameters.getInstance(algorithm);
                     algParams.init(algParamSpec);
                 } else {
-                    algParams = getAlgorithmParameters(algorithm);
+                    algParams = getPBEAlgorithmParameters(algorithm);
                 }
             } else {
                 // Check default key protection algorithm for PKCS12 keystores
@@ -879,7 +902,7 @@
                 if (algorithm == null || algorithm.isEmpty()) {
                     algorithm = "PBEWithSHA1AndDESede";
                 }
-                algParams = getAlgorithmParameters(algorithm);
+                algParams = getPBEAlgorithmParameters(algorithm);
             }
 
             ObjectIdentifier pbeOID = mapPBEAlgorithmToOID(algorithm);
@@ -1194,7 +1217,7 @@
 
             if (debug != null) {
                 debug.println("Storing " + (privateKeyCount + secretKeyCount) +
-                    " protected key(s) in a PKCS#7 data content-type");
+                    " protected key(s) in a PKCS#7 data");
             }
 
             byte[] safeContentData = createSafeContent();
@@ -1207,7 +1230,7 @@
 
             if (debug != null) {
                 debug.println("Storing " + certificateCount +
-                    " certificate(s) in a PKCS#7 encryptedData content-type");
+                    " certificate(s) in a PKCS#7 encryptedData");
             }
 
             byte[] encrData = createEncryptedData(password);
@@ -1478,7 +1501,7 @@
             // generate MAC (MAC key is generated within JCE)
             Mac m = Mac.getInstance("HmacPBESHA1");
             PBEParameterSpec params =
-                        new PBEParameterSpec(salt, iterationCount);
+                        new PBEParameterSpec(salt, MAC_ITERATION_COUNT);
             SecretKey key = getPBEKey(passwd);
             m.init(key, params);
             m.update(data);
@@ -1486,7 +1509,7 @@
 
             // encode as MacData
             MacData macData = new MacData(algName, macResult, salt,
-                                                iterationCount);
+                                                MAC_ITERATION_COUNT);
             DerOutputStream bytes = new DerOutputStream();
             bytes.write(macData.getEncoded());
             mData = bytes.toByteArray();
@@ -1878,7 +1901,7 @@
 
         // create AlgorithmParameters
         AlgorithmParameters algParams =
-                getAlgorithmParameters("PBEWithSHA1AndRC2_40");
+                getPBEAlgorithmParameters("PBEWithSHA1AndRC2_40");
         DerOutputStream bytes = new DerOutputStream();
         AlgorithmId algId =
                 new AlgorithmId(pbeWithSHAAnd40BitRC2CBC_OID, algParams);
@@ -1998,7 +2021,7 @@
             if (contentType.equals(ContentInfo.DATA_OID)) {
 
                 if (debug != null) {
-                    debug.println("Loading PKCS#7 data content-type");
+                    debug.println("Loading PKCS#7 data");
                 }
 
                 safeContentsData = safeContents.getData();
@@ -2007,15 +2030,11 @@
 
                     if (debug != null) {
                         debug.println("Warning: skipping PKCS#7 encryptedData" +
-                            " content-type - no password was supplied");
+                            " - no password was supplied");
                     }
                     continue;
                 }
 
-                if (debug != null) {
-                    debug.println("Loading PKCS#7 encryptedData content-type");
-                }
-
                 DerInputStream edi =
                                 safeContents.getContent().toDerInputStream();
                 int edVersion = edi.getInteger();
@@ -2036,6 +2055,30 @@
                 ObjectIdentifier algOid = in.getOID();
                 AlgorithmParameters algParams = parseAlgParameters(algOid, in);
 
+                PBEParameterSpec pbeSpec;
+                int ic = 0;
+
+                if (algParams != null) {
+                    try {
+                        pbeSpec =
+                            algParams.getParameterSpec(PBEParameterSpec.class);
+                    } catch (InvalidParameterSpecException ipse) {
+                        throw new IOException(
+                            "Invalid PBE algorithm parameters");
+                    }
+                    ic = pbeSpec.getIterationCount();
+
+                    if (ic > MAX_ITERATION_COUNT) {
+                        throw new IOException("PBE iteration count too large");
+                    }
+                }
+
+                if (debug != null) {
+                    debug.println("Loading PKCS#7 encryptedData " +
+                        "(" + new AlgorithmId(algOid).getName() +
+                        " iterations: " + ic + ")");
+                }
+
                 while (true) {
                     try {
                         // Use JCE
@@ -2066,8 +2109,15 @@
 
         // The MacData is optional.
         if (password != null && s.available() > 0) {
-           MacData macData = new MacData(s);
-           try {
+            MacData macData = new MacData(s);
+            int ic = macData.getIterations();
+
+            try {
+                if (ic > MAX_ITERATION_COUNT) {
+                    throw new InvalidAlgorithmParameterException(
+                        "MAC iteration count too large: " + ic);
+                }
+
                 String algName =
                         macData.getDigestAlgName().toUpperCase(Locale.ENGLISH);
 
@@ -2077,8 +2127,7 @@
                 // generate MAC (MAC key is created within JCE)
                 Mac m = Mac.getInstance("HmacPBE" + algName);
                 PBEParameterSpec params =
-                        new PBEParameterSpec(macData.getSalt(),
-                                        macData.getIterations());
+                        new PBEParameterSpec(macData.getSalt(), ic);
                 SecretKey key = getPBEKey(password);
                 m.init(key, params);
                 m.update(authSafeData);
@@ -2086,16 +2135,16 @@
 
                 if (debug != null) {
                     debug.println("Checking keystore integrity " +
-                        "(MAC algorithm: " + m.getAlgorithm() + ")");
+                        "(" + m.getAlgorithm() + " iterations: " + ic + ")");
                 }
 
                 if (!MessageDigest.isEqual(macData.getDigest(), macResult)) {
                    throw new UnrecoverableKeyException("Failed PKCS12" +
                                         " integrity checking");
                 }
-           } catch (Exception e) {
+            } catch (Exception e) {
                 throw new IOException("Integrity check failed: " + e, e);
-           }
+            }
         }
 
         /*
--- a/src/java.base/share/classes/sun/security/provider/DSAKeyPairGenerator.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/security/provider/DSAKeyPairGenerator.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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,8 @@
 import java.security.spec.DSAParameterSpec;
 
 import sun.security.jca.JCAUtil;
+import static sun.security.util.SecurityProviderConstants.DEF_DSA_KEY_SIZE;
+import static sun.security.util.SecurityProviderConstants.getDefDSASubprimeSize;
 
 /**
  * This class generates DSA key parameters and public/private key
@@ -45,15 +47,14 @@
  * @author Andreas Sterbenz
  *
  */
-public class DSAKeyPairGenerator extends KeyPairGenerator
-        implements java.security.interfaces.DSAKeyPairGenerator {
+class DSAKeyPairGenerator extends KeyPairGenerator {
 
     /* Length for prime P and subPrime Q in bits */
     private int plen;
     private int qlen;
 
     /* whether to force new parameters to be generated for each KeyPair */
-    private boolean forceNewParameters;
+    boolean forceNewParameters;
 
     /* preset algorithm parameters. */
     private DSAParameterSpec params;
@@ -61,9 +62,9 @@
     /* The source of random bits to use */
     private SecureRandom random;
 
-    public DSAKeyPairGenerator() {
+    DSAKeyPairGenerator(int defaultKeySize) {
         super("DSA");
-        initialize(1024, null);
+        initialize(defaultKeySize, null);
     }
 
     private static void checkStrength(int sizeP, int sizeQ) {
@@ -84,61 +85,7 @@
     }
 
     public void initialize(int modlen, SecureRandom random) {
-        // generate new parameters when no precomputed ones available.
-        initialize(modlen, true, random);
-        this.forceNewParameters = false;
-    }
-
-    /**
-     * Initializes the DSA key pair generator. If <code>genParams</code>
-     * is false, a set of pre-computed parameters is used.
-     */
-    @Override
-    public void initialize(int modlen, boolean genParams, SecureRandom random)
-            throws InvalidParameterException {
-
-        int subPrimeLen = -1;
-        if (modlen <= 1024) {
-            subPrimeLen = 160;
-        } else if (modlen == 2048) {
-            subPrimeLen = 224;
-        } else if (modlen == 3072) {
-            subPrimeLen = 256;
-        }
-        checkStrength(modlen, subPrimeLen);
-        if (genParams) {
-            params = null;
-        } else {
-            params = ParameterCache.getCachedDSAParameterSpec(modlen,
-                subPrimeLen);
-            if (params == null) {
-                throw new InvalidParameterException
-                    ("No precomputed parameters for requested modulus size "
-                     + "available");
-            }
-
-        }
-        this.plen = modlen;
-        this.qlen = subPrimeLen;
-        this.random = random;
-        this.forceNewParameters = genParams;
-    }
-
-    /**
-     * Initializes the DSA object using a DSA parameter object.
-     *
-     * @param params a fully initialized DSA parameter object.
-     */
-    @Override
-    public void initialize(DSAParams params, SecureRandom random)
-            throws InvalidParameterException {
-
-        if (params == null) {
-            throw new InvalidParameterException("Params must not be null");
-        }
-        DSAParameterSpec spec = new DSAParameterSpec
-                                (params.getP(), params.getQ(), params.getG());
-        initialize0(spec, random);
+        init(modlen, random, false);
     }
 
     /**
@@ -157,10 +104,21 @@
             throw new InvalidAlgorithmParameterException
                 ("Inappropriate parameter");
         }
-        initialize0((DSAParameterSpec)params, random);
+        init((DSAParameterSpec)params, random, false);
     }
 
-    private void initialize0(DSAParameterSpec params, SecureRandom random) {
+    void init(int modlen, SecureRandom random, boolean forceNew) {
+        int subPrimeLen = getDefDSASubprimeSize(modlen);
+        checkStrength(modlen, subPrimeLen);
+        this.plen = modlen;
+        this.qlen = subPrimeLen;
+        this.params = null;
+        this.random = random;
+        this.forceNewParameters = forceNew;
+    }
+
+    void init(DSAParameterSpec params, SecureRandom random,
+        boolean forceNew) {
         int sizeP = params.getP().bitLength();
         int sizeQ = params.getQ().bitLength();
         checkStrength(sizeP, sizeQ);
@@ -168,7 +126,7 @@
         this.qlen = sizeQ;
         this.params = params;
         this.random = random;
-        this.forceNewParameters = false;
+        this.forceNewParameters = forceNew;
     }
 
     /**
@@ -197,7 +155,7 @@
         return generateKeyPair(spec.getP(), spec.getQ(), spec.getG(), random);
     }
 
-    public KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g,
+    private KeyPair generateKeyPair(BigInteger p, BigInteger q, BigInteger g,
                                    SecureRandom random) {
 
         BigInteger x = generateX(random, q);
@@ -252,4 +210,55 @@
         return y;
     }
 
+    public static final class Current extends DSAKeyPairGenerator {
+        public Current() {
+            super(DEF_DSA_KEY_SIZE);
+        }
+    }
+
+    public static final class Legacy extends DSAKeyPairGenerator
+        implements java.security.interfaces.DSAKeyPairGenerator {
+
+        public Legacy() {
+            super(1024);
+        }
+
+        /**
+         * Initializes the DSA key pair generator. If <code>genParams</code>
+         * is false, a set of pre-computed parameters is used.
+         */
+        @Override
+        public void initialize(int modlen, boolean genParams,
+            SecureRandom random) throws InvalidParameterException {
+            if (genParams) {
+                super.init(modlen, random, true);
+            } else {
+                DSAParameterSpec cachedParams =
+                    ParameterCache.getCachedDSAParameterSpec(modlen,
+                        getDefDSASubprimeSize(modlen));
+                if (cachedParams == null) {
+                    throw new InvalidParameterException
+                        ("No precomputed parameters for requested modulus" +
+                         " size available");
+                }
+                super.init(cachedParams, random, false);
+            }
+        }
+
+        /**
+         * Initializes the DSA object using a DSA parameter object.
+         *
+         * @param params a fully initialized DSA parameter object.
+         */
+        @Override
+        public void initialize(DSAParams params, SecureRandom random)
+            throws InvalidParameterException {
+            if (params == null) {
+                throw new InvalidParameterException("Params must not be null");
+             }
+             DSAParameterSpec spec = new DSAParameterSpec
+                 (params.getP(), params.getQ(), params.getG());
+             super.init(spec, random, false);
+        }
+    }
 }
--- a/src/java.base/share/classes/sun/security/provider/DSAParameterGenerator.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/security/provider/DSAParameterGenerator.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -34,15 +34,18 @@
 import java.security.InvalidParameterException;
 import java.security.MessageDigest;
 import java.security.SecureRandom;
+import java.security.ProviderException;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.InvalidParameterSpecException;
 import java.security.spec.DSAParameterSpec;
 import java.security.spec.DSAGenParameterSpec;
 
+import static sun.security.util.SecurityProviderConstants.DEF_DSA_KEY_SIZE;
+import static sun.security.util.SecurityProviderConstants.getDefDSASubprimeSize;
+
+
 /**
- * This class generates parameters for the DSA algorithm. It uses a default
- * prime modulus size of 1024 bits, which can be overwritten during
- * initialization.
+ * This class generates parameters for the DSA algorithm.
  *
  * @author Jan Luehe
  *
@@ -56,10 +59,6 @@
 
 public class DSAParameterGenerator extends AlgorithmParameterGeneratorSpi {
 
-    // the default parameters
-    private static final DSAGenParameterSpec DEFAULTS =
-        new DSAGenParameterSpec(1024, 160, 160);
-
     // the length of prime P, subPrime Q, and seed in bits
     private int valueL = -1;
     private int valueN = -1;
@@ -80,18 +79,14 @@
      */
     @Override
     protected void engineInit(int strength, SecureRandom random) {
-        if ((strength >= 512) && (strength <= 1024) && (strength % 64 == 0)) {
-            this.valueN = 160;
-        } else if (strength == 2048) {
-            this.valueN = 224;
-        } else if (strength == 3072) {
-            this.valueN = 256;
-        } else {
+        if ((strength != 2048) && (strength != 3072) &&
+            ((strength < 512) || (strength > 1024) || (strength % 64 != 0))) {
             throw new InvalidParameterException(
-                "Unexpected strength (size of prime): " + strength + ". " +
-                "Prime size should be 512 - 1024, or 2048, 3072");
+                "Unexpected strength (size of prime): " + strength +
+                ". Prime size should be 512-1024, 2048, or 3072");
         }
         this.valueL = strength;
+        this.valueN = getDefDSASubprimeSize(strength);
         this.seedLen = valueN;
         this.random = random;
     }
@@ -110,7 +105,6 @@
     @Override
     protected void engineInit(AlgorithmParameterSpec genParamSpec,
             SecureRandom random) throws InvalidAlgorithmParameterException {
-
         if (!(genParamSpec instanceof DSAGenParameterSpec)) {
             throw new InvalidAlgorithmParameterException("Invalid parameter");
         }
@@ -136,11 +130,7 @@
                 this.random = new SecureRandom();
             }
             if (valueL == -1) {
-                try {
-                    engineInit(DEFAULTS, this.random);
-                } catch (InvalidAlgorithmParameterException iape) {
-                    // should never happen
-                }
+                engineInit(DEF_DSA_KEY_SIZE, this.random);
             }
             BigInteger[] pAndQ = generatePandQ(this.random, valueL,
                                                valueN, seedLen);
@@ -206,13 +196,17 @@
         int b = (valueL - 1) % outLen;
         byte[] seedBytes = new byte[seedLen/8];
         BigInteger twoSl = BigInteger.TWO.pow(seedLen);
-        int primeCertainty = 80; // for 1024-bit prime P
-        if (valueL == 2048) {
+        int primeCertainty = -1;
+        if (valueL <= 1024) {
+            primeCertainty = 80;
+        } else if (valueL == 2048) {
             primeCertainty = 112;
         } else if (valueL == 3072) {
             primeCertainty = 128;
         }
-
+        if (primeCertainty < 0) {
+            throw new ProviderException("Invalid valueL: " + valueL);
+        }
         BigInteger resultP, resultQ, seed = null;
         int counter;
         while (true) {
--- a/src/java.base/share/classes/sun/security/provider/SunEntries.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/security/provider/SunEntries.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -29,6 +29,7 @@
 import java.net.*;
 import java.util.Map;
 import java.security.*;
+import sun.security.action.GetPropertyAction;
 
 /**
  * Defines the entries of the SUN provider.
@@ -74,6 +75,10 @@
 
 final class SunEntries {
 
+    private static final boolean useLegacyDSA =
+        Boolean.parseBoolean(GetPropertyAction.privilegedGetProperty
+            ("jdk.security.legacyDSAKeyPairGenerator"));
+
     private SunEntries() {
         // empty
     }
@@ -174,8 +179,9 @@
         /*
          *  Key Pair Generator engines
          */
-        map.put("KeyPairGenerator.DSA",
-            "sun.security.provider.DSAKeyPairGenerator");
+        String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$";
+        dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current");
+        map.put("KeyPairGenerator.DSA", dsaKPGImplClass);
         map.put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
         map.put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
         map.put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");
--- a/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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,6 +32,7 @@
 import java.security.spec.RSAKeyGenParameterSpec;
 
 import sun.security.jca.JCAUtil;
+import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
 
 /**
  * RSA keypair generation. Standard algorithm, minimum key length 512 bit.
@@ -55,7 +56,7 @@
 
     public RSAKeyPairGenerator() {
         // initialize to default in case the app does not call initialize()
-        initialize(2048, null);
+        initialize(DEF_RSA_KEY_SIZE, null);
     }
 
     // initialize the generator. See JCA doc
--- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java	Fri Oct 20 09:49:02 2017 -0700
@@ -26,6 +26,8 @@
 package sun.security.tools.keytool;
 
 import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.security.CodeSigner;
 import java.security.CryptoPrimitive;
 import java.security.KeyStore;
@@ -72,6 +74,7 @@
 import sun.security.provider.X509Factory;
 import sun.security.provider.certpath.ssl.SSLServerCertStore;
 import sun.security.util.Password;
+import sun.security.util.SecurityProviderConstants;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
 import javax.crypto.SecretKeyFactory;
@@ -168,7 +171,12 @@
     private List<String> ids = new ArrayList<>();   // used in GENCRL
     private List<String> v3ext = new ArrayList<>();
 
-    // Warnings on weak algorithms
+    // In-place importkeystore is special.
+    // A backup is needed, and no need to prompt for deststorepass.
+    private boolean inplaceImport = false;
+    private String inplaceBackupName = null;
+
+    // Warnings on weak algorithms etc
     private List<String> weakWarnings = new ArrayList<>();
 
     private static final DisabledAlgorithmConstraints DISABLED_CHECK =
@@ -846,37 +854,52 @@
                 ("New.password.must.be.at.least.6.characters"));
         }
 
+        // Set this before inplaceImport check so we can compare name.
+        if (ksfname == null) {
+            ksfname = System.getProperty("user.home") + File.separator
+                    + ".keystore";
+        }
+
+        KeyStore srcKeyStore = null;
+        if (command == IMPORTKEYSTORE) {
+            inplaceImport = inplaceImportCheck();
+            if (inplaceImport) {
+                // We load srckeystore first so we have srcstorePass that
+                // can be assigned to storePass
+                srcKeyStore = loadSourceKeyStore();
+                if (storePass == null) {
+                    storePass = srcstorePass;
+                }
+            }
+        }
+
         // Check if keystore exists.
         // If no keystore has been specified at the command line, try to use
         // the default, which is located in $HOME/.keystore.
         // If the command is "genkey", "identitydb", "import", or "printcert",
         // it is OK not to have a keystore.
-        if (isKeyStoreRelated(command)) {
-            if (ksfname == null) {
-                ksfname = System.getProperty("user.home") + File.separator
-                    + ".keystore";
-            }
-
-            if (!nullStream) {
-                try {
-                    ksfile = new File(ksfname);
-                    // Check if keystore file is empty
-                    if (ksfile.exists() && ksfile.length() == 0) {
-                        throw new Exception(rb.getString
-                        ("Keystore.file.exists.but.is.empty.") + ksfname);
-                    }
-                    ksStream = new FileInputStream(ksfile);
-                } catch (FileNotFoundException e) {
-                    if (command != GENKEYPAIR &&
+
+        // DO NOT open the existing keystore if this is an in-place import.
+        // The keystore should be created as brand new.
+        if (isKeyStoreRelated(command) && !nullStream && !inplaceImport) {
+            try {
+                ksfile = new File(ksfname);
+                // Check if keystore file is empty
+                if (ksfile.exists() && ksfile.length() == 0) {
+                    throw new Exception(rb.getString
+                            ("Keystore.file.exists.but.is.empty.") + ksfname);
+                }
+                ksStream = new FileInputStream(ksfile);
+            } catch (FileNotFoundException e) {
+                if (command != GENKEYPAIR &&
                         command != GENSECKEY &&
                         command != IDENTITYDB &&
                         command != IMPORTCERT &&
                         command != IMPORTPASS &&
                         command != IMPORTKEYSTORE &&
                         command != PRINTCRL) {
-                        throw new Exception(rb.getString
-                                ("Keystore.file.does.not.exist.") + ksfname);
-                    }
+                    throw new Exception(rb.getString
+                            ("Keystore.file.does.not.exist.") + ksfname);
                 }
             }
         }
@@ -900,7 +923,7 @@
         // Create new keystore
         // Probe for keystore type when filename is available
         if (ksfile != null && ksStream != null && providerName == null &&
-            hasStoretypeOption == false) {
+                hasStoretypeOption == false && !inplaceImport) {
             keyStore = KeyStore.getInstance(ksfile, storePass);
         } else {
             if (providerName == null) {
@@ -930,7 +953,11 @@
              * Null stream keystores are loaded later.
              */
             if (!nullStream) {
-                keyStore.load(ksStream, storePass);
+                if (inplaceImport) {
+                    keyStore.load(null, storePass);
+                } else {
+                    keyStore.load(ksStream, storePass);
+                }
                 if (ksStream != null) {
                     ksStream.close();
                 }
@@ -1167,7 +1194,11 @@
                 }
             }
         } else if (command == IMPORTKEYSTORE) {
-            doImportKeyStore();
+            // When not in-place import, srcKeyStore is not loaded yet.
+            if (srcKeyStore == null) {
+                srcKeyStore = loadSourceKeyStore();
+            }
+            doImportKeyStore(srcKeyStore);
             kssave = true;
         } else if (command == KEYCLONE) {
             keyPassNew = newPass;
@@ -1298,6 +1329,51 @@
                 }
             }
         }
+
+        if (isKeyStoreRelated(command)
+                && !token && !nullStream && ksfname != null) {
+
+            // JKS storetype warning on the final result keystore
+            File f = new File(ksfname);
+            char[] pass = (storePassNew!=null) ? storePassNew : storePass;
+            if (f.exists()) {
+                // Probe for real type. A JKS can be loaded as PKCS12 because
+                // DualFormat support, vice versa.
+                keyStore = KeyStore.getInstance(f, pass);
+                String realType = keyStore.getType();
+                if (realType.equalsIgnoreCase("JKS")
+                        || realType.equalsIgnoreCase("JCEKS")) {
+                    boolean allCerts = true;
+                    for (String a : Collections.list(keyStore.aliases())) {
+                        if (!keyStore.entryInstanceOf(
+                                a, TrustedCertificateEntry.class)) {
+                            allCerts = false;
+                            break;
+                        }
+                    }
+                    // Don't warn for "cacerts" style keystore.
+                    if (!allCerts) {
+                        weakWarnings.add(String.format(
+                                rb.getString("jks.storetype.warning"),
+                                realType, ksfname));
+                    }
+                }
+                if (inplaceImport) {
+                    String realSourceStoreType = KeyStore.getInstance(
+                            new File(inplaceBackupName), srcstorePass).getType();
+                    String format =
+                            realType.equalsIgnoreCase(realSourceStoreType) ?
+                            rb.getString("backup.keystore.warning") :
+                            rb.getString("migrate.keystore.warning");
+                    weakWarnings.add(
+                            String.format(format,
+                                    srcksfname,
+                                    realSourceStoreType,
+                                    inplaceBackupName,
+                                    realType));
+                }
+            }
+        }
     }
 
     /**
@@ -1742,9 +1818,12 @@
     {
         if (keysize == -1) {
             if ("EC".equalsIgnoreCase(keyAlgName)) {
-                keysize = 256;
-            } else {
-                keysize = 2048;     // RSA and DSA
+                keysize = SecurityProviderConstants.DEF_EC_KEY_SIZE;
+            } else if ("RSA".equalsIgnoreCase(keyAlgName)) {
+                keysize = SecurityProviderConstants.DEF_RSA_KEY_SIZE;
+            } else if ("DSA".equalsIgnoreCase(keyAlgName)) {
+                // hardcode for now as DEF_DSA_KEY_SIZE is still 1024
+                keysize = 2048; // SecurityProviderConstants.DEF_DSA_KEY_SIZE;
             }
         }
 
@@ -1989,12 +2068,40 @@
         }
     }
 
+    boolean inplaceImportCheck() throws Exception {
+        if (P11KEYSTORE.equalsIgnoreCase(srcstoretype) ||
+                KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
+            return false;
+        }
+
+        if (srcksfname != null) {
+            File srcksfile = new File(srcksfname);
+            if (srcksfile.exists() && srcksfile.length() == 0) {
+                throw new Exception(rb.getString
+                        ("Source.keystore.file.exists.but.is.empty.") +
+                        srcksfname);
+            }
+            if (srcksfile.getCanonicalFile()
+                    .equals(new File(ksfname).getCanonicalFile())) {
+                return true;
+            } else {
+                // Informational, especially if destkeystore is not
+                // provided, which default to ~/.keystore.
+                System.err.println(String.format(rb.getString(
+                        "importing.keystore.status"), srcksfname, ksfname));
+                return false;
+            }
+        } else {
+            throw new Exception(rb.getString
+                    ("Please.specify.srckeystore"));
+        }
+    }
+
     /**
      * Load the srckeystore from a stream, used in -importkeystore
      * @return the src KeyStore
      */
     KeyStore loadSourceKeyStore() throws Exception {
-        boolean isPkcs11 = false;
 
         InputStream is = null;
         File srcksfile = null;
@@ -2007,20 +2114,9 @@
                 System.err.println();
                 tinyHelp();
             }
-            isPkcs11 = true;
         } else {
-            if (srcksfname != null) {
-                srcksfile = new File(srcksfname);
-                    if (srcksfile.exists() && srcksfile.length() == 0) {
-                        throw new Exception(rb.getString
-                                ("Source.keystore.file.exists.but.is.empty.") +
-                                srcksfname);
-                }
-                is = new FileInputStream(srcksfile);
-            } else {
-                throw new Exception(rb.getString
-                        ("Please.specify.srckeystore"));
-            }
+            srcksfile = new File(srcksfname);
+            is = new FileInputStream(srcksfile);
         }
 
         KeyStore store;
@@ -2087,17 +2183,32 @@
      * keep alias unchanged if no name conflict, otherwise, prompt.
      * keep keypass unchanged for keys
      */
-    private void doImportKeyStore() throws Exception {
+    private void doImportKeyStore(KeyStore srcKS) throws Exception {
 
         if (alias != null) {
-            doImportKeyStoreSingle(loadSourceKeyStore(), alias);
+            doImportKeyStoreSingle(srcKS, alias);
         } else {
             if (dest != null || srckeyPass != null) {
                 throw new Exception(rb.getString(
                         "if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified"));
             }
-            doImportKeyStoreAll(loadSourceKeyStore());
+            doImportKeyStoreAll(srcKS);
         }
+
+        if (inplaceImport) {
+            // Backup to file.old or file.old2...
+            // The keystore is not rewritten yet now.
+            for (int n = 1; /* forever */; n++) {
+                inplaceBackupName = srcksfname + ".old" + (n == 1 ? "" : n);
+                File bkFile = new File(inplaceBackupName);
+                if (!bkFile.exists()) {
+                    Files.copy(Paths.get(srcksfname), bkFile.toPath());
+                    break;
+                }
+            }
+
+        }
+
         /*
          * Information display rule of -importkeystore
          * 1. inside single, shows failure
--- a/src/java.base/share/classes/sun/security/tools/keytool/Resources.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/security/tools/keytool/Resources.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -471,6 +471,10 @@
         {"verified.by.s.in.s.weak", "Verified by %s in %s with a %s"},
         {"whose.sigalg.risk", "%s uses the %s signature algorithm which is considered a security risk."},
         {"whose.key.risk", "%s uses a %s which is considered a security risk."},
+        {"jks.storetype.warning", "The %1$s keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using \"keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12\"."},
+        {"migrate.keystore.warning", "Migrated \"%1$s\" to %4$s. The %2$s keystore is backed up as \"%3$s\"."},
+        {"backup.keystore.warning", "The original keystore \"%1$s\" is backed up as \"%3$s\"..."},
+        {"importing.keystore.status", "Importing keystore %1$s to %2$s..."},
     };
 
 
--- a/src/java.base/share/classes/sun/security/util/IOUtils.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/security/util/IOUtils.java	Fri Oct 20 09:49:02 2017 -0700
@@ -37,7 +37,7 @@
 public class IOUtils {
 
     /**
-     * Read up to <code>length</code> of bytes from <code>in</code>
+     * Read up to {@code length} of bytes from {@code in}
      * until EOF is detected.
      * @param is input stream, must not be null
      * @param length number of bytes to read
@@ -78,4 +78,22 @@
         }
         return output;
     }
+
+    /**
+     * Read {@code length} of bytes from {@code in}. An exception is
+     * thrown if there are not enough bytes in the stream.
+     *
+     * @param is input stream, must not be null
+     * @param length number of bytes to read, must not be negative
+     * @return bytes read
+     * @throws IOException if any IO error or a premature EOF is detected, or
+     *      if {@code length} is negative since this length is usually also
+     *      read from {@code is}.
+     */
+    public static byte[] readNBytes(InputStream is, int length) throws IOException {
+        if (length < 0) {
+            throw new IOException("length cannot be negative: " + length);
+        }
+        return readFully(is, length, true);
+    }
 }
--- a/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -111,7 +111,11 @@
         is.defaultReadObject();
 
         if (encoding == null) {  // from an old version
-            init((int[])components, componentLen);
+            int[] comp = (int[])components;
+            if (componentLen > comp.length) {
+                componentLen = comp.length;
+            }
+            init(comp, componentLen);
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java	Fri Oct 20 09:49:02 2017 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2017, 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.util.regex.PatternSyntaxException;
+import java.security.InvalidParameterException;
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Various constants such as version number, default key length, used by
+ * the JDK security/crypto providers.
+ */
+public final class SecurityProviderConstants {
+    private static final Debug debug =
+        Debug.getInstance("jca", "ProviderConfig");
+
+    // Cannot create one of these
+    private SecurityProviderConstants () {
+    }
+
+    public static final int getDefDSASubprimeSize(int primeSize) {
+        if (primeSize <= 1024) {
+            return 160;
+        } else if (primeSize == 2048) {
+            return 224;
+        } else if (primeSize == 3072) {
+            return 256;
+        } else {
+            throw new InvalidParameterException("Invalid DSA Prime Size: " +
+                primeSize);
+        }
+    }
+
+    public static final int DEF_DSA_KEY_SIZE;
+    public static final int DEF_RSA_KEY_SIZE;
+    public static final int DEF_DH_KEY_SIZE;
+    public static final int DEF_EC_KEY_SIZE;
+
+    private static final String KEY_LENGTH_PROP =
+        "jdk.security.defaultKeySize";
+    static {
+        String keyLengthStr = GetPropertyAction.privilegedGetProperty
+            (KEY_LENGTH_PROP);
+        int dsaKeySize = 1024;
+        int rsaKeySize = 2048;
+        int dhKeySize = 2048;
+        int ecKeySize = 256;
+
+        if (keyLengthStr != null) {
+            try {
+                String[] pairs = keyLengthStr.split(",");
+                for (String p : pairs) {
+                    String[] algoAndValue = p.split(":");
+                    if (algoAndValue.length != 2) {
+                        // invalid pair, skip to next pair
+                        if (debug != null) {
+                            debug.println("Ignoring invalid pair in " +
+                                KEY_LENGTH_PROP + " property: " + p);
+                        }
+                        continue;
+                    }
+                    String algoName = algoAndValue[0].trim().toUpperCase();
+                    int value = -1;
+                    try {
+                        value = Integer.parseInt(algoAndValue[1].trim());
+                    } catch (NumberFormatException nfe) {
+                        // invalid value, skip to next pair
+                        if (debug != null) {
+                            debug.println("Ignoring invalid value in " +
+                                KEY_LENGTH_PROP + " property: " + p);
+                        }
+                        continue;
+                    }
+                    if (algoName.equals("DSA")) {
+                        dsaKeySize = value;
+                    } else if (algoName.equals("RSA")) {
+                        rsaKeySize = value;
+                    } else if (algoName.equals("DH")) {
+                        dhKeySize = value;
+                    } else if (algoName.equals("EC")) {
+                        ecKeySize = value;
+                    } else {
+                        if (debug != null) {
+                            debug.println("Ignoring unsupported algo in " +
+                                KEY_LENGTH_PROP + " property: " + p);
+                        }
+                        continue;
+                    }
+                    if (debug != null) {
+                        debug.println("Overriding default " + algoName +
+                            " keysize with value from " +
+                            KEY_LENGTH_PROP + " property: " + value);
+                    }
+                }
+            } catch (PatternSyntaxException pse) {
+                // if property syntax is not followed correctly
+                if (debug != null) {
+                    debug.println("Unexpected exception while parsing " +
+                        KEY_LENGTH_PROP + " property: " + pse);
+                }
+            }
+        }
+        DEF_DSA_KEY_SIZE = dsaKeySize;
+        DEF_RSA_KEY_SIZE = rsaKeySize;
+        DEF_DH_KEY_SIZE = dhKeySize;
+        DEF_EC_KEY_SIZE = ecKeySize;
+    }
+}
--- a/src/java.base/share/classes/sun/security/x509/NameConstraintsExtension.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.base/share/classes/sun/security/x509/NameConstraintsExtension.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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.net.util.IPAddressUtil;
 import sun.security.util.*;
 import sun.security.pkcs.PKCS9Attribute;
 
@@ -440,6 +441,7 @@
         X500Principal subjectPrincipal = cert.getSubjectX500Principal();
         X500Name subject = X500Name.asX500Name(subjectPrincipal);
 
+        // Check subject as an X500Name
         if (subject.isEmpty() == false) {
             if (verify(subject) == false) {
                 return false;
@@ -465,12 +467,51 @@
                         "certificate: " + ce.getMessage());
         }
 
-        // If there are no subjectAlternativeNames, perform the special-case
-        // check where if the subjectName contains any EMAILADDRESS
-        // attributes, they must be checked against RFC822 constraints.
-        // If that passes, we're fine.
         if (altNames == null) {
-            return verifyRFC822SpecialCase(subject);
+            altNames = new GeneralNames();
+
+            // RFC 5280 4.2.1.10:
+            // When constraints are imposed on the rfc822Name name form,
+            // but the certificate does not include a subject alternative name,
+            // the rfc822Name constraint MUST be applied to the attribute of
+            // type emailAddress in the subject distinguished name.
+            for (AVA ava : subject.allAvas()) {
+                ObjectIdentifier attrOID = ava.getObjectIdentifier();
+                if (attrOID.equals(PKCS9Attribute.EMAIL_ADDRESS_OID)) {
+                    String attrValue = ava.getValueString();
+                    if (attrValue != null) {
+                        try {
+                            altNames.add(new GeneralName(
+                                    new RFC822Name(attrValue)));
+                        } catch (IOException ioe) {
+                            continue;
+                        }
+                    }
+                }
+            }
+        }
+
+        // If there is no IPAddressName or DNSName in subjectAlternativeNames,
+        // see if the last CN inside subjectName can be used instead.
+        DerValue derValue = subject.findMostSpecificAttribute
+                (X500Name.commonName_oid);
+        String cn = derValue == null ? null : derValue.getAsString();
+
+        if (cn != null) {
+            try {
+                if (IPAddressUtil.isIPv4LiteralAddress(cn) ||
+                        IPAddressUtil.isIPv6LiteralAddress(cn)) {
+                    if (!hasNameType(altNames, GeneralNameInterface.NAME_IP)) {
+                        altNames.add(new GeneralName(new IPAddressName(cn)));
+                    }
+                } else {
+                    if (!hasNameType(altNames, GeneralNameInterface.NAME_DNS)) {
+                        altNames.add(new GeneralName(new DNSName(cn)));
+                    }
+                }
+            } catch (IOException ioe) {
+                // OK, cn is neither IP nor DNS
+            }
         }
 
         // verify each subjectAltName
@@ -485,6 +526,15 @@
         return true;
     }
 
+    private static boolean hasNameType(GeneralNames names, int type) {
+        for (GeneralName name : names.names()) {
+            if (name.getType() == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * check whether a name conforms to these NameConstraints.
      * This involves verifying that the name is consistent with the
@@ -567,37 +617,6 @@
     }
 
     /**
-     * Perform the RFC 822 special case check. We have a certificate
-     * that does not contain any subject alternative names. Check that
-     * any EMAILADDRESS attributes in its subject name conform to these
-     * NameConstraints.
-     *
-     * @param subject the certificate's subject name
-     * @return true if certificate verifies successfully
-     * @throws IOException on error
-     */
-    public boolean verifyRFC822SpecialCase(X500Name subject) throws IOException {
-        for (AVA ava : subject.allAvas()) {
-            ObjectIdentifier attrOID = ava.getObjectIdentifier();
-            if (attrOID.equals(PKCS9Attribute.EMAIL_ADDRESS_OID)) {
-                String attrValue = ava.getValueString();
-                if (attrValue != null) {
-                    RFC822Name emailName;
-                    try {
-                        emailName = new RFC822Name(attrValue);
-                    } catch (IOException ioe) {
-                        continue;
-                    }
-                    if (!verify(emailName)) {
-                        return(false);
-                    }
-                }
-             }
-        }
-        return true;
-    }
-
-    /**
      * Clone all objects that may be modified during certificate validation.
      */
     public Object clone() {
--- a/src/java.corba/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.corba/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java	Fri Oct 20 09:49:02 2017 -0700
@@ -38,7 +38,10 @@
 import java.security.NoSuchAlgorithmException;
 import java.security.DigestOutputStream;
 import java.security.AccessController;
+import java.security.PermissionCollection;
+import java.security.Permissions;
 import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
 
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Field;
@@ -57,6 +60,8 @@
 
 import java.util.Arrays;
 import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
 
 import com.sun.corba.se.impl.util.RepositoryId;
 
@@ -443,6 +448,65 @@
     private static final PersistentFieldsValue persistentFieldsValue =
         new PersistentFieldsValue();
 
+    /**
+     * Creates a PermissionDomain that grants no permission.
+     */
+    private ProtectionDomain noPermissionsDomain() {
+        PermissionCollection perms = new Permissions();
+        perms.setReadOnly();
+        return new ProtectionDomain(null, perms);
+    }
+
+    /**
+     * Aggregate the ProtectionDomains of all the classes that separate
+     * a concrete class {@code cl} from its ancestor's class declaring
+     * a constructor {@code cons}.
+     *
+     * If {@code cl} is defined by the boot loader, or the constructor
+     * {@code cons} is declared by {@code cl}, or if there is no security
+     * manager, then this method does nothing and {@code null} is returned.
+     *
+     * @param cons A constructor declared by {@code cl} or one of its
+     *             ancestors.
+     * @param cl A concrete class, which is either the class declaring
+     *           the constructor {@code cons}, or a serializable subclass
+     *           of that class.
+     * @return An array of ProtectionDomain representing the set of
+     *         ProtectionDomain that separate the concrete class {@code cl}
+     *         from its ancestor's declaring {@code cons}, or {@code null}.
+     */
+    private ProtectionDomain[] getProtectionDomains(Constructor<?> cons,
+                                                    Class<?> cl) {
+        ProtectionDomain[] domains = null;
+        if (cons != null && cl.getClassLoader() != null
+                && System.getSecurityManager() != null) {
+            Class<?> cls = cl;
+            Class<?> fnscl = cons.getDeclaringClass();
+            Set<ProtectionDomain> pds = null;
+            while (cls != fnscl) {
+                ProtectionDomain pd = cls.getProtectionDomain();
+                if (pd != null) {
+                    if (pds == null) pds = new HashSet<>();
+                    pds.add(pd);
+                }
+                cls = cls.getSuperclass();
+                if (cls == null) {
+                    // that's not supposed to happen
+                    // make a ProtectionDomain with no permission.
+                    // should we throw instead?
+                    if (pds == null) pds = new HashSet<>();
+                    else pds.clear();
+                    pds.add(noPermissionsDomain());
+                    break;
+                }
+            }
+            if (pds != null) {
+                domains = pds.toArray(new ProtectionDomain[0]);
+            }
+        }
+        return domains;
+    }
+
     /*
      * Initialize class descriptor.  This method is only invoked on class
      * descriptors created via calls to lookupInternal().  This method is kept
@@ -568,11 +632,15 @@
 
                 readResolveObjectMethod = bridge.readResolveForSerialization(cl);
 
+                domains = new ProtectionDomain[] {noPermissionsDomain()};
+
                 if (externalizable)
                     cons = getExternalizableConstructor(cl) ;
                 else
                     cons = getSerializableConstructor(cl) ;
 
+                domains = getProtectionDomains(cons, cl);
+
                 if (serializable && !forProxyClass) {
                     writeObjectMethod = bridge.writeObjectForSerialization(cl) ;
                     readObjectMethod = bridge.readObjectForSerialization(cl);
@@ -910,7 +978,7 @@
     {
         if (cons != null) {
             try {
-                return cons.newInstance();
+                return bridge.newInstanceForSerialization(cons, domains);
             } catch (IllegalAccessException ex) {
                 // should not occur, as access checks have been suppressed
                 InternalError ie = new InternalError();
@@ -1506,6 +1574,7 @@
     private transient MethodHandle writeReplaceObjectMethod;
     private transient MethodHandle readResolveObjectMethod;
     private transient Constructor<?> cons;
+    private transient ProtectionDomain[] domains;
 
     /**
      * Beginning in Java to IDL ptc/02-01-12, RMI-IIOP has a
--- a/src/java.corba/share/classes/sun/corba/Bridge.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.corba/share/classes/sun/corba/Bridge.java	Fri Oct 20 09:49:02 2017 -0700
@@ -27,8 +27,9 @@
 
 import java.io.OptionalDataException;
 import java.lang.invoke.MethodHandle;
-import java.lang.reflect.Field ;
-import java.lang.reflect.Constructor ;
+import java.lang.reflect.Field;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.StackWalker;
 import java.lang.StackWalker.StackFrame;
 import java.util.Optional;
@@ -37,6 +38,7 @@
 import java.security.AccessController;
 import java.security.Permission;
 import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
 
 import sun.misc.Unsafe;
 import sun.reflect.ReflectionFactory;
@@ -341,6 +343,36 @@
     }
 
     /**
+     * Invokes the supplied constructor, adding the provided protection domains
+     * to the invocation stack before invoking {@code Constructor::newInstance}.
+     *
+     * This is equivalent to calling
+     * {@code ReflectionFactory.newInstanceForSerialization(cons,domains)}.
+     *
+     * @param cons A constructor obtained from {@code
+     *        newConstructorForSerialization} or {@code
+     *        newConstructorForExternalization}.
+     *
+     * @param domains An array of protection domains that limit the privileges
+     *        with which the constructor is invoked. Can be {@code null}
+     *        or empty, in which case privileges are only limited by the
+     *        {@linkplain AccessController#getContext() current context}.
+     *
+     * @return A new object built from the provided constructor.
+     *
+     * @throws NullPointerException if {@code cons} is {@code null}.
+     * @throws InstantiationException if thrown by {@code cons.newInstance()}.
+     * @throws InvocationTargetException if thrown by {@code cons.newInstance()}.
+     * @throws IllegalAccessException if thrown by {@code cons.newInstance()}.
+     */
+    public final Object newInstanceForSerialization(Constructor<?> cons,
+                                                    ProtectionDomain[] domains)
+        throws InstantiationException, InvocationTargetException, IllegalAccessException
+    {
+        return reflectionFactory.newInstanceForSerialization(cons, domains);
+    }
+
+    /**
      * Returns true if the given class defines a static initializer method,
      * false otherwise.
      */
--- a/src/java.desktop/share/native/liblcms/cmscgats.c	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/share/native/liblcms/cmscgats.c	Fri Oct 20 09:49:02 2017 -0700
@@ -900,7 +900,7 @@
             k = 0;
             NextCh(it8);
 
-            while (k < MAXSTR && it8->ch != sng) {
+            while (k < (MAXSTR-1) && it8->ch != sng) {
 
                 if (it8->ch == '\n'|| it8->ch == '\r') k = MAXSTR+1;
                 else {
@@ -2053,14 +2053,18 @@
 static
 void ReadType(cmsIT8* it8, char* SheetTypePtr)
 {
+    cmsInt32Number cnt = 0;
+
     // First line is a very special case.
 
     while (isseparator(it8->ch))
             NextCh(it8);
 
-    while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != -1) {
+    while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != 0) {
 
         *SheetTypePtr++= (char) it8 ->ch;
+        if (cnt++ < MAXSTR)
+            *SheetTypePtr++= (char) it8 ->ch;
         NextCh(it8);
     }
 
@@ -2253,7 +2257,7 @@
 // that should be something like some printable characters plus a \n
 // returns 0 if this is not like a CGATS, or an integer otherwise. This integer is the number of words in first line?
 static
-int IsMyBlock(cmsUInt8Number* Buffer, int n)
+int IsMyBlock(const cmsUInt8Number* Buffer, int n)
 {
     int words = 1, space = 0, quot = 0;
     int i;
@@ -2317,7 +2321,7 @@
 // ---------------------------------------------------------- Exported routines
 
 
-cmsHANDLE  CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, void *Ptr, cmsUInt32Number len)
+cmsHANDLE  CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cmsUInt32Number len)
 {
     cmsHANDLE hIT8;
     cmsIT8*  it8;
@@ -2326,7 +2330,7 @@
     _cmsAssert(Ptr != NULL);
     _cmsAssert(len != 0);
 
-    type = IsMyBlock((cmsUInt8Number*)Ptr, len);
+    type = IsMyBlock((const cmsUInt8Number*)Ptr, len);
     if (type == 0) return NULL;
 
     hIT8 = cmsIT8Alloc(ContextID);
--- a/src/java.desktop/share/native/liblcms/cmsnamed.c	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/share/native/liblcms/cmsnamed.c	Fri Oct 20 09:49:02 2017 -0700
@@ -546,7 +546,11 @@
         size = v ->Allocated * 2;
 
     // Keep a maximum color lists can grow, 100K entries seems reasonable
-    if (size > 1024*100) return FALSE;
+    if (size > 1024 * 100) {
+        _cmsFree(v->ContextID, (void*) v->List);
+        v->List = NULL;
+        return FALSE;
+    }
 
     NewPtr = (_cmsNAMEDCOLOR*) _cmsRealloc(v ->ContextID, v ->List, size * sizeof(_cmsNAMEDCOLOR));
     if (NewPtr == NULL)
@@ -568,8 +572,11 @@
     v ->nColors   = 0;
     v ->ContextID  = ContextID;
 
-    while (v -> Allocated < n){
-        if (!GrowNamedColorList(v)) return NULL;
+    while (v -> Allocated < n) {
+        if (!GrowNamedColorList(v)) {
+            _cmsFree(ContextID, (void*) v);
+            return NULL;
+        }
     }
 
     strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix)-1);
--- a/src/java.desktop/share/native/liblcms/cmsopt.c	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/share/native/liblcms/cmsopt.c	Fri Oct 20 09:49:02 2017 -0700
@@ -1483,6 +1483,7 @@
 
         // LUT optimizes to nothing. Set the identity LUT
         cmsStageFree(ObtainedCurves);
+        ObtainedCurves = NULL;
 
         if (!cmsPipelineInsertStage(Dest, cmsAT_BEGIN, cmsStageAllocIdentity(Dest ->ContextID, Src ->InputChannels)))
             goto Error;
--- a/src/java.desktop/share/native/liblcms/cmstypes.c	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/share/native/liblcms/cmstypes.c	Fri Oct 20 09:49:02 2017 -0700
@@ -1489,6 +1489,7 @@
 
         // Check for overflow
         if (Offset < (SizeOfHeader + 8)) goto Error;
+        if (((Offset + Len) < Len) || ((Offset + Len) > SizeOfTag + 8)) goto Error;
 
         // True begin of the string
         BeginOfThisString = Offset - SizeOfHeader - 8;
@@ -4460,18 +4461,19 @@
     NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans);
     if (NewLUT == NULL) return NULL;
 
-    if (!_cmsReadUInt32Number(io, &ElementCount)) return NULL;
-
-    if (!ReadPositionTable(self, io, ElementCount, BaseOffset, NewLUT, ReadMPEElem)) {
-        if (NewLUT != NULL) cmsPipelineFree(NewLUT);
-        *nItems = 0;
-        return NULL;
-    }
+    if (!_cmsReadUInt32Number(io, &ElementCount)) goto Error;
+    if (!ReadPositionTable(self, io, ElementCount, BaseOffset, NewLUT, ReadMPEElem)) goto Error;
 
     // Success
     *nItems = 1;
     return NewLUT;
 
+    // Error
+Error:
+    if (NewLUT != NULL) cmsPipelineFree(NewLUT);
+    *nItems = 0;
+    return NULL;
+
     cmsUNUSED_PARAMETER(SizeOfTag);
 }
 
--- a/src/java.desktop/share/native/liblcms/lcms2.h	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/share/native/liblcms/lcms2.h	Fri Oct 20 09:49:02 2017 -0700
@@ -1836,7 +1836,7 @@
 
 // Persistence
 CMSAPI cmsHANDLE        CMSEXPORT cmsIT8LoadFromFile(cmsContext ContextID, const char* cFileName);
-CMSAPI cmsHANDLE        CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, void *Ptr, cmsUInt32Number len);
+CMSAPI cmsHANDLE        CMSEXPORT cmsIT8LoadFromMem(cmsContext ContextID, const void *Ptr, cmsUInt32Number len);
 // CMSAPI cmsHANDLE        CMSEXPORT cmsIT8LoadFromIOhandler(cmsContext ContextID, cmsIOHANDLER* io);
 
 CMSAPI cmsBool          CMSEXPORT cmsIT8SaveToFile(cmsHANDLE hIT8, const char* cFileName);
--- a/src/java.desktop/windows/native/libawt/windows/CmdIDList.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/CmdIDList.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -61,29 +61,36 @@
     m_first_free = first_index; // head of the free list
 }
 
+
+jboolean AwtCmdIDList::isFreeIDAvailable() {
+    CriticalSection::Lock l(m_lock);
+
+    if (m_first_free == -1) {   // out of free ids
+        if (m_capacity == ARRAY_MAXIMUM_SIZE) {
+            return JNI_FALSE;
+        }
+    }
+    return JNI_TRUE;
+}
+
 // Assign an id to the object.  Recycle the first free entry from the
 // head of the free list or allocate more memory for a new free list.
 UINT AwtCmdIDList::Add(AwtObject* obj)
 {
     CriticalSection::Lock l(m_lock);
+    if (!isFreeIDAvailable()) {
+        throw std::bad_alloc(); // fatal error
+    }
 
     if (m_first_free == -1) {   // out of free ids
-        if (m_capacity == ARRAY_MAXIMUM_SIZE) {
-            // Really bad - out of ids.  Since we hardly can have *so*
-            // many items simultaneously in existence, we have an id
-            // leak somewhere.
-            DASSERT(FALSE);
-            return 0;
-        }
-        else {                  // snarf a bigger arena
-            UINT old_capacity = m_capacity; // will be the first free entry
-            m_capacity += ARRAY_SIZE_INCREMENT;
-            if (m_capacity > ARRAY_MAXIMUM_SIZE)
-                m_capacity = ARRAY_MAXIMUM_SIZE;
-            m_array = (CmdIDEntry *)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_array,
-                                        m_capacity, sizeof(CmdIDEntry*));
-            BuildFreeList(old_capacity);
-        }
+        // snarf a bigger arena
+        UINT old_capacity = m_capacity; // will be the first free entry
+        m_capacity += ARRAY_SIZE_INCREMENT;
+        if (m_capacity > ARRAY_MAXIMUM_SIZE)
+            m_capacity = ARRAY_MAXIMUM_SIZE;
+        m_array = (CmdIDEntry *)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_array,
+                                    m_capacity, sizeof(CmdIDEntry*));
+        BuildFreeList(old_capacity);
     }
 
     DASSERT(m_first_free != -1);
--- a/src/java.desktop/windows/native/libawt/windows/CmdIDList.h	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/CmdIDList.h	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -38,6 +38,7 @@
     UINT Add(AwtObject* obj);
     AwtObject* Lookup(UINT id);
     void Remove(UINT id);
+    jboolean isFreeIDAvailable();
 
     CriticalSection    m_lock;
 
--- a/src/java.desktop/windows/native/libawt/windows/awt.h	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt.h	Fri Oct 20 09:49:02 2017 -0700
@@ -57,15 +57,6 @@
     }                                                                     \
 }
 
-#define JNI_CHECK_PEER_GOTO(peer, where) {                                \
-    JNI_CHECK_NULL_GOTO(peer, "peer", where);                             \
-    pData = JNI_GET_PDATA(peer);                                          \
-    if (pData == NULL) {                                                  \
-        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
-        goto where;                                                       \
-    }                                                                     \
-}
-
 #define JNI_CHECK_NULL_RETURN(obj, msg) {                                 \
     if (obj == NULL) {                                                    \
         env->ExceptionClear();                                            \
@@ -74,15 +65,6 @@
     }                                                                     \
 }
 
-#define JNI_CHECK_PEER_RETURN(peer) {                                     \
-    JNI_CHECK_NULL_RETURN(peer, "peer");                                  \
-    pData = JNI_GET_PDATA(peer);                                          \
-    if (pData == NULL) {                                                  \
-        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
-        return;                                                           \
-    }                                                                     \
-}
-
 #define JNI_CHECK_PEER_CREATION_RETURN(peer) {                            \
     if (peer == NULL ) {                                                  \
         return;                                                           \
@@ -109,6 +91,33 @@
     }                                                                     \
 }
 
+/**
+ * This macros must be used under SyncCall or on the Toolkit thread.
+ */
+#define JNI_CHECK_PEER_GOTO(peer, where) {                                \
+    JNI_CHECK_NULL_GOTO(peer, "peer", where);                             \
+    pData = JNI_GET_PDATA(peer);                                          \
+    if (pData == NULL) {                                                  \
+        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
+        goto where;                                                       \
+    }                                                                     \
+}
+
+/**
+ * This macros must be used under SyncCall or on the Toolkit thread.
+ */
+#define JNI_CHECK_PEER_RETURN(peer) {                                     \
+    JNI_CHECK_NULL_RETURN(peer, "peer");                                  \
+    pData = JNI_GET_PDATA(peer);                                          \
+    if (pData == NULL) {                                                  \
+        THROW_NULL_PDATA_IF_NOT_DESTROYED(peer);                          \
+        return;                                                           \
+    }                                                                     \
+}
+
+/**
+ * This macros must be used under SyncCall or on the Toolkit thread.
+ */
 #define JNI_CHECK_PEER_RETURN_NULL(peer) {                                \
     JNI_CHECK_NULL_RETURN_NULL(peer, "peer");                             \
     pData = JNI_GET_PDATA(peer);                                          \
@@ -118,6 +127,9 @@
     }                                                                     \
 }
 
+/**
+ * This macros must be used under SyncCall or on the Toolkit thread.
+ */
 #define JNI_CHECK_PEER_RETURN_VAL(peer, val) {                            \
     JNI_CHECK_NULL_RETURN_VAL(peer, "peer", val);                         \
     pData = JNI_GET_PDATA(peer);                                          \
--- a/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -65,6 +65,7 @@
 /* Create a new AwtButton object and window. */
 AwtButton* AwtButton::Create(jobject self, jobject parent)
 {
+    DASSERT(AwtToolkit::IsMainThread());
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 
     /* the result */
@@ -88,7 +89,6 @@
 
         JNI_CHECK_PEER_GOTO(parent, done);
         awtParent = (AwtCanvas*)pData;
-        JNI_CHECK_NULL_GOTO(awtParent, "awtParent", done);
 
         target = env->GetObjectField(self, AwtObject::targetID);
         JNI_CHECK_NULL_GOTO(target, "target", done);
@@ -375,9 +375,6 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(self);
-
     SetLabelStruct *sls = new SetLabelStruct;
     sls->button = env->NewGlobalRef(self);
     sls->label = (label != NULL) ? (jstring)env->NewGlobalRef(label) : NULL;
@@ -399,14 +396,9 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(parent);
-
     AwtToolkit::CreateComponent(
         self, parent, (AwtToolkit::ComponentFactory)AwtButton::Create);
 
-    JNI_CHECK_PEER_CREATION_RETURN(self);
-
     CATCH_BAD_ALLOC;
 }
 
--- a/src/java.desktop/windows/native/libawt/windows/awt_Canvas.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Canvas.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -59,6 +59,7 @@
  */
 AwtCanvas* AwtCanvas::Create(jobject self, jobject hParent)
 {
+    DASSERT(AwtToolkit::IsMainThread());
     TRY;
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 
@@ -74,12 +75,11 @@
             return NULL;
         }
 
+        PDATA pData;
         AwtComponent* parent;
 
-        JNI_CHECK_NULL_GOTO(hParent, "null hParent", done);
-
-        parent = (AwtComponent*)JNI_GET_PDATA(hParent);
-        JNI_CHECK_NULL_GOTO(parent, "null parent", done);
+        JNI_CHECK_PEER_GOTO(hParent, done);
+        parent = (AwtCanvas*)pData;
 
         target = env->GetObjectField(self, AwtObject::targetID);
         JNI_CHECK_NULL_GOTO(target, "null target", done);
@@ -236,12 +236,9 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(parent);
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtCanvas::Create);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -70,6 +70,7 @@
 
 AwtCheckbox* AwtCheckbox::Create(jobject peer, jobject parent)
 {
+    DASSERT(AwtToolkit::IsMainThread());
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 
     jstring label = NULL;
@@ -81,11 +82,10 @@
             return NULL;
         }
 
+        PDATA pData;
         AwtComponent* awtParent;
-        JNI_CHECK_NULL_GOTO(parent, "null parent", done);
-
-        awtParent = (AwtComponent*)JNI_GET_PDATA(parent);
-        JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
+        JNI_CHECK_PEER_GOTO(parent, done);
+        awtParent = (AwtCanvas*)pData;
 
         target = env->GetObjectField(peer, AwtObject::targetID);
         JNI_CHECK_NULL_GOTO(target, "null target", done);
@@ -669,11 +669,10 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(parent);
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtCheckbox::Create);
+    PDATA pData;
     JNI_CHECK_PEER_CREATION_RETURN(self);
 
 #ifdef DEBUG
--- a/src/java.desktop/windows/native/libawt/windows/awt_Choice.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Choice.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -104,7 +104,7 @@
 }
 
 AwtChoice* AwtChoice::Create(jobject peer, jobject parent) {
-
+    DASSERT(AwtToolkit::IsMainThread());
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 
     jobject target = NULL;
@@ -115,12 +115,10 @@
         if (env->EnsureLocalCapacity(1) < 0) {
             return NULL;
         }
+        PDATA pData;
         AwtCanvas* awtParent;
-
-        JNI_CHECK_NULL_GOTO(parent, "null parent", done);
-
-        awtParent = (AwtCanvas*)JNI_GET_PDATA(parent);
-        JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
+        JNI_CHECK_PEER_GOTO(parent, done);
+        awtParent = (AwtCanvas*)pData;
 
         target = env->GetObjectField(peer, AwtObject::targetID);
         JNI_CHECK_NULL_GOTO(target, "null target", done);
@@ -830,12 +828,9 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(parent);
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtChoice::Create);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -151,6 +151,11 @@
     jobject component;
     jboolean doSetFocus;
 };
+// Struct for _SetParent function
+struct SetParentStruct {
+    jobject component;
+    jobject parentComp;
+};
 /************************************************************************/
 
 //////////////////////////////////////////////////////////////////////////
@@ -269,9 +274,6 @@
 {
     DASSERT(AwtToolkit::IsMainThread());
 
-    /* Disconnect all links. */
-    UnlinkObjects();
-
     /*
      * All the messages for this component are processed, native
      * resources are freed, and Java object is not connected to
@@ -283,6 +285,8 @@
 
 void AwtComponent::Dispose()
 {
+    DASSERT(AwtToolkit::IsMainThread());
+
     // NOTE: in case the component/toplevel was focused, Java should
     // have already taken care of proper transferring it or clearing.
 
@@ -301,8 +305,10 @@
     /* Release global ref to input method */
     SetInputMethod(NULL, TRUE);
 
-    if (m_childList != NULL)
+    if (m_childList != NULL) {
         delete m_childList;
+        m_childList = NULL;
+    }
 
     DestroyDropTarget();
     ReleaseDragCapture(0);
@@ -325,6 +331,9 @@
         m_brushBackground = NULL;
     }
 
+    /* Disconnect all links. */
+    UnlinkObjects();
+
     if (m_bPauseDestroy) {
         // AwtComponent::WmNcDestroy could be released now
         m_bPauseDestroy = FALSE;
@@ -6288,21 +6297,36 @@
     return result;
 }
 
-void AwtComponent::SetParent(void * param) {
+void AwtComponent::_SetParent(void * param)
+{
     if (AwtToolkit::IsMainThread()) {
-        AwtComponent** comps = (AwtComponent**)param;
-        if ((comps[0] != NULL) && (comps[1] != NULL)) {
-            HWND selfWnd = comps[0]->GetHWnd();
-            HWND parentWnd = comps[1]->GetHWnd();
-            if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) {
-                // Shouldn't trigger native focus change
-                // (only the proxy may be the native focus owner).
-                ::SetParent(selfWnd, parentWnd);
-            }
+        JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+        SetParentStruct *data = (SetParentStruct*) param;
+        jobject self = data->component;
+        jobject parent = data->parentComp;
+
+        AwtComponent *awtComponent = NULL;
+        AwtComponent *awtParent = NULL;
+
+        PDATA pData;
+        JNI_CHECK_PEER_GOTO(self, ret);
+        awtComponent = (AwtComponent *)pData;
+        JNI_CHECK_PEER_GOTO(parent, ret);
+        awtParent = (AwtComponent *)pData;
+
+        HWND selfWnd = awtComponent->GetHWnd();
+        HWND parentWnd = awtParent->GetHWnd();
+        if (::IsWindow(selfWnd) && ::IsWindow(parentWnd)) {
+            // Shouldn't trigger native focus change
+            // (only the proxy may be the native focus owner).
+            ::SetParent(selfWnd, parentWnd);
         }
-        delete[] comps;
+ret:
+        env->DeleteGlobalRef(self);
+        env->DeleteGlobalRef(parent);
+        delete data;
     } else {
-        AwtToolkit::GetInstance().InvokeFunction(AwtComponent::SetParent, param);
+        AwtToolkit::GetInstance().InvokeFunction(AwtComponent::_SetParent, param);
     }
 }
 
@@ -7129,15 +7153,12 @@
 Java_sun_awt_windows_WComponentPeer_pSetParent(JNIEnv* env, jobject self, jobject parent) {
     TRY;
 
-    typedef AwtComponent* PComponent;
-    AwtComponent** comps = new PComponent[2];
-    AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(self);
-    AwtComponent* parentComp = (AwtComponent*)JNI_GET_PDATA(parent);
-    comps[0] = comp;
-    comps[1] = parentComp;
-
-    AwtToolkit::GetInstance().SyncCall(AwtComponent::SetParent, comps);
-    // comps is deleted in SetParent
+    SetParentStruct * data = new SetParentStruct;
+    data->component = env->NewGlobalRef(self);
+    data->parentComp = env->NewGlobalRef(parent);
+
+    AwtToolkit::GetInstance().SyncCall(AwtComponent::_SetParent, data);
+    // global refs and data are deleted in SetParent
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.desktop/windows/native/libawt/windows/awt_Component.h	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.h	Fri Oct 20 09:49:02 2017 -0700
@@ -672,6 +672,7 @@
     static void _RemoveNativeDropTarget(void *param);
     static jintArray _CreatePrintedPixels(void *param);
     static jboolean _NativeHandlesWheelScrolling(void *param);
+    static void _SetParent(void * param);
     static void _SetRectangularShape(void *param);
     static void _SetZOrder(void *param);
 
--- a/src/java.desktop/windows/native/libawt/windows/awt_Dialog.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Dialog.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -111,12 +111,13 @@
         PDATA pData;
         AwtWindow* awtParent = NULL;
         HWND hwndParent = NULL;
+
         target = env->GetObjectField(peer, AwtObject::targetID);
         JNI_CHECK_NULL_GOTO(target, "null target", done);
 
         if (parent != NULL) {
             JNI_CHECK_PEER_GOTO(parent, done);
-            awtParent = (AwtWindow *)(JNI_GET_PDATA(parent));
+            awtParent = (AwtWindow *)pData;
             hwndParent = awtParent->GetHWnd();
         } else {
             // There is no way to prevent a parentless dialog from showing on
@@ -775,11 +776,9 @@
 {
     TRY;
 
-    PDATA pData;
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtDialog::Create);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.desktop/windows/native/libawt/windows/awt_FileDialog.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_FileDialog.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -691,7 +691,7 @@
     jobject peerRef = env->NewGlobalRef(peer);
     jobject resultRef = (jobject)AwtToolkit::GetInstance().SyncCall(
         (void*(*)(void*))AwtFileDialog::_GetLocationOnScreen, (void *)peerRef);
-    env->DeleteLocalRef(peerRef);
+    env->DeleteGlobalRef(peerRef);
 
     if (resultRef != NULL)
     {
--- a/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -878,11 +878,16 @@
 
     if (str == NULL) {
         JNU_ThrowNullPointerException(env, "str argument");
-        return NULL;
+        return 0;
     }
-    if ((len < 0) || (off < 0) || (len + off > (env->GetArrayLength(str)))) {
+    if ((len < 0) || (off < 0) || (len + off < 0) ||
+        (len + off > (env->GetArrayLength(str)))) {
         JNU_ThrowArrayIndexOutOfBoundsException(env, "off/len argument");
-        return NULL;
+        return 0;
+    }
+
+    if (off == env->GetArrayLength(str)) {
+        return 0;
     }
 
     jchar *strp = new jchar[len];
@@ -914,12 +919,18 @@
 
     if (str == NULL) {
         JNU_ThrowNullPointerException(env, "bytes argument");
-        return NULL;
+        return 0;
     }
-    if ((len < 0) || (off < 0) || (len + off > (env->GetArrayLength(str)))) {
+    if ((len < 0) || (off < 0) || (len + off < 0) ||
+        (len + off > (env->GetArrayLength(str)))) {
         JNU_ThrowArrayIndexOutOfBoundsException(env, "off or len argument");
-        return NULL;
+        return 0;
     }
+
+    if (off == env->GetArrayLength(str)) {
+        return 0;
+    }
+
     char *pStrBody = NULL;
     jint result = 0;
     try {
@@ -927,12 +938,12 @@
                                                          AwtFont::widthsID);
         if (array == NULL) {
             JNU_ThrowNullPointerException(env, "Can't access widths array.");
-            return NULL;
+            return 0;
         }
         pStrBody = (char *)env->GetPrimitiveArrayCritical(str, 0);
         if (pStrBody == NULL) {
             JNU_ThrowNullPointerException(env, "Can't access str bytes.");
-            return NULL;
+            return 0;
         }
         char *pStr = pStrBody + off;
 
@@ -942,7 +953,7 @@
             if (widths == NULL) {
                 env->ReleasePrimitiveArrayCritical(str, pStrBody, 0);
                 JNU_ThrowNullPointerException(env, "Can't access widths.");
-                return NULL;
+                return 0;
             }
             for (; len; len--) {
                 result += widths[*pStr++];
--- a/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -1580,12 +1580,12 @@
 
     PDATA pData;
 
-    pData = JNI_GET_PDATA(peer);
+    JNI_CHECK_PEER_GOTO(peer, ret);
     AwtFrame *f = (AwtFrame *)pData;
 
     // dialog here may be NULL, for example, if the blocker is a native dialog
     // however, we need to install/unistall modal hooks anyway
-    pData = JNI_GET_PDATA(blockerPeer);
+    JNI_CHECK_PEER_GOTO(blockerPeer, ret);
     AwtDialog *d = (AwtDialog *)pData;
 
     if ((f != NULL) && ::IsWindow(f->GetHWnd()))
@@ -1637,7 +1637,7 @@
             }
         }
     }
-
+ret:
     env->DeleteGlobalRef(self);
     env->DeleteGlobalRef(peer);
     env->DeleteGlobalRef(blockerPeer);
@@ -1809,8 +1809,6 @@
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtFrame::Create);
-    PDATA pData;
-    JNI_CHECK_PEER_CREATION_RETURN(self);
 
     CATCH_BAD_ALLOC;
 }
@@ -1924,8 +1922,6 @@
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtFrame::Create);
-    PDATA pData;
-    JNI_CHECK_PEER_CREATION_RETURN(self);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.desktop/windows/native/libawt/windows/awt_Label.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Label.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -80,7 +80,7 @@
 
         JNI_CHECK_PEER_GOTO(parent, done);
         awtParent = (AwtCanvas*)pData;
-        JNI_CHECK_NULL_GOTO(awtParent, "awtParent", done);
+
         target  = env->GetObjectField(labelPeer, AwtObject::targetID);
         JNI_CHECK_NULL_GOTO(target, "target", done);
 
@@ -392,12 +392,9 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(parent);
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtLabel::Create);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.desktop/windows/native/libawt/windows/awt_List.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_List.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -89,10 +89,9 @@
 
         PDATA pData;
         AwtCanvas* awtParent;
+
         JNI_CHECK_PEER_GOTO(parent, done);
-
         awtParent = (AwtCanvas*)pData;
-        JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
 
         /* target is Hjava_awt_List * */
         target = env->GetObjectField(peer, AwtObject::targetID);
@@ -928,9 +927,6 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(self);
-
     SelectElementStruct *ses = new SelectElementStruct;
     ses->list = env->NewGlobalRef(self);
     ses->index = pos;
@@ -994,11 +990,8 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(parent);
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)AwtList::Create);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -217,6 +217,10 @@
         if (env->EnsureLocalCapacity(1) < 0) {
             return NULL;
         }
+        if (!AwtToolkit::GetInstance().isFreeIDAvailable()) {
+            return NULL;
+        }
+
         JNI_CHECK_NULL_RETURN_NULL(menuPeer, "peer");
 
         /* target is a java.awt.MenuItem  */
--- a/src/java.desktop/windows/native/libawt/windows/awt_ScrollPane.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_ScrollPane.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -96,10 +96,9 @@
 
         PDATA pData;
         AwtComponent* awtParent;
+
         JNI_CHECK_PEER_GOTO(parent, done);
-
         awtParent = (AwtComponent*)pData;
-        JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
 
         target = env->GetObjectField(self, AwtObject::targetID);
         JNI_CHECK_NULL_GOTO(target, "null target", done);
@@ -679,11 +678,10 @@
 
     DTRACE_PRINTLN2("%x: WScrollPanePeer.create(%x)", self, parent);
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(parent);
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtScrollPane::Create);
+    PDATA pData;
     JNI_CHECK_PEER_CREATION_RETURN(self);
     ((AwtScrollPane*)pData)->VerifyState();
 
--- a/src/java.desktop/windows/native/libawt/windows/awt_Scrollbar.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Scrollbar.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -38,7 +38,11 @@
     jint value;
     jint visible;
     jint min, max;
-
+};
+// struct for _SetLineIncrement()/_SetPageIncrement() methods
+struct SetIncrementStruct {
+    jobject scrollbar;
+    jint increment;
 };
 /************************************************************************
  * AwtScrollbar fields
@@ -108,10 +112,9 @@
 
         PDATA pData;
         AwtCanvas* awtParent;
+
         JNI_CHECK_PEER_GOTO(parent, done);
-
         awtParent = (AwtCanvas*)pData;
-        JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
 
         target = env->GetObjectField(peer, AwtObject::targetID);
         JNI_CHECK_NULL_GOTO(target, "null target", done);
@@ -471,6 +474,52 @@
     delete svs;
 }
 
+void AwtScrollbar::_SetLineIncrement(void *param)
+{
+    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+    SetIncrementStruct *sis = (SetIncrementStruct *)param;
+    jobject self = sis->scrollbar;
+    jint increment = sis->increment;
+
+    AwtScrollbar *sb = NULL;
+
+    PDATA pData;
+    JNI_CHECK_PEER_GOTO(self, ret);
+    sb = (AwtScrollbar *)pData;
+    if (::IsWindow(sb->GetHWnd()))
+    {
+        sb->SetLineIncrement(increment);
+    }
+ret:
+    env->DeleteGlobalRef(self);
+
+    delete sis;
+}
+
+void AwtScrollbar::_SetPageIncrement(void *param)
+{
+    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+    SetIncrementStruct *sis = (SetIncrementStruct *)param;
+    jobject self = sis->scrollbar;
+    jint increment = sis->increment;
+
+    AwtScrollbar *sb = NULL;
+
+    PDATA pData;
+    JNI_CHECK_PEER_GOTO(self, ret);
+    sb = (AwtScrollbar *)pData;
+    if (::IsWindow(sb->GetHWnd()))
+    {
+        sb->SetPageIncrement(increment);
+    }
+ret:
+    env->DeleteGlobalRef(self);
+
+    delete sis;
+}
+
 /************************************************************************
  * Scrollbar native methods
  */
@@ -546,10 +595,12 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(self);
-    AwtScrollbar* c = (AwtScrollbar*)pData;
-    c->SetLineIncrement(increment);
+    SetIncrementStruct *sis = new SetIncrementStruct;
+    sis->scrollbar = env->NewGlobalRef(self);
+    sis->increment = increment;
+
+    AwtToolkit::GetInstance().SyncCall(AwtScrollbar::_SetLineIncrement, sis);
+    // global ref and svs are deleted in _SetValues
 
     CATCH_BAD_ALLOC;
 }
@@ -565,10 +616,12 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(self);
-    AwtScrollbar* c = (AwtScrollbar*)pData;
-    c->SetPageIncrement(increment);
+    SetIncrementStruct *sis = new SetIncrementStruct;
+    sis->scrollbar = env->NewGlobalRef(self);
+    sis->increment = increment;
+
+    AwtToolkit::GetInstance().SyncCall(AwtScrollbar::_SetPageIncrement, sis);
+    // global ref and svs are deleted in _SetValues
 
     CATCH_BAD_ALLOC;
 }
@@ -584,12 +637,9 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(parent);
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtScrollbar::Create);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.desktop/windows/native/libawt/windows/awt_Scrollbar.h	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Scrollbar.h	Fri Oct 20 09:49:02 2017 -0700
@@ -77,6 +77,8 @@
 
     INLINE virtual BOOL IsScrollbar() { return TRUE; }
 
+    static void _SetLineIncrement(void *param);
+    static void _SetPageIncrement(void *param);
     // invoked on Toolkit thread
     static void _SetValues(void *param);
 
--- a/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -505,12 +505,9 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(parent);
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtTextArea::Create);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -95,10 +95,9 @@
 
         PDATA pData;
         AwtCanvas* awtParent;
+
         JNI_CHECK_PEER_GOTO(parent, done);
-
         awtParent = (AwtCanvas*)pData;
-        JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
 
         target = env->GetObjectField(peer, AwtObject::targetID);
         JNI_CHECK_NULL_GOTO(target, "null target", done);
--- a/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -260,12 +260,9 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(parent);
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtTextField::Create);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -1869,6 +1869,11 @@
     }
 }
 
+jboolean AwtToolkit::isFreeIDAvailable()
+{
+    return m_cmdIDs->isFreeIDAvailable();
+}
+
 UINT AwtToolkit::CreateCmdID(AwtObject* object)
 {
     return m_cmdIDs->Add(object);
--- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -373,6 +373,8 @@
     BOOL PreProcessMouseMsg(class AwtComponent* p, MSG& msg);
     BOOL PreProcessKeyMsg(class AwtComponent* p, MSG& msg);
 
+    /* Checks that an free ID exists. */
+    jboolean isFreeIDAvailable();
     /* Create an ID which maps to an AwtObject pointer, such as a menu. */
     UINT CreateCmdID(AwtObject* object);
 
--- a/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp	Fri Oct 20 09:49:02 2017 -0700
@@ -3400,12 +3400,9 @@
 {
     TRY;
 
-    PDATA pData;
-//    JNI_CHECK_PEER_RETURN(parent);
     AwtToolkit::CreateComponent(self, parent,
                                 (AwtToolkit::ComponentFactory)
                                 AwtWindow::Create);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/RMIExporter.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/RMIExporter.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 
 package com.sun.jmx.remote.internal.rmi;
 
+import java.io.ObjectInputFilter;
 import java.rmi.NoSuchObjectException;
 import java.rmi.Remote;
 import java.rmi.RemoteException;
@@ -51,7 +52,8 @@
     public Remote exportObject(Remote obj,
                                int port,
                                RMIClientSocketFactory csf,
-                               RMIServerSocketFactory ssf)
+                               RMIServerSocketFactory ssf,
+                               ObjectInputFilter filter)
             throws RemoteException;
 
     public boolean unexportObject(Remote obj, boolean force)
--- a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Fri Oct 20 09:49:02 2017 -0700
@@ -32,6 +32,7 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.ObjectInputFilter;
 import java.io.ObjectOutputStream;
 import java.net.MalformedURLException;
 import java.rmi.server.RMIClientSocketFactory;
@@ -101,19 +102,59 @@
         "jmx.remote.rmi.server.socket.factory";
 
     /**
-    * Name of the attribute that specifies a list of class names acceptable
-    * as parameters to the {@link RMIServer#newClient(java.lang.Object) RMIServer.newClient()}
+    * Name of the attribute that specifies an
+    * {@link ObjectInputFilter} pattern string to filter classes acceptable
+    * for {@link RMIServer#newClient(java.lang.Object) RMIServer.newClient()}
     * remote method call.
     * <p>
-    * This list of classes should correspond to the transitive closure of the
-    * credentials class (or classes) used by the installed {@linkplain JMXAuthenticator}
-    * associated with the {@linkplain RMIServer} implementation.
+    * The filter pattern must be in same format as used in
+    * {@link java.io.ObjectInputFilter.Config#createFilter}
     * <p>
-    * If the attribute is not set, or is null, then any class is
-    * deemed acceptable.
+    * This list of classes allowed by filter should correspond to the
+    * transitive closure of the credentials class (or classes) used by the
+    * installed {@linkplain JMXAuthenticator} associated with the
+    * {@linkplain RMIServer} implementation.
+    * If the attribute is not set then any class is deemed acceptable.
+    * @see ObjectInputFilter
     */
-    public static final String CREDENTIAL_TYPES =
-            "jmx.remote.rmi.server.credential.types";
+    public static final String CREDENTIALS_FILTER_PATTERN =
+        "jmx.remote.rmi.server.credentials.filter.pattern";
+
+    /**
+     * This attribute defines a pattern from which to create a
+     * {@link java.io.ObjectInputFilter} that will be used when deserializing
+     * objects sent to the {@code JMXConnectorServer} by any client.
+     * <p>
+     * The filter will be called for any class found in the serialized
+     * stream sent to server by client, including all JMX defined classes
+     * (such as {@link javax.management.ObjectName}), all method parameters,
+     * and, if present in the stream, all classes transitively referred by
+     * the serial form of any deserialized object.
+     * The pattern must be in same format as used in
+     * {@link java.io.ObjectInputFilter.Config#createFilter}.
+     * It may define a white list of permitted classes, a black list of
+     * rejected classes, a maximum depth for the deserialized objects,
+     * etc.
+     * <p>
+     * To be functional, the filter should allow at least all the
+     * concrete types in the transitive closure of all objects that
+     * might get serialized when serializing all JMX classes referred
+     * as parameters in the {@link
+     * javax.management.remote.rmi.RMIConnection} interface,
+     * plus all classes that a {@link javax.management.remote.rmi.RMIConnector client}
+     * might need to transmit wrapped in {@linkplain java.rmi.MarshalledObject
+     * marshalled objects} in order to interoperate with the MBeans registered
+     * in the {@code MBeanServer}. That would potentially include all the
+     * concrete {@linkplain javax.management.openmbean  JMX OpenTypes} and the
+     * classes they use in their serial form.
+     * <p>
+     * Care must be taken when defining such a filter, as defining
+     * a white list too restrictive or a too wide a black list may
+     * prevent legitimate clients from interoperating with the
+     * {@code JMXConnectorServer}.
+     */
+    public static final String SERIAL_FILTER_PATTERN =
+       "jmx.remote.rmi.server.serial.filter.pattern";
 
     /**
      * <p>Makes an <code>RMIConnectorServer</code>.
--- a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java	Fri Oct 20 09:49:02 2017 -0700
@@ -26,6 +26,7 @@
 package javax.management.remote.rmi;
 
 import java.io.IOException;
+import java.io.ObjectInputFilter;
 import java.rmi.NoSuchObjectException;
 import java.rmi.Remote;
 import java.rmi.RemoteException;
@@ -39,15 +40,13 @@
 
 import com.sun.jmx.remote.internal.rmi.RMIExporter;
 import com.sun.jmx.remote.util.EnvHelp;
-import java.io.ObjectStreamClass;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 import sun.reflect.misc.ReflectUtil;
-import sun.rmi.server.DeserializationChecker;
 import sun.rmi.server.UnicastServerRef;
 import sun.rmi.server.UnicastServerRef2;
+import sun.rmi.transport.LiveRef;
 
 /**
  * <p>An {@link RMIServer} object that is exported through JRMP and that
@@ -60,8 +59,6 @@
  */
 public class RMIJRMPServerImpl extends RMIServerImpl {
 
-    private final ExportedWrapper exportedWrapper;
-
     /**
      * <p>Creates a new {@link RMIServer} object that will be exported
      * on the given port using the given socket factories.</p>
@@ -100,33 +97,48 @@
         this.ssf = ssf;
         this.env = (env == null) ? Collections.<String, Object>emptyMap() : env;
 
+        // This attribute was represented by RMIConnectorServer.CREDENTIALS_TYPES.
+        // This attribute is superceded by
+        // RMIConnectorServer.CREDENTIALS_FILTER_PATTERN.
+        // Retaining this for backward compatibility.
         String[] credentialsTypes
-                = (String[]) this.env.get(RMIConnectorServer.CREDENTIAL_TYPES);
-        List<String> types = null;
-        if (credentialsTypes != null) {
-            types = new ArrayList<>();
-            for (String type : credentialsTypes) {
-                if (type == null) {
-                    throw new IllegalArgumentException("A credential type is null.");
-                }
-                ReflectUtil.checkPackageAccess(type);
-                types.add(type);
-            }
+                = (String[]) this.env.get("jmx.remote.rmi.server.credential.types");
+
+        String credentialsFilter
+                = (String) this.env.get(RMIConnectorServer.CREDENTIALS_FILTER_PATTERN);
+
+        // It is impossible for both attributes to be specified
+        if(credentialsTypes != null && credentialsFilter != null)
+            throw new IllegalArgumentException("Cannot specify both \""
+                    + "jmx.remote.rmi.server.credential.types" + "\" and \""
+           + RMIConnectorServer.CREDENTIALS_FILTER_PATTERN + "\"");
+        else if(credentialsFilter != null){
+            cFilter = ObjectInputFilter.Config.createFilter(credentialsFilter);
+            allowedTypes = null;
         }
-        exportedWrapper = types != null ?
-                new ExportedWrapper(this, types) :
-                null;
+        else if (credentialsTypes != null) {
+            allowedTypes = Arrays.stream(credentialsTypes).filter(
+                    s -> s!= null).collect(Collectors.toSet());
+            allowedTypes.stream().forEach(ReflectUtil::checkPackageAccess);
+            cFilter = this::newClientCheckInput;
+        } else {
+            allowedTypes = null;
+            cFilter = null;
+        }
+
+        String userJmxFilter =
+                (String) this.env.get(RMIConnectorServer.SERIAL_FILTER_PATTERN);
+        if(userJmxFilter != null && !userJmxFilter.isEmpty())
+            jmxRmiFilter = ObjectInputFilter.Config.createFilter(userJmxFilter);
+        else
+            jmxRmiFilter = null;
     }
 
     protected void export() throws IOException {
-        if (exportedWrapper != null) {
-            export(exportedWrapper);
-        } else {
-            export(this);
-        }
+        export(this, cFilter);
     }
 
-    private void export(Remote obj) throws RemoteException {
+    private void export(Remote obj, ObjectInputFilter typeFilter) throws RemoteException {
         final RMIExporter exporter =
             (RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE);
         final boolean daemon = EnvHelp.isServerDaemon(env);
@@ -137,16 +149,14 @@
                     " cannot be used to specify an exporter!");
         }
 
-        if (daemon) {
+        if (exporter != null) {
+            exporter.exportObject(obj, port, csf, ssf, typeFilter);
+        } else {
             if (csf == null && ssf == null) {
-                new UnicastServerRef(port).exportObject(obj, null, true);
+                new UnicastServerRef(new LiveRef(port), typeFilter).exportObject(obj, null, daemon);
             } else {
-                new UnicastServerRef2(port, csf, ssf).exportObject(obj, null, true);
+                new UnicastServerRef2(port, csf, ssf, typeFilter).exportObject(obj, null, daemon);
             }
-        } else if (exporter != null) {
-            exporter.exportObject(obj, port, csf, ssf);
-        } else {
-            UnicastRemoteObject.exportObject(obj, port, csf, ssf);
         }
     }
 
@@ -173,11 +183,7 @@
      *            RMIJRMPServerImpl has not been exported yet.
      */
     public Remote toStub() throws IOException {
-        if (exportedWrapper != null) {
-            return RemoteObject.toStub(exportedWrapper);
-        } else {
-            return RemoteObject.toStub(this);
-        }
+        return RemoteObject.toStub(this);
     }
 
     /**
@@ -207,7 +213,7 @@
         RMIConnection client =
             new RMIConnectionImpl(this, connectionId, getDefaultClassLoader(),
                                   subject, env);
-        export(client);
+        export(client, jmxRmiFilter);
         return client;
     }
 
@@ -224,56 +230,39 @@
      * server failed.
      */
     protected void closeServer() throws IOException {
-        if (exportedWrapper != null) {
-            unexport(exportedWrapper, true);
-        } else {
-            unexport(this, true);
+        unexport(this, true);
+    }
+
+    /**
+     * Check that a type in the remote invocation of {@link RMIServerImpl#newClient}
+     * is one of the {@code allowedTypes}.
+     *
+     * @param clazz       the class; may be null
+     * @param size        the size for arrays, otherwise is 0
+     * @param nObjectRefs the current number of object references
+     * @param depth       the current depth
+     * @param streamBytes the current number of bytes consumed
+     * @return {@code ObjectInputFilter.Status.ALLOWED} if the class is allowed,
+     *          otherwise {@code ObjectInputFilter.Status.REJECTED}
+     */
+    ObjectInputFilter.Status newClientCheckInput(ObjectInputFilter.FilterInfo filterInfo) {
+        ObjectInputFilter.Status status = ObjectInputFilter.Status.UNDECIDED;
+        if (allowedTypes != null && filterInfo.serialClass() != null) {
+            // If enabled, check type
+            String type = filterInfo.serialClass().getName();
+            if (allowedTypes.contains(type))
+                status = ObjectInputFilter.Status.ALLOWED;
+            else
+                status = ObjectInputFilter.Status.REJECTED;
         }
+        return status;
     }
 
     private final int port;
     private final RMIClientSocketFactory csf;
     private final RMIServerSocketFactory ssf;
     private final Map<String, ?> env;
-
-    private static class ExportedWrapper implements RMIServer, DeserializationChecker {
-        private final RMIServer impl;
-        private final List<String> allowedTypes;
-
-        private ExportedWrapper(RMIServer impl, List<String> credentialsTypes) {
-            this.impl = impl;
-            allowedTypes = credentialsTypes;
-        }
-
-        @Override
-        public String getVersion() throws RemoteException {
-            return impl.getVersion();
-        }
-
-        @Override
-        public RMIConnection newClient(Object credentials) throws IOException {
-            return impl.newClient(credentials);
-        }
-
-        @Override
-        public void check(Method method, ObjectStreamClass descriptor,
-                int paramIndex, int callID) {
-            String type = descriptor.getName();
-            if (!allowedTypes.contains(type)) {
-                throw new ClassCastException("Unsupported type: " + type);
-            }
-        }
-
-        @Override
-        public void checkProxyClass(Method method, String[] ifaces,
-                int paramIndex, int callID) {
-            if (ifaces != null && ifaces.length > 0) {
-                for (String iface : ifaces) {
-                    if (!allowedTypes.contains(iface)) {
-                        throw new ClassCastException("Unsupported type: " + iface);
-                    }
-                }
-            }
-        }
-    }
+    private final Set<String> allowedTypes;
+    private final ObjectInputFilter jmxRmiFilter;
+    private final ObjectInputFilter cFilter;
 }
--- a/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java	Fri Oct 20 09:49:02 2017 -0700
@@ -35,8 +35,6 @@
 import java.security.Permission;
 import java.rmi.server.RMIClassLoader;
 import java.security.PrivilegedAction;
-import jdk.internal.misc.ObjectStreamClassValidator;
-import jdk.internal.misc.SharedSecrets;
 
 /**
  * MarshalInputStream is an extension of ObjectInputStream.  When resolving
@@ -54,11 +52,6 @@
  * @author      Peter Jones
  */
 public class MarshalInputStream extends ObjectInputStream {
-    interface StreamChecker extends ObjectStreamClassValidator {
-        void checkProxyInterfaceNames(String[] ifaces);
-    }
-
-    private volatile StreamChecker streamChecker = null;
 
     /**
      * Value of "java.rmi.server.useCodebaseOnly" property,
@@ -245,11 +238,6 @@
     protected Class<?> resolveProxyClass(String[] interfaces)
         throws IOException, ClassNotFoundException
     {
-        StreamChecker checker = streamChecker;
-        if (checker != null) {
-            checker.checkProxyInterfaceNames(interfaces);
-        }
-
         /*
          * Always read annotation written by MarshalOutputStream.
          */
@@ -330,28 +318,4 @@
     void useCodebaseOnly() {
         useCodebaseOnly = true;
     }
-
-    synchronized void setStreamChecker(StreamChecker checker) {
-        streamChecker = checker;
-        SharedSecrets.getJavaObjectInputStreamAccess().setValidator(this, checker);
-    }
-    @Override
-    protected ObjectStreamClass readClassDescriptor() throws IOException,
-            ClassNotFoundException {
-        ObjectStreamClass descriptor = super.readClassDescriptor();
-
-        validateDesc(descriptor);
-
-        return descriptor;
-    }
-
-    private void validateDesc(ObjectStreamClass descriptor) {
-        StreamChecker checker;
-        synchronized (this) {
-            checker = streamChecker;
-        }
-        if (checker != null) {
-            checker.validateDescriptor(descriptor);
-        }
-    }
 }
--- a/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java	Fri Oct 20 09:49:02 2017 -0700
@@ -30,7 +30,6 @@
 import java.io.ObjectInputFilter;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutput;
-import java.io.ObjectStreamClass;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.rmi.AccessException;
@@ -330,11 +329,16 @@
             logCall(obj, method);
 
             // unmarshal parameters
-            Object[] params = null;
+            Class<?>[] types = method.getParameterTypes();
+            Object[] params = new Object[types.length];
 
             try {
                 unmarshalCustomCallData(in);
-                params = unmarshalParameters(obj, method, marshalStream);
+                // Unmarshal the parameters
+                for (int i = 0; i < types.length; i++) {
+                    params[i] = unmarshalValue(types[i], in);
+                }
+
             } catch (AccessException aex) {
                 // For compatibility, AccessException is not wrapped in UnmarshalException
                 // disable saving any refs in the inputStream for GC
@@ -600,84 +604,4 @@
         }
     }
 
-    /**
-     * Unmarshal parameters for the given method of the given instance over
-     * the given marshalinputstream. Perform any necessary checks.
-     */
-    private Object[] unmarshalParameters(Object obj, Method method, MarshalInputStream in)
-    throws IOException, ClassNotFoundException {
-        return (obj instanceof DeserializationChecker) ?
-            unmarshalParametersChecked((DeserializationChecker)obj, method, in) :
-            unmarshalParametersUnchecked(method, in);
-    }
-
-    /**
-     * Unmarshal parameters for the given method of the given instance over
-     * the given marshalinputstream. Do not perform any additional checks.
-     */
-    private Object[] unmarshalParametersUnchecked(Method method, ObjectInput in)
-    throws IOException, ClassNotFoundException {
-        Class<?>[] types = method.getParameterTypes();
-        Object[] params = new Object[types.length];
-        for (int i = 0; i < types.length; i++) {
-            params[i] = unmarshalValue(types[i], in);
-        }
-        return params;
-    }
-
-    /**
-     * Unmarshal parameters for the given method of the given instance over
-     * the given marshalinputstream. Do perform all additional checks.
-     */
-    private Object[] unmarshalParametersChecked(
-        DeserializationChecker checker,
-        Method method, MarshalInputStream in)
-    throws IOException, ClassNotFoundException {
-        int callID = methodCallIDCount.getAndIncrement();
-        MyChecker myChecker = new MyChecker(checker, method, callID);
-        in.setStreamChecker(myChecker);
-        try {
-            Class<?>[] types = method.getParameterTypes();
-            Object[] values = new Object[types.length];
-            for (int i = 0; i < types.length; i++) {
-                myChecker.setIndex(i);
-                values[i] = unmarshalValue(types[i], in);
-            }
-            myChecker.end(callID);
-            return values;
-        } finally {
-            in.setStreamChecker(null);
-        }
-    }
-
-    private static class MyChecker implements MarshalInputStream.StreamChecker {
-        private final DeserializationChecker descriptorCheck;
-        private final Method method;
-        private final int callID;
-        private int parameterIndex;
-
-        MyChecker(DeserializationChecker descriptorCheck, Method method, int callID) {
-            this.descriptorCheck = descriptorCheck;
-            this.method = method;
-            this.callID = callID;
-        }
-
-        @Override
-        public void validateDescriptor(ObjectStreamClass descriptor) {
-            descriptorCheck.check(method, descriptor, parameterIndex, callID);
-        }
-
-        @Override
-        public void checkProxyInterfaceNames(String[] ifaces) {
-            descriptorCheck.checkProxyClass(method, ifaces, parameterIndex, callID);
-        }
-
-        void setIndex(int parameterIndex) {
-            this.parameterIndex = parameterIndex;
-        }
-
-        void end(int callId) {
-            descriptorCheck.end(callId);
-        }
-    }
 }
--- a/src/java.rmi/share/classes/sun/rmi/transport/Target.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.rmi/share/classes/sun/rmi/transport/Target.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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,6 +31,7 @@
 import java.rmi.server.Unreferenced;
 import java.security.AccessControlContext;
 import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.*;
 import sun.rmi.runtime.Log;
 import sun.rmi.runtime.NewThreadAction;
@@ -322,27 +323,15 @@
             Remote obj = getImpl();
             if (obj instanceof Unreferenced) {
                 final Unreferenced unrefObj = (Unreferenced) obj;
-                final Thread t =
-                    java.security.AccessController.doPrivileged(
-                        new NewThreadAction(new Runnable() {
-                            public void run() {
-                                unrefObj.unreferenced();
-                            }
-                        }, "Unreferenced-" + nextThreadNum++, false, true));
-                // REMIND: access to nextThreadNum not synchronized; you care?
-                /*
-                 * We must manually set the context class loader appropriately
-                 * for threads that may invoke user code (see bugid 4171278).
-                 */
-                java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction<Void>() {
-                        public Void run() {
-                        t.setContextClassLoader(ccl);
-                        return null;
-                    }
-                });
-
-                t.start();
+                AccessController.doPrivileged(
+                    new NewThreadAction(() -> {
+                        Thread.currentThread().setContextClassLoader(ccl);
+                        AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                            unrefObj.unreferenced();
+                            return null;
+                        }, acc);
+                    }, "Unreferenced-" + nextThreadNum++, false, true)).start();
+                    // REMIND: access to nextThreadNum not synchronized; you care?
             }
 
             unpinImpl();
--- a/src/java.smartcardio/share/classes/sun/security/smartcardio/CardImpl.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.smartcardio/share/classes/sun/security/smartcardio/CardImpl.java	Fri Oct 20 09:49:02 2017 -0700
@@ -270,7 +270,7 @@
     }
 
     public String toString() {
-        return "PC/SC card in " + terminal.getName()
+        return "PC/SC card in " + terminal.name
             + ", protocol " + getProtocol() + ", state " + state;
     }
 
@@ -278,6 +278,7 @@
     protected void finalize() throws Throwable {
         try {
             if (state == State.OK) {
+                state = State.DISCONNECTED;
                 SCardDisconnect(cardId, SCARD_LEAVE_CARD);
             }
         } finally {
--- a/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/exception/JAXWSExceptionBase.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/util/exception/JAXWSExceptionBase.java	Fri Oct 20 09:49:02 2017 -0700
@@ -34,6 +34,8 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 import java.util.ResourceBundle;
 import javax.xml.ws.WebServiceException;
@@ -122,13 +124,21 @@
         String resourceBundleName = (String) in.readObject();
         String key = (String) in.readObject();
         int len = in.readInt();
-        if (len == -1) {
+        if (len < -1) {
+            throw new NegativeArraySizeException();
+        } else if (len == -1) {
             args = null;
-        } else {
+        } else if (len < 255) {
             args = new Object[len];
             for (int i = 0; i < args.length; i++) {
                 args[i] = in.readObject();
             }
+        } else {
+            List<Object> argList = new ArrayList<>(Math.min(len, 1024));
+            for (int i = 0; i < len; i++) {
+                argList.add(in.readObject());
+            }
+            args = argList.toArray(new Object[argList.size()]);
         }
         msg = new LocalizableMessageFactory(resourceBundleName).getMessage(key,args);
     }
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/PredicatedNodeTest.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/PredicatedNodeTest.java	Fri Oct 20 09:49:02 2017 -0700
@@ -71,6 +71,14 @@
     {
       stream.defaultReadObject();
       m_predicateIndex = -1;
+
+      /**
+       * Initialize to the declared value.
+       * As noted at declaration, this variable is used only for clones for getLastPos,
+       * it should have been excluded from serialization. For compatibility, we'll
+       * keep it as is but initializing to the declared value.
+       */
+      m_predCount = -1;
       resetProximityPositions();
     }
     catch (ClassNotFoundException cnfe)
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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,11 +33,13 @@
 import javax.crypto.spec.DHParameterSpec;
 
 import sun.security.provider.ParameterCache;
+import static sun.security.util.SecurityProviderConstants.*;
 
 import static sun.security.pkcs11.TemplateManager.*;
 import sun.security.pkcs11.wrapper.*;
 import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
 
+
 import sun.security.rsa.RSAKeyFactory;
 
 /**
@@ -98,7 +100,7 @@
         // override lower limit to disallow unsecure keys being generated
         // override upper limit to deter DOS attack
         if (algorithm.equals("EC")) {
-            keySize = 256;
+            keySize = DEF_EC_KEY_SIZE;
             if ((minKeyLen == -1) || (minKeyLen < 112)) {
                 minKeyLen = 112;
             }
@@ -107,13 +109,11 @@
             }
         } else {
             if (algorithm.equals("DSA")) {
-                // keep default keysize at 1024 since larger keysizes may be
-                // incompatible with SHA1withDSA and SHA-2 Signature algs
-                // may not be supported by native pkcs11 implementations
-                keySize = 1024;
+                keySize = DEF_DSA_KEY_SIZE;
+            } else if (algorithm.equals("RSA")) {
+                keySize = DEF_RSA_KEY_SIZE;
             } else {
-                // RSA and DH
-                keySize = 2048;
+                keySize = DEF_DH_KEY_SIZE;
             }
             if ((minKeyLen == -1) || (minKeyLen < 512)) {
                 minKeyLen = 512;
--- a/src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyPairGenerator.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ECKeyPairGenerator.java	Fri Oct 20 09:49:02 2017 -0700
@@ -39,6 +39,7 @@
 import sun.security.jca.JCAUtil;
 import sun.security.util.ECParameters;
 import sun.security.util.ECUtil;
+import static sun.security.util.SecurityProviderConstants.DEF_EC_KEY_SIZE;
 
 /**
  * EC keypair generator.
@@ -50,7 +51,6 @@
 
     private static final int KEY_SIZE_MIN = 112; // min bits (see ecc_impl.h)
     private static final int KEY_SIZE_MAX = 571; // max bits (see ecc_impl.h)
-    private static final int KEY_SIZE_DEFAULT = 256;
 
     // used to seed the keypair generator
     private SecureRandom random;
@@ -66,7 +66,7 @@
      */
     public ECKeyPairGenerator() {
         // initialize to default in case the app does not call initialize()
-        initialize(KEY_SIZE_DEFAULT, null);
+        initialize(DEF_EC_KEY_SIZE, null);
     }
 
     // initialize the generator. See JCA doc
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSAKeyPairGenerator.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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,6 +31,7 @@
 import java.security.spec.RSAKeyGenParameterSpec;
 
 import sun.security.rsa.RSAKeyFactory;
+import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE;
 
 /**
  * RSA keypair generator.
@@ -45,14 +46,13 @@
     // Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers
     static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384
     static final int KEY_SIZE_MAX = 16384;
-    private static final int KEY_SIZE_DEFAULT = 2048;
 
     // size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX
     private int keySize;
 
     public RSAKeyPairGenerator() {
         // initialize to default in case the app does not call initialize()
-        initialize(KEY_SIZE_DEFAULT, null);
+        initialize(DEF_RSA_KEY_SIZE, null);
     }
 
     // initialize the generator. See JCA doc
@@ -76,7 +76,7 @@
 
         int tmpSize;
         if (params == null) {
-            tmpSize = KEY_SIZE_DEFAULT;
+            tmpSize = DEF_RSA_KEY_SIZE;
         } else if (params instanceof RSAKeyGenParameterSpec) {
 
             if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) {
--- a/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.Serializable;
+import java.io.ObjectInputFilter;
 import java.lang.management.ManagementFactory;
 import java.net.InetAddress;
 import java.net.MalformedURLException;
@@ -45,14 +45,12 @@
 import java.rmi.registry.Registry;
 import java.rmi.server.RMIClientSocketFactory;
 import java.rmi.server.RMIServerSocketFactory;
-import java.rmi.server.RMISocketFactory;
 import java.rmi.server.RemoteObject;
 import java.rmi.server.UnicastRemoteObject;
 import java.security.KeyStore;
 import java.security.Principal;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
@@ -84,6 +82,7 @@
 import sun.rmi.server.UnicastRef;
 import sun.rmi.server.UnicastServerRef;
 import sun.rmi.server.UnicastServerRef2;
+import sun.rmi.transport.LiveRef;
 
 /**
  * This class initializes and starts the RMIConnectorServer for JSR 163
@@ -142,6 +141,8 @@
                 "com.sun.management.jmxremote.ssl.need.client.auth";
         public static final String SSL_CONFIG_FILE_NAME =
                 "com.sun.management.jmxremote.ssl.config.file";
+        public static final String SERIAL_FILTER_PATTERN =
+                "com.sun.management.jmxremote.serial.filter.pattern";
     }
 
     /**
@@ -182,7 +183,8 @@
         public Remote exportObject(Remote obj,
                 int port,
                 RMIClientSocketFactory csf,
-                RMIServerSocketFactory ssf)
+                RMIServerSocketFactory ssf,
+                ObjectInputFilter filter)
                 throws RemoteException {
 
             synchronized (this) {
@@ -193,9 +195,9 @@
 
             final UnicastServerRef ref;
             if (csf == null && ssf == null) {
-                ref = new UnicastServerRef(port);
+                ref = new UnicastServerRef(new LiveRef(port), filter);
             } else {
-                ref = new UnicastServerRef2(port, csf, ssf);
+                ref = new UnicastServerRef2(port, csf, ssf, filter);
             }
             return ref.exportObject(obj, null, true);
         }
@@ -435,6 +437,7 @@
 
         final String bindAddress =
                 props.getProperty(PropertyNames.HOST);
+        final String jmxRmiFilter = props.getProperty(PropertyNames.SERIAL_FILTER_PATTERN);
 
         if (logger.isLoggable(Level.DEBUG)) {
             logger.log(Level.DEBUG, "startRemoteConnectorServer",
@@ -471,7 +474,7 @@
                     sslConfigFileName, enabledCipherSuitesList,
                     enabledProtocolsList, sslNeedClientAuth,
                     useAuthentication, loginConfigName,
-                    passwordFileName, accessFileName, bindAddress);
+                    passwordFileName, accessFileName, bindAddress, jmxRmiFilter);
             cs = data.jmxConnectorServer;
             url = data.jmxRemoteURL;
             config("startRemoteConnectorServer",
@@ -511,9 +514,7 @@
         // This RMI server should not keep the VM alive
         Map<String, Object> env = new HashMap<>();
         env.put(RMIExporter.EXPORTER_ATTRIBUTE, new PermanentExporter());
-        env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
-            String[].class.getName(), String.class.getName()
-        });
+        env.put(RMIConnectorServer.CREDENTIALS_FILTER_PATTERN, String.class.getName() + ";!*");
 
         // The local connector server need only be available via the
         // loopback connection.
@@ -729,7 +730,8 @@
             String loginConfigName,
             String passwordFileName,
             String accessFileName,
-            String bindAddress)
+            String bindAddress,
+            String jmxRmiFilter)
             throws IOException, MalformedURLException {
 
         /* Make sure we use non-guessable RMI object IDs.  Otherwise
@@ -744,9 +746,11 @@
         PermanentExporter exporter = new PermanentExporter();
 
         env.put(RMIExporter.EXPORTER_ATTRIBUTE, exporter);
-        env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
-            String[].class.getName(), String.class.getName()
-        });
+        env.put(RMIConnectorServer.CREDENTIALS_FILTER_PATTERN, String.class.getName() + ";!*");
+
+        if(jmxRmiFilter != null && !jmxRmiFilter.isEmpty()) {
+            env.put(RMIConnectorServer.SERIAL_FILTER_PATTERN, jmxRmiFilter);
+        }
 
         boolean useSocketFactory = bindAddress != null && !useSsl;
 
--- a/src/jdk.management.agent/share/conf/management.properties	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/jdk.management.agent/share/conf/management.properties	Fri Oct 20 09:49:02 2017 -0700
@@ -329,3 +329,42 @@
 #      The format of the value for that property is any string accepted
 #      by java.net.InetAddress.getByName(String).
 #
+
+# ################ Filter for ObjectInputStream #############################
+# com.sun.management.jmxremote.serial.filter.pattern=<filter-string>
+#   A filter, if configured, is used by java.io.ObjectInputStream during
+#   deserialization of parameters sent to the JMX default agent to validate the 
+#   contents of the stream.
+#   A filter is configured as a sequence of patterns, each pattern is either
+#   matched against the name of a class in the stream or defines a limit.
+#   Patterns are separated by ";" (semicolon).
+#   Whitespace is significant and is considered part of the pattern.
+#
+#   If a pattern includes a "=", it sets a limit.
+#   If a limit appears more than once the last value is used.
+#   Limits are checked before classes regardless of the order in the sequence of patterns.
+#   If any of the limits are exceeded, the filter status is REJECTED.
+#
+#       maxdepth=value - the maximum depth of a graph
+#       maxrefs=value  - the maximum number of internal references
+#       maxbytes=value - the maximum number of bytes in the input stream
+#       maxarray=value - the maximum array length allowed
+#
+#   Other patterns, from left to right, match the class or package name as
+#   returned from Class.getName.
+#   If the class is an array type, the class or package to be matched is the element type.
+#   Arrays of any number of dimensions are treated the same as the element type.
+#   For example, a pattern of "!example.Foo", rejects creation of any instance or
+#   array of example.Foo.
+#
+#   If the pattern starts with "!", the status is REJECTED if the remaining pattern
+#       is matched; otherwise the status is ALLOWED if the pattern matches.
+#   If the pattern contains "/", the non-empty prefix up to the "/" is the module name;
+#       if the module name matches the module name of the class then
+#       the remaining pattern is matched with the class name.
+#   If there is no "/", the module name is not compared.
+#   If the pattern ends with ".**" it matches any class in the package and all subpackages.
+#   If the pattern ends with ".*" it matches any class in the package.
+#   If the pattern ends with "*", it matches any class with the pattern as a prefix.
+#   If the pattern is equal to the class name, it matches.
+#   Otherwise, the status is UNDECIDED.
--- a/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java	Fri Oct 20 09:49:02 2017 -0700
@@ -29,9 +29,14 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.Permission;
+import java.security.ProtectionDomain;
 import java.security.PrivilegedAction;
+import jdk.internal.misc.SharedSecrets;
+import jdk.internal.misc.JavaSecurityAccess;
 
 /**
  * ReflectionFactory supports custom serialization.
@@ -140,6 +145,66 @@
     }
 
     /**
+     * Invokes the supplied constructor, adding the provided protection domains
+     * to the invocation stack before invoking {@code Constructor::newInstance}.
+     * If no {@linkplain System#getSecurityManager() security manager} is present,
+     * or no domains are provided, then this method simply calls
+     * {@code cons.newInstance()}. Otherwise, it invokes the provided constructor
+     * with privileges at the intersection of the current context and the provided
+     * protection domains.
+     *
+     * @param cons A constructor obtained from {@code
+     *        newConstructorForSerialization} or {@code
+     *        newConstructorForExternalization}.
+     * @param domains An array of protection domains that limit the privileges
+     *        with which the constructor is invoked. Can be {@code null}
+     *        or empty, in which case privileges are only limited by the
+     *        {@linkplain AccessController#getContext() current context}.
+     *
+     * @return A new object built from the provided constructor.
+     *
+     * @throws NullPointerException if {@code cons} is {@code null}.
+     * @throws InstantiationException if thrown by {@code cons.newInstance()}.
+     * @throws InvocationTargetException if thrown by {@code cons.newInstance()}.
+     * @throws IllegalAccessException if thrown by {@code cons.newInstance()}.
+     */
+    public final Object newInstanceForSerialization(Constructor<?> cons,
+                                                    ProtectionDomain[] domains)
+        throws InstantiationException, InvocationTargetException, IllegalAccessException
+    {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null || domains == null || domains.length == 0) {
+            return cons.newInstance();
+        } else {
+            JavaSecurityAccess jsa = SharedSecrets.getJavaSecurityAccess();
+            PrivilegedAction<?> pea = () -> {
+                try {
+                    return cons.newInstance();
+                } catch (InstantiationException
+                         | InvocationTargetException
+                         | IllegalAccessException x) {
+                    throw new UndeclaredThrowableException(x);
+                }
+            }; // Can't use PrivilegedExceptionAction with jsa
+            try {
+                return jsa.doIntersectionPrivilege(pea,
+                           AccessController.getContext(),
+                           new AccessControlContext(domains));
+            } catch (UndeclaredThrowableException x) {
+                Throwable cause = x.getCause();
+                 if (cause instanceof InstantiationException)
+                    throw (InstantiationException) cause;
+                if (cause instanceof InvocationTargetException)
+                    throw (InvocationTargetException) cause;
+                if (cause instanceof IllegalAccessException)
+                    throw (IllegalAccessException) cause;
+                // not supposed to happen
+                throw x;
+            }
+        }
+    }
+
+    /**
      * Returns a direct MethodHandle for the {@code readObjectNoData} method on
      * a Serializable class.
      * The first argument of {@link MethodHandle#invoke} is the serializable
@@ -224,4 +289,3 @@
         }
     }
 }
-
--- a/test/jdk/java/io/Serializable/serialFilter/SerialFilterTest.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/test/jdk/java/io/Serializable/serialFilter/SerialFilterTest.java	Fri Oct 20 09:49:02 2017 -0700
@@ -36,9 +36,11 @@
 import java.lang.reflect.Proxy;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.atomic.LongAdder;
 
 import javax.net.ssl.SSLEngineResult;
@@ -165,6 +167,11 @@
                 interfaces, (p, m, args) -> p);
 
         Runnable runnable = (Runnable & Serializable) SerialFilterTest::noop;
+
+        List<Class<?>> classList = new ArrayList<>();
+        classList.add(HashSet.class);
+        classList.addAll(Collections.nCopies(21, Map.Entry[].class));
+
         Object[][] objects = {
                 { null, 0, -1, 0, 0, 0,
                         Arrays.asList()},        // no callback, no values
@@ -184,8 +191,7 @@
                                 objArray.getClass(),
                                 SerialFilterTest.class,
                                 java.lang.invoke.SerializedLambda.class)},
-                { deepHashSet(10), 48, -1, 50, 11, 619,
-                        Arrays.asList(HashSet.class)},
+                { deepHashSet(10), 69, 4, 50, 11, 619, classList },
                 { proxy.getClass(), 3, -1, 2, 2, 112,
                         Arrays.asList(Runnable.class,
                                 java.lang.reflect.Proxy.class,
--- a/test/jdk/java/security/Signature/Offsets.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/test/jdk/java/security/Signature/Offsets.java	Fri Oct 20 09:49:02 2017 -0700
@@ -34,7 +34,7 @@
 
 /*
  * @test
- * @bug 8050374
+ * @bug 8050374 8181048
  * @key randomness
  * @summary This test validates signature verification
  *          Signature.verify(byte[], int, int). The test uses RandomFactory to
@@ -106,18 +106,25 @@
         Signature signature = Signature.getInstance(algorithm, provider);
 
         String keyAlgo;
+        int keySize = 2048;
         if (algorithm.contains("RSA")) {
             keyAlgo = "RSA";
         } else if (algorithm.contains("ECDSA")) {
             keyAlgo = "EC";
+            keySize = 256;
         } else if (algorithm.contains("DSA")) {
             keyAlgo = "DSA";
+            if (algorithm.startsWith("SHAwith") ||
+                    algorithm.startsWith("SHA1with")) {
+                keySize = 1024;
+            }
         } else {
             throw new RuntimeException("Test doesn't support this signature "
                     + "algorithm: " + algorithm);
         }
 
         KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlgo, provider);
+        kpg.initialize(keySize);
         KeyPair kp = kpg.generateKeyPair();
         PublicKey pubkey = kp.getPublic();
         PrivateKey privkey = kp.getPrivate();
--- a/test/jdk/java/security/SignedObject/Chain.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/test/jdk/java/security/SignedObject/Chain.java	Fri Oct 20 09:49:02 2017 -0700
@@ -32,7 +32,7 @@
 
 /*
  * @test
- * @bug 8050374
+ * @bug 8050374 8181048
  * @summary Verify a chain of signed objects
  */
 public class Chain {
@@ -97,22 +97,28 @@
         final Provider provider;
         final KeyAlg keyAlg;
         final SigAlg sigAlg;
+        final int keySize;
 
-        Test(SigAlg sigAlg, KeyAlg keyAlg, Provider privider) {
-            this.provider = privider;
+        Test(SigAlg sigAlg, KeyAlg keyAlg, Provider provider) {
+            this(sigAlg, keyAlg, provider, -1);
+        }
+
+        Test(SigAlg sigAlg, KeyAlg keyAlg, Provider provider, int keySize) {
+            this.provider = provider;
             this.keyAlg = keyAlg;
             this.sigAlg = sigAlg;
+            this.keySize = keySize;
         }
     }
 
     private static final Test[] tests = {
-        new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Default),
+        new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Default, 1024),
         new Test(SigAlg.MD2withRSA, KeyAlg.RSA, Provider.Default),
         new Test(SigAlg.MD5withRSA, KeyAlg.RSA, Provider.Default),
         new Test(SigAlg.SHA1withRSA, KeyAlg.RSA, Provider.Default),
-        new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Sun),
-        new Test(SigAlg.SHA224withDSA, KeyAlg.DSA, Provider.Sun),
-        new Test(SigAlg.SHA256withDSA, KeyAlg.DSA, Provider.Sun),
+        new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Sun, 1024),
+        new Test(SigAlg.SHA224withDSA, KeyAlg.DSA, Provider.Sun, 2048),
+        new Test(SigAlg.SHA256withDSA, KeyAlg.DSA, Provider.Sun, 2048),
     };
 
     private static final String str = "to-be-signed";
@@ -148,6 +154,9 @@
                 kpg = KeyPairGenerator.getInstance(test.keyAlg.name);
             }
             for (int j=0; j < N; j++) {
+                if (test.keySize != -1) {
+                    kpg.initialize(test.keySize);
+                }
                 KeyPair kp = kpg.genKeyPair();
                 KeyPair anotherKp = kpg.genKeyPair();
                 privKeys[j] = kp.getPrivate();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java	Fri Oct 20 09:49:02 2017 -0700
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8159377
+ * @library /lib/testlibrary
+ * @summary Tests ObjectFilter on default agent
+ * @author Harsha Wardhana B
+ * @modules java.management
+ * @build jdk.testlibrary.* DefaultAgentFilterTest
+ * @run main/othervm/timeout=600 -XX:+UsePerfData DefaultAgentFilterTest
+ */
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InvalidClassException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.net.BindException;
+import java.rmi.UnmarshalException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.Utils;
+
+public class DefaultAgentFilterTest {
+
+    public static class MyTestObject implements Serializable {
+
+        String a;
+        int id;
+    }
+
+    public interface TestMBean {
+
+        public void op1(HashSet<Object> params);
+
+        public void op2(String s, HashSet<String> params);
+
+        public void op3(MyTestObject obj, String s, HashMap<String, String> param);
+    }
+
+    public static class Test implements TestMBean {
+
+        @Override
+        public void op1(HashSet<Object> params) {
+            System.out.println("Invoked op1");
+        }
+
+        @Override
+        public void op2(String s, HashSet<String> params) {
+            System.out.println("Invoked op2");
+        }
+
+        @Override
+        public void op3(MyTestObject obj, String s, HashMap<String, String> param) {
+            System.out.println("Invoked op3");
+        }
+    }
+
+    private static class TestAppRun implements AutoCloseable {
+
+        private Process p;
+        private final ProcessBuilder pb;
+        private final String name;
+        private final AtomicBoolean started = new AtomicBoolean(false);
+        private volatile long pid = -1;
+
+        public TestAppRun(ProcessBuilder pb, String name) {
+            this.pb = pb;
+            this.name = name;
+        }
+
+        public synchronized void start() throws Exception {
+            if (started.compareAndSet(false, true)) {
+                try {
+                    AtomicBoolean error = new AtomicBoolean(false);
+                    AtomicBoolean bindError = new AtomicBoolean(false);
+                    p = ProcessTools.startProcess(
+                            TEST_APP_NAME + "{" + name + "}",
+                            pb,
+                            (line) -> {
+                                if (line.toLowerCase().contains("exception")
+                                || line.toLowerCase().contains("error")) {
+                                    error.set(true);
+                                }
+                                bindError.set(line.toLowerCase().contains("bindexception"));
+                                return true;
+                            });
+                    if (bindError.get()) {
+                        throw new BindException("Process could not be started");
+                    } else if (error.get()) {
+                        throw new RuntimeException();
+                    }
+                    pid = p.pid();
+                } catch (Exception ex) {
+                    if (p != null) {
+                        p.destroy();
+                        p.waitFor();
+                    }
+                    throw ex;
+                }
+            }
+        }
+
+        public long getPid() {
+            return pid;
+        }
+
+        public synchronized void stop()
+                throws IOException, InterruptedException {
+            if (started.compareAndSet(true, false)) {
+                p.getOutputStream().write(0);
+                p.getOutputStream().flush();
+                int ec = p.waitFor();
+                if (ec != 0) {
+                    StringBuilder msg = new StringBuilder();
+                    msg.append("Test application '").append(name);
+                    msg.append("' failed with exit code: ");
+                    msg.append(ec);
+                    System.err.println(msg);
+                }
+            }
+        }
+
+        @Override
+        public void close() throws Exception {
+            stop();
+        }
+    }
+
+    private static final String TEST_APP_NAME = "TestApp";
+
+    private static void testDefaultAgent(String propertyFile) throws Exception {
+        int port = Utils.getFreePort();
+        String propFile = System.getProperty("test.src") + File.separator + propertyFile;
+        List<String> pbArgs = new ArrayList<>(Arrays.asList(
+                "-cp",
+                System.getProperty("test.class.path"),
+                "-XX:+UsePerfData"
+        ));
+        String[] args = new String[]{
+            "-Dcom.sun.management.jmxremote.port=" + port,
+            "-Dcom.sun.management.jmxremote.authenticate=false",
+            "-Dcom.sun.management.jmxremote.ssl=false",
+            "-Dcom.sun.management.config.file=" + propFile
+        };
+        pbArgs.addAll(Arrays.asList(args));
+        pbArgs.add(TEST_APP_NAME);
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                pbArgs.toArray(new String[pbArgs.size()])
+        );
+
+        try (TestAppRun s = new TestAppRun(pb, DefaultAgentFilterTest.class.getSimpleName())) {
+            s.start();
+            JMXServiceURL url = testConnect(port);
+            testMBeanOperations(url);
+        }
+    }
+
+    private static JMXServiceURL testConnect(int port) throws Exception {
+        EOFException lastException = null;
+        JMXServiceURL url = null;
+        // factor adjusted timeout (5 seconds) for the RMI to become available
+        long timeout = System.currentTimeMillis() + Utils.adjustTimeout(5000);
+        do {
+            lastException = null;
+            try {
+                Registry registry = LocateRegistry.getRegistry(port);
+                String[] relist = registry.list();
+                for (int i = 0; i < relist.length; ++i) {
+                    System.out.println("Got registry: " + relist[i]);
+                }
+                String jmxUrlStr = String.format(
+                        "service:jmx:rmi:///jndi/rmi://localhost:%d/jmxrmi",
+                        port);
+                url = new JMXServiceURL(jmxUrlStr);
+
+                try (JMXConnector c = JMXConnectorFactory.connect(url, null)) {
+                    MBeanServerConnection conn = c.getMBeanServerConnection();
+                    ObjectName name = new ObjectName("jtreg:type=Test");
+                    conn.createMBean(Test.class.getName(), name);
+                }
+            } catch (Exception ex) {
+                if (ex instanceof EOFException) {
+                    lastException = (EOFException) ex;
+                    System.out.println("Error establishing RMI connection. Retrying in 500ms.");
+                    Thread.sleep(500);
+                } else {
+                    throw ex;
+                }
+            }
+        } while (lastException != null && System.currentTimeMillis() < timeout);
+        if (lastException != null) {
+            throw lastException;
+        }
+        return url;
+    }
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("---" + DefaultAgentFilterTest.class.getName() + "-main: starting ...");
+
+        boolean retry = false;
+        do {
+            try {
+                // blacklist String
+                testDefaultAgent("mgmt1.properties");
+                System.out.println("----\tTest FAILED !!");
+                throw new RuntimeException("---" + DefaultAgentFilterTest.class.getName() + " - No exception reported");
+            } catch (Exception ex) {
+                if (ex instanceof InvocationTargetException) {
+                    if (ex.getCause() instanceof BindException
+                            || ex.getCause() instanceof java.rmi.ConnectException) {
+                        System.out.println("Failed to allocate ports. Retrying ...");
+                        retry = true;
+                    }
+                } else if (ex instanceof InvalidClassException) {
+                    System.out.println("----\tTest PASSED !!");
+                } else if (ex instanceof UnmarshalException
+                        && ((UnmarshalException) ex).getCause() instanceof InvalidClassException) {
+                    System.out.println("----\tTest PASSED !!");
+                } else {
+                    System.out.println(ex);
+                    System.out.println("----\tTest FAILED !!");
+                    throw ex;
+                }
+            }
+        } while (retry);
+        retry = false;
+        do {
+            try {
+                // blacklist non-existent class
+                testDefaultAgent("mgmt2.properties");
+                System.out.println("----\tTest PASSED !!");
+            } catch (Exception ex) {
+                if (ex instanceof InvocationTargetException) {
+                    if (ex.getCause() instanceof BindException
+                            || ex.getCause() instanceof java.rmi.ConnectException) {
+                        System.out.println("Failed to allocate ports. Retrying ...");
+                        retry = true;
+                    }
+                } else {
+                    System.out.println(ex);
+                    System.out.println("----\tTest FAILED !!");
+                    throw ex;
+                }
+            }
+        } while (retry);
+
+        System.out.println("---" + DefaultAgentFilterTest.class.getName() + "-main: finished ...");
+    }
+
+    private static void testMBeanOperations(JMXServiceURL serverUrl) throws Exception {
+        Map<String, Object> clientEnv = new HashMap<>(1);
+        ObjectName name = new ObjectName("jtreg:type=Test");
+        try (JMXConnector client = JMXConnectorFactory.connect(serverUrl, clientEnv)) {
+            MBeanServerConnection conn = client.getMBeanServerConnection();
+
+            HashSet<String> set = new HashSet<>();
+            set.add("test1");
+            set.add("test2");
+
+            String a = "A";
+
+            Object[] params1 = {set};
+            String[] sig1 = {HashSet.class.getName()};
+            conn.invoke(name, "op1", params1, sig1);
+
+            Object[] params2 = {a, set};
+            String[] sig2 = {String.class.getName(), HashSet.class.getName()};
+            conn.invoke(name, "op2", params2, sig2);
+
+            HashMap<String, String> map = new HashMap<>();
+            map.put("a", "A");
+            map.put("b", "B");
+
+            Object[] params3 = {new MyTestObject(), a, map};
+            String[] sig3 = {MyTestObject.class.getName(), String.class.getName(),
+                HashMap.class.getName()};
+            conn.invoke(name, "op3", params3, sig3);
+        }
+    }
+}
+
+class TestApp {
+
+    private static void doSomething() throws IOException {
+        int r = System.in.read();
+        System.out.println("read: " + r);
+    }
+
+    public static void main(String args[]) throws Exception {
+        System.out.println("main enter");
+        System.out.flush();
+        doSomething();
+        System.out.println("main exit");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/mandatory/connection/NewRMIClientFilterTest.java	Fri Oct 20 09:49:02 2017 -0700
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 8159377
+ * @summary Tests ObjectInputFilter on RMIServer.newClient
+ * @author Harsha Wardhana B
+ * @modules java.management
+ * @run clean NewRMIClientFilterTest
+ * @run build NewRMIClientFilterTest
+ * @run main NewRMIClientFilterTest
+ */
+import java.io.InvalidClassException;
+import java.io.Serializable;
+import java.lang.management.ManagementFactory;
+import java.util.HashMap;
+import java.util.Map;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnectorServer;
+
+public class NewRMIClientFilterTest {
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("---NewRMIClientFilterTest-main: starting ...");
+        String filter1 = java.lang.String.class.getName() + ";!*";
+        String filter2 = java.lang.String.class.getName() + ";" + MyCredentials.class.getName() + ";!*";
+
+        JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
+        JMXServiceURL serverUrl = null;
+        Map<String, Object> env = new HashMap<>(1);
+        JMXConnectorServer server = null;
+
+        System.out.println("\n---NewRMIClientFilterTest-main: testing types = null");
+        server = newServer(url, null);
+        serverUrl = server.getAddress();
+        doTest(serverUrl, null);
+        doTest(serverUrl, new String[]{"toto", "titi"});
+        doTest(serverUrl, new Object[]{new MyCredentials(), "toto"});
+        server.stop();
+
+        System.out.println("\n---NewRMIClientFilterTest-main: testing types = String[]");
+        env.put(RMIConnectorServer.CREDENTIALS_FILTER_PATTERN,
+                filter1);
+        server = newServer(url, env);
+        serverUrl = server.getAddress();
+        doTest(serverUrl, null);
+        doTest(serverUrl, new String[]{"toto", "titi"});
+        try {
+            doTest(serverUrl, new MyCredentials());
+            throw new Error("Bad client is not refused!");
+        } catch (Exception e) {
+            isInvalidClassEx(e);
+        } finally {
+            server.stop();
+        }
+
+        System.out.println("\n---NewRMIClientFilterTest-main: testing user specific types = String, MyCredentials");
+        env.put(RMIConnectorServer.CREDENTIALS_FILTER_PATTERN,
+                filter2);
+        server = newServer(url, env);
+        serverUrl = server.getAddress();
+        doTest(serverUrl, null);
+        doTest(serverUrl, new String[]{"toto", "titi"});
+        doTest(serverUrl, new MyCredentials[]{new MyCredentials(), (MyCredentials) null});
+        try {
+            doTest(serverUrl, new Object[]{"toto", new byte[3]});
+            throw new Error("Bad client is not refused!");
+        } catch (Exception e) {
+            isInvalidClassEx(e);
+        } finally {
+            server.stop();
+        }
+
+        System.out.println("---NewRMIClientFilterTest-main PASSED!!!");
+    }
+
+    private static void doTest(JMXServiceURL serverAddr, Object credentials) throws Exception {
+        System.out.println("---NewRMIClientFilterTest-test:\n\tserver address: "
+                + serverAddr + "\n\tcredentials: " + credentials);
+
+        Map<String, Object> env = new HashMap<>(1);
+        env.put("jmx.remote.credentials", credentials);
+        JMXConnector client = null;
+        try {
+            client = JMXConnectorFactory.connect(serverAddr, env);
+            client.getMBeanServerConnection().getDefaultDomain();
+        } finally {
+            try {
+                client.close();
+            } catch (Exception e) {
+            }
+        }
+        System.out.println("---NewRMIClientFilterTest-test: PASSED!");
+    }
+
+    private static JMXConnectorServer newServer(JMXServiceURL url, Map<String, Object> env)
+            throws Exception {
+        JMXConnectorServer server = JMXConnectorServerFactory.newJMXConnectorServer(
+                url,
+                env,
+                ManagementFactory.getPlatformMBeanServer());
+
+        server.start();
+        return server;
+    }
+
+    private static class MyCredentials implements Serializable {
+    }
+
+    private static void isInvalidClassEx(Exception e) {
+        Throwable cause = e;
+        while (cause != null) {
+            if (cause instanceof InvalidClassException) {
+                System.out.println("---NewRMIClientFilterTest-InvalidClassException expected: " + cause);
+                return;
+            }
+            cause = cause.getCause();
+        }
+        e.printStackTrace();
+        throw new RuntimeException("Did not get expected InvalidClassException!");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/mandatory/connection/mgmt1.properties	Fri Oct 20 09:49:02 2017 -0700
@@ -0,0 +1,38 @@
+# ################ Filter for ObjectInputStream #############################
+com.sun.management.jmxremote.serial.filter.pattern=!DefaultAgentFilterTest$MyTestObject
+#   A filter, if configured, is used by java.io.ObjectInputStream during
+#   deserialization of parameters sent to the JMX default agent to validate the 
+#   contents of the stream.
+#   A filter is configured as a sequence of patterns, each pattern is either
+#   matched against the name of a class in the stream or defines a limit.
+#   Patterns are separated by ";" (semicolon).
+#   Whitespace is significant and is considered part of the pattern.
+#
+#   If a pattern includes a "=", it sets a limit.
+#   If a limit appears more than once the last value is used.
+#   Limits are checked before classes regardless of the order in the sequence of patterns.
+#   If any of the limits are exceeded, the filter status is REJECTED.
+#
+#       maxdepth=value - the maximum depth of a graph
+#       maxrefs=value  - the maximum number of internal references
+#       maxbytes=value - the maximum number of bytes in the input stream
+#       maxarray=value - the maximum array length allowed
+#
+#   Other patterns, from left to right, match the class or package name as
+#   returned from Class.getName.
+#   If the class is an array type, the class or package to be matched is the element type.
+#   Arrays of any number of dimensions are treated the same as the element type.
+#   For example, a pattern of "!example.Foo", rejects creation of any instance or
+#   array of example.Foo.
+#
+#   If the pattern starts with "!", the status is REJECTED if the remaining pattern
+#       is matched; otherwise the status is ALLOWED if the pattern matches.
+#   If the pattern contains "/", the non-empty prefix up to the "/" is the module name;
+#       if the module name matches the module name of the class then
+#       the remaining pattern is matched with the class name.
+#   If there is no "/", the module name is not compared.
+#   If the pattern ends with ".**" it matches any class in the package and all subpackages.
+#   If the pattern ends with ".*" it matches any class in the package.
+#   If the pattern ends with "*", it matches any class with the pattern as a prefix.
+#   If the pattern is equal to the class name, it matches.
+#   Otherwise, the status is UNDECIDED.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/remote/mandatory/connection/mgmt2.properties	Fri Oct 20 09:49:02 2017 -0700
@@ -0,0 +1,38 @@
+# ################ Filter for ObjectInputStream #############################
+com.sun.management.jmxremote.serial.filter.pattern=!DefaultAgentFilterTest$ThisTypeIsNotUsed
+#   A filter, if configured, is used by java.io.ObjectInputStream during
+#   deserialization of parameters sent to the JMX default agent to validate the 
+#   contents of the stream.
+#   A filter is configured as a sequence of patterns, each pattern is either
+#   matched against the name of a class in the stream or defines a limit.
+#   Patterns are separated by ";" (semicolon).
+#   Whitespace is significant and is considered part of the pattern.
+#
+#   If a pattern includes a "=", it sets a limit.
+#   If a limit appears more than once the last value is used.
+#   Limits are checked before classes regardless of the order in the sequence of patterns.
+#   If any of the limits are exceeded, the filter status is REJECTED.
+#
+#       maxdepth=value - the maximum depth of a graph
+#       maxrefs=value  - the maximum number of internal references
+#       maxbytes=value - the maximum number of bytes in the input stream
+#       maxarray=value - the maximum array length allowed
+#
+#   Other patterns, from left to right, match the class or package name as
+#   returned from Class.getName.
+#   If the class is an array type, the class or package to be matched is the element type.
+#   Arrays of any number of dimensions are treated the same as the element type.
+#   For example, a pattern of "!example.Foo", rejects creation of any instance or
+#   array of example.Foo.
+#
+#   If the pattern starts with "!", the status is REJECTED if the remaining pattern
+#       is matched; otherwise the status is ALLOWED if the pattern matches.
+#   If the pattern contains "/", the non-empty prefix up to the "/" is the module name;
+#       if the module name matches the module name of the class then
+#       the remaining pattern is matched with the class name.
+#   If there is no "/", the module name is not compared.
+#   If the pattern ends with ".**" it matches any class in the package and all subpackages.
+#   If the pattern ends with ".*" it matches any class in the package.
+#   If the pattern ends with "*", it matches any class with the pattern as a prefix.
+#   If the pattern is equal to the class name, it matches.
+#   Otherwise, the status is UNDECIDED.
\ No newline at end of file
--- a/test/jdk/javax/management/remote/mandatory/connectorServer/RMIExporterTest.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/test/jdk/javax/management/remote/mandatory/connectorServer/RMIExporterTest.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,7 @@
 import javax.management.remote.JMXConnectorServerFactory;
 import javax.management.remote.JMXServiceURL;
 import com.sun.jmx.remote.internal.rmi.RMIExporter;
+import java.io.ObjectInputFilter;
 
 public class RMIExporterTest {
 
@@ -60,7 +61,8 @@
         public Remote exportObject(Remote obj,
                                    int port,
                                    RMIClientSocketFactory csf,
-                                   RMIServerSocketFactory ssf)
+                                   RMIServerSocketFactory ssf,
+                                   ObjectInputFilter unused)
             throws RemoteException {
             System.out.println("CustomRMIExporter::exportObject():: " +
                                "Remote = " + obj);
--- a/test/jdk/sun/security/provider/DSA/TestAlgParameterGenerator.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/test/jdk/sun/security/provider/DSA/TestAlgParameterGenerator.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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 7044060 8055351
+ * @bug 7044060 8055351 8181048
  * @summary verify that DSA parameter generation works
  * @run main/timeout=600 TestAlgParameterGenerator
  */
@@ -81,7 +81,6 @@
         AlgorithmParameters param = apg.generateParameters();
         stop = System.currentTimeMillis();
         System.out.println("Time: " + (stop - start) + " ms.");
-        checkParamStrength(param, 1024);
 
         // make sure the old model works
         int[] strengths = {512, 768, 1024};
--- a/test/jdk/sun/security/provider/DSA/TestKeyPairGenerator.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/test/jdk/sun/security/provider/DSA/TestKeyPairGenerator.java	Fri Oct 20 09:49:02 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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 4800108 8072452
+ * @bug 4800108 8072452 8181048
  * @summary verify that precomputed DSA parameters are always used (512, 768,
  *          1024, 2048, 3072 bit)
  * @run main/othervm/timeout=15 TestKeyPairGenerator
@@ -59,15 +59,12 @@
         // on JDKs that do not have the fix
         kpg = KeyPairGenerator.getInstance("DSA", "SUN");
         kp = kpg.generateKeyPair();
-        checkKeyLength(kp, 1024);
 
         kpg = KeyPairGenerator.getInstance("DSA", "SUN");
         kp = kpg.generateKeyPair();
-        checkKeyLength(kp, 1024);
 
         // some other basic tests
         kp = kpg.generateKeyPair();
-        checkKeyLength(kp, 1024);
 
         kpg.initialize(1024);
         kp = kpg.generateKeyPair();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/provider/DSA/TestLegacyDSAKeyPairGenerator.java	Fri Oct 20 09:49:02 2017 -0700
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, 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 8181048
+ * @summary verify that when the returned DSA KeyPairGenerator is
+ * an instance of java.security.interfaces.DSAKeyPairGenerator,
+ * the behavior is compliant with the javadoc spec.
+ * @run main/othervm -Djdk.security.legacyDSAKeyPairGenerator=tRUe TestLegacyDSAKeyPairGenerator
+ */
+
+import java.security.*;
+import java.security.interfaces.*;
+
+public class TestLegacyDSAKeyPairGenerator {
+
+    private static void checkKeyLength(KeyPair kp, int len) throws Exception {
+        DSAPublicKey key = (DSAPublicKey)kp.getPublic();
+        int n = key.getParams().getP().bitLength();
+        System.out.println("Key length: " + n);
+        if (len != n) {
+            throw new Exception("Wrong key length");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", "SUN");
+        // check the returned object implements the legacy interface
+        if (!(kpg instanceof DSAKeyPairGenerator)) {
+            throw new Exception("Should be an instance of DSAKeyPairGenerator");
+        }
+        System.out.println("Returned an instance of DSAKeyPairGenerator");
+        // check the default key size is 1024 when initiaize(..) is not called
+        KeyPair kp1 = kpg.generateKeyPair();
+        checkKeyLength(kp1, 1024);
+        KeyPair kp2 = kpg.generateKeyPair();
+        checkKeyLength(kp2, 1024);
+        System.out.println("Used 1024 default key size");
+
+        // check kp1 and kp2 uses the same DSA parameters p, q, g
+        DSAParams param1 = ((DSAPublicKey)kp1.getPublic()).getParams();
+        DSAParams param2 = ((DSAPublicKey)kp2.getPublic()).getParams();
+        if ((param1.getP().compareTo(param2.getP()) != 0) ||
+            (param1.getQ().compareTo(param2.getQ()) != 0) ||
+            (param1.getG().compareTo(param2.getG()) != 0)) {
+            throw new RuntimeException("Key params mismatch");
+        }
+        System.out.println("Used same default params");
+
+        // check that the documented exception is thrown if no cached parameters
+        int sizeNotInCache = (1024 - 64);
+        try {
+            ((DSAKeyPairGenerator)kpg).initialize(sizeNotInCache, false, null);
+            throw new RuntimeException("Expected IPE not thrown");
+        } catch (InvalidParameterException ipe) {
+            System.out.println("Throwed expected IPE");
+        }
+        ((DSAKeyPairGenerator)kpg).initialize(sizeNotInCache, true, null);
+        KeyPair kp = kpg.generateKeyPair();
+        checkKeyLength(kp, sizeNotInCache);
+        System.out.println("Generated requested key size");
+    }
+}
--- a/test/jdk/sun/security/tools/keytool/WeakAlg.java	Fri Oct 20 17:16:05 2017 +0530
+++ b/test/jdk/sun/security/tools/keytool/WeakAlg.java	Fri Oct 20 09:49:02 2017 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8171319 8177569
+ * @bug 8171319 8177569 8182879
  * @summary keytool should print out warnings when reading or generating
   *         cert/cert req using weak algorithms
  * @library /test/lib
@@ -40,6 +40,7 @@
  * @run main/othervm/timeout=600 -Duser.language=en -Duser.country=US WeakAlg
  */
 
+import jdk.test.lib.Asserts;
 import jdk.test.lib.SecurityTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import sun.security.tools.KeyStoreUtil;
@@ -47,6 +48,7 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintStream;
@@ -141,25 +143,164 @@
         kt("-delete -alias b");
         kt("-printcrl -file b.crl")
                 .shouldContain("WARNING: not verified");
+
+        jksTypeCheck();
+
+        checkInplaceImportKeyStore();
+    }
+
+    static void jksTypeCheck() throws Exception {
+
+        // No warning for cacerts, all certs
+        kt0("-cacerts -list -storepass changeit")
+                .shouldNotContain("Warning:");
+
+        rm("ks");
+        rm("ks2");
+
+        kt("-genkeypair -alias a -dname CN=A")
+                .shouldNotContain("Warning:");
+        kt("-list")
+                .shouldNotContain("Warning:");
+        kt("-list -storetype jks") // no warning if PKCS12 used as JKS
+                .shouldNotContain("Warning:");
+        kt("-exportcert -alias a -file a.crt")
+                .shouldNotContain("Warning:");
+
+        // warn if migrating to JKS
+        importkeystore("ks", "ks2", "-deststoretype jks")
+                .shouldContain("JKS keystore uses a proprietary format");
+
+        rm("ks");
+        rm("ks2");
+        rm("ks3");
+
+        // no warning if all certs
+        kt("-importcert -alias b -file a.crt -storetype jks -noprompt")
+                .shouldNotContain("Warning:");
+        kt("-genkeypair -alias a -dname CN=A")
+                .shouldContain("JKS keystore uses a proprietary format");
+        kt("-list")
+                .shouldContain("JKS keystore uses a proprietary format");
+        kt("-list -storetype pkcs12") // warn if JKS used as PKCS12
+                .shouldContain("JKS keystore uses a proprietary format");
+        kt("-exportcert -alias a -file a.crt")
+                .shouldContain("JKS keystore uses a proprietary format");
+        kt("-printcert -file a.crt") // no warning if keystore not touched
+                .shouldNotContain("Warning:");
+        kt("-certreq -alias a -file a.req")
+                .shouldContain("JKS keystore uses a proprietary format");
+        kt("-printcertreq -file a.req") // no warning if keystore not touched
+                .shouldNotContain("Warning:");
+
+        // No warning if migrating from JKS
+        importkeystore("ks", "ks2", "")
+                .shouldNotContain("Warning:");
+
+        importkeystore("ks", "ks3", "-deststoretype pkcs12")
+                .shouldNotContain("Warning:");
+
+        rm("ks");
+
+        kt("-genkeypair -alias a -dname CN=A -storetype jceks")
+                .shouldContain("JCEKS keystore uses a proprietary format");
+        kt("-list")
+                .shouldContain("JCEKS keystore uses a proprietary format");
+        kt("-importcert -alias b -file a.crt -noprompt")
+                .shouldContain("JCEKS keystore uses a proprietary format");
+        kt("-exportcert -alias a -file a.crt")
+                .shouldContain("JCEKS keystore uses a proprietary format");
+        kt("-printcert -file a.crt")
+                .shouldNotContain("Warning:");
+        kt("-certreq -alias a -file a.req")
+                .shouldContain("JCEKS keystore uses a proprietary format");
+        kt("-printcertreq -file a.req")
+                .shouldNotContain("Warning:");
+        kt("-genseckey -alias c -keyalg AES -keysize 128")
+                .shouldContain("JCEKS keystore uses a proprietary format");
     }
 
     static void checkImportKeyStore() throws Exception {
 
-        saveStore();
+        rm("ks2");
+        rm("ks3");
 
-        rm("ks");
-        kt("-importkeystore -srckeystore ks2 -srcstorepass changeit")
+        importkeystore("ks", "ks2", "")
                 .shouldContain("3 entries successfully imported")
                 .shouldContain("Warning")
                 .shouldMatch("<b>.*512-bit RSA key.*risk")
                 .shouldMatch("<a>.*MD5withRSA.*risk");
 
-        rm("ks");
-        kt("-importkeystore -srckeystore ks2 -srcstorepass changeit -srcalias a")
+        importkeystore("ks", "ks3", "-srcalias a")
                 .shouldContain("Warning")
                 .shouldMatch("<a>.*MD5withRSA.*risk");
+    }
 
-        reStore();
+    static void checkInplaceImportKeyStore() throws Exception {
+
+        rm("ks");
+        genkeypair("a", "");
+
+        // Same type backup
+        importkeystore("ks", "ks", "")
+                .shouldContain("Warning:")
+                .shouldMatch("original.*ks.old");
+
+        importkeystore("ks", "ks", "")
+                .shouldContain("Warning:")
+                .shouldMatch("original.*ks.old2");
+
+        importkeystore("ks", "ks", "-srcstoretype jks") // it knows real type
+                .shouldContain("Warning:")
+                .shouldMatch("original.*ks.old3");
+
+        String cPath = new File("ks").getCanonicalPath();
+
+        importkeystore("ks", cPath, "")
+                .shouldContain("Warning:")
+                .shouldMatch("original.*ks.old4");
+
+        // Migration
+        importkeystore("ks", "ks", "-deststoretype jks")
+                .shouldContain("Warning:")
+                .shouldContain("JKS keystore uses a proprietary format")
+                .shouldMatch("Migrated.*JKS.*PKCS12.*ks.old5");
+
+        Asserts.assertEQ(
+                KeyStore.getInstance(
+                        new File("ks"), "changeit".toCharArray()).getType(),
+                "JKS");
+
+        importkeystore("ks", "ks", "-srcstoretype PKCS12")
+                .shouldContain("Warning:")
+                .shouldNotContain("proprietary format")
+                .shouldMatch("Migrated.*PKCS12.*JKS.*ks.old6");
+
+        Asserts.assertEQ(
+                KeyStore.getInstance(
+                        new File("ks"), "changeit".toCharArray()).getType(),
+                "PKCS12");
+
+        Asserts.assertEQ(
+                KeyStore.getInstance(
+                        new File("ks.old6"), "changeit".toCharArray()).getType(),
+                "JKS");
+
+        // One password prompt is enough for migration
+        kt0("-importkeystore -srckeystore ks -destkeystore ks", "changeit")
+                .shouldMatch("original.*ks.old7");
+
+        // But three if importing to a different keystore
+        rm("ks2");
+        kt0("-importkeystore -srckeystore ks -destkeystore ks2",
+                    "changeit")
+                .shouldContain("Keystore password is too short");
+
+        kt0("-importkeystore -srckeystore ks -destkeystore ks2",
+                "changeit", "changeit", "changeit")
+                .shouldContain("Importing keystore ks to ks2...")
+                .shouldNotContain("original")
+                .shouldNotContain("Migrated");
     }
 
     static void checkImport() throws Exception {
@@ -525,17 +666,22 @@
         }
     }
 
+    static OutputAnalyzer kt(String cmd, String... input) {
+        return kt0("-keystore ks -storepass changeit " +
+                "-keypass changeit " + cmd, input);
+    }
+
     // Fast keytool execution by directly calling its main() method
-    static OutputAnalyzer kt(String cmd, String... input) {
+    static OutputAnalyzer kt0(String cmd, String... input) {
         PrintStream out = System.out;
         PrintStream err = System.err;
         InputStream ins = System.in;
         ByteArrayOutputStream bout = new ByteArrayOutputStream();
         ByteArrayOutputStream berr = new ByteArrayOutputStream();
         boolean succeed = true;
+        String sout;
+        String serr;
         try {
-            cmd = "-keystore ks -storepass changeit " +
-                    "-keypass changeit " + cmd;
             System.out.println("---------------------------------------------");
             System.out.println("$ keytool " + cmd);
             System.out.println();
@@ -559,19 +705,26 @@
             System.setOut(out);
             System.setErr(err);
             System.setIn(ins);
+            sout = new String(bout.toByteArray());
+            serr = new String(berr.toByteArray());
+            System.out.println("STDOUT:\n" + sout + "\nSTDERR:\n" + serr);
         }
-        String sout = new String(bout.toByteArray());
-        String serr = new String(berr.toByteArray());
-        System.out.println("STDOUT:\n" + sout + "\nSTDERR:\n" + serr);
         if (!succeed) {
             throw new RuntimeException();
         }
         return new OutputAnalyzer(sout, serr);
     }
 
+    static OutputAnalyzer importkeystore(String src, String dest,
+                                         String options) {
+        return kt0("-importkeystore "
+                + "-srckeystore " + src + " -destkeystore " + dest
+                + " -srcstorepass changeit -deststorepass changeit " + options);
+    }
+
     static OutputAnalyzer genkeypair(String alias, String options) {
         return kt("-genkeypair -alias " + alias + " -dname CN=" + alias
-                + " -storetype JKS " + options);
+                + " -storetype PKCS12 " + options);
     }
 
     static OutputAnalyzer certreq(String alias, String options) {