changeset 12815:4c4efa8fa39a jdk8u162-b04

Merge
author asaha
date Tue, 24 Oct 2017 23:16:46 -0700
parents 64df143be721 (current diff) ae96c5b7ce99 (diff)
children 8f56ba1989c0
files .hgtags src/share/classes/sun/misc/JavaObjectInputStreamAccess.java src/share/classes/sun/misc/ObjectStreamClassValidator.java src/share/classes/sun/rmi/registry/RegistryImpl.java src/share/classes/sun/security/ssl/SupportedEllipticCurvesExtension.java src/share/classes/sun/security/ssl/SupportedEllipticPointFormatsExtension.java src/share/lib/security/java.security-aix src/share/lib/security/java.security-linux src/share/lib/security/java.security-macosx src/share/lib/security/java.security-solaris src/share/lib/security/java.security-windows src/windows/native/sun/windows/awt_Component.cpp
diffstat 79 files changed, 3283 insertions(+), 1255 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Oct 24 13:07:11 2017 -0700
+++ b/.hgtags	Tue Oct 24 23:16:46 2017 -0700
@@ -664,6 +664,8 @@
 60767ec3909b3d0cb26dd7b3f952c62053719dda jdk8u112-b15
 5dd7e4bae5c2f1ee4f80c5570e7e3e2f715f7a32 jdk8u112-b16
 41fac11792c1ee6945f56721ee558a7424395a81 jdk8u112-b31
+548a51660ee94aeb77b2432594aeb87f87c21697 jdk8u112-b32
+a334b0815d34948188537a177a32cee27007ea2c jdk8u112-b33
 ab5ff8f1e52c5e3ca02e988f4d978af63ceca5b8 jdk8u121-b00
 5f0839ac7e0d25dd1ae705df496b12ca76c26d59 jdk8u121-b01
 f91e3aa155b3c6774afb456db15fb358313d5771 jdk8u121-b02
@@ -678,6 +680,12 @@
 ec72a941be0a50ab77f5375cf710bc06e4f118d3 jdk8u121-b11
 9561afc12df843ef21ecd9d7b3633371e7a2bfc4 jdk8u121-b12
 2974746e56192cdd14fc2dd43179bcf28e4faf4a jdk8u121-b13
+4f69f3363a2ecee8d3df2b046266a76c2a805139 jdk8u121-b31
+ec26e3331158912f86268ef473e64514c70cbd52 jdk8u121-b32
+cb2c7c89dd09edcda4cb7bd0db623c813d3e5dbc jdk8u121-b33
+90f36d39acdc5be0665722538749c59583e3b83d jdk8u121-b34
+cec5310dcc2b876dd53a057035cb63dd22f63257 jdk8u121-b35
+a5c94735ad3fb33f353abc23e25915db2ff7a36e jdk8u121-b36
 032874d46bf95478cb86690b3c91d335c0764b0b jdk8u131-b00
 bea5b22daf5ddd941f3bcbf7a4e5fc5244ceb788 jdk8u131-b01
 a01d217a232906e82f80e5bc3db4d60c4c74716e jdk8u131-b02
@@ -690,6 +698,10 @@
 40d00399869d8a28cfecf360234f340e9e0ad3b1 jdk8u131-b09
 c0091a673d766ce2e76a945bab6de325fe78dd88 jdk8u131-b10
 3ab471c4760a808e39406303ff33a25a542b9c75 jdk8u131-b11
+d50ccb38def5968145fd3f6e0579416bb027e85c jdk8u131-b31
+e54624a8ebe3639d3b2360adb9ae0fa32f1bef57 jdk8u131-b32
+15006e8dc79bd0005d264bff0b1677a109cf5a02 jdk8u131-b33
+e6e35f065443533c81db69022a272927b0b20f69 jdk8u131-b34
 a160009bbe1417d85f1c0eec890fdb17391b3637 jdk8u141-b00
 e95a13de2d36050302a1af422967f5260fc8eabd jdk8u141-b01
 936085d9aff0554a3bdab2fcbbec1d1864e656a2 jdk8u141-b02
@@ -712,6 +724,14 @@
 2ea94405100763c772ab3989200115d7a23c7532 jdk8u141-b15
 b64b1dfdbe7cfe3859f1023c0f1fb0216bce4ae7 jdk8u144-b00
 d2744852f3e64f7b0ba54f3a64ed5e2107e6ee68 jdk8u144-b01
+55899d2b99b0725d74eebc510a116423329ad6f0 jdk8u141-b31
+a3c4020f84aeb0dba467534239951f8818bdfb84 jdk8u141-b32
+b64b1dfdbe7cfe3859f1023c0f1fb0216bce4ae7 jdk8u144-b00
+d2744852f3e64f7b0ba54f3a64ed5e2107e6ee68 jdk8u144-b01
+a05113a4c91c59f44b9894e12aeda07a7534ff7e jdk8u144-b31
+c4f7f2878c4bc54dcc12eddbbcd90d4c7a5dddfe jdk8u144-b32
+785d45a4c0b715ff0131abda873e3c2f85874ac3 jdk8u144-b33
+71dee2264dddd5a2c90d8c6f3a3f4ffd8da02551 jdk8u144-b34
 072e084bceeedeb75467e40ca77786ac9ef5227a jdk8u151-b00
 5b0fa6e004312a5910a6a70e4fbc0f00a678e650 jdk8u151-b01
 bd40efd56b4544ff9048d2f7be4cf108b281a6f3 jdk8u151-b02
@@ -752,6 +772,56 @@
 50047f057dc14fa5e08e2b449304a21889e4079a jdk8u152-b14
 bfd67d7c7d41b320225d5502cec55c6b38cdaa6d jdk8u152-b15
 1cb70967c4d78a45a60d0d6eb64cb7fbe89ad005 jdk8u152-b16
+072e084bceeedeb75467e40ca77786ac9ef5227a jdk8u151-b00
+5b0fa6e004312a5910a6a70e4fbc0f00a678e650 jdk8u151-b01
+bd40efd56b4544ff9048d2f7be4cf108b281a6f3 jdk8u151-b02
+58243fea3fe2669e93350bb4b77e188623b85503 jdk8u151-b03
+27273bbb711a402efe5fcd332003ba419102f662 jdk8u151-b04
+0efdf2c7a21464e5f3d89474ffdfe81db61031fd jdk8u151-b05
+c6c870e267de694bc85dc4af23a648824063f95b jdk8u151-b06
+1442bc728814af451e2dd1a6719a64485d27e3a0 jdk8u122-b00
+f6030acfa5aec0e64d45adfac69b9e7e5c12bc74 jdk8u122-b01
+6b072c3a6db7ab06804c91aab77431799dfb5d47 jdk8u122-b02
+141beb4d854d213c1aefcc4406f09aa6b0809e43 jdk8u122-b03
+141beb4d854d213c1aefcc4406f09aa6b0809e43 jdk8u122-b03
+0000000000000000000000000000000000000000 jdk8u122-b03
+0000000000000000000000000000000000000000 jdk8u122-b03
+d8c1eb38a23286991238eed87ab04c331700839b jdk8u122-b03
+774f11d707e0ff685c131cd625d96e1f58527990 jdk8u122-b04
+000711011f8ab7ab5ea88e02086c48181b42ab8f jdk8u132-b00
+f7be58eb30bc2cdea8a8e0fb254f52f176f5b57d jdk8u152-b00
+072df97b6e2af59f5e2433ae6b2dbecb16b03cd8 jdk8u152-b01
+dbf817e782805bffcb9a0d84f452349926329d62 jdk8u152-b02
+824988d089dde02e15f04c3b994115f78b9408c9 jdk8u152-b03
+4c95cacb8ec77cbda2ae1d4e070b39ec6b527769 jdk8u152-b04
+9c692f8574178a5505efe39cdff1ea92d4f95cbd jdk8u152-b05
+636043375508d667052c84691c55d4c633376dbe jdk8u152-b06
+83998ef9e0b96e1f5f9d4667575a81e8aa06b981 jdk8u152-b07
+e62e091df75fd92bf9d8c573f6224132c99b33ea jdk8u152-b08
+eb71140d49732a226340c0e0a2224c0215fc161a jdk8u152-b09
+1442bc728814af451e2dd1a6719a64485d27e3a0 jdk8u122-b00
+f6030acfa5aec0e64d45adfac69b9e7e5c12bc74 jdk8u122-b01
+6b072c3a6db7ab06804c91aab77431799dfb5d47 jdk8u122-b02
+141beb4d854d213c1aefcc4406f09aa6b0809e43 jdk8u122-b03
+141beb4d854d213c1aefcc4406f09aa6b0809e43 jdk8u122-b03
+0000000000000000000000000000000000000000 jdk8u122-b03
+0000000000000000000000000000000000000000 jdk8u122-b03
+d8c1eb38a23286991238eed87ab04c331700839b jdk8u122-b03
+774f11d707e0ff685c131cd625d96e1f58527990 jdk8u122-b04
+000711011f8ab7ab5ea88e02086c48181b42ab8f jdk8u132-b00
+f7be58eb30bc2cdea8a8e0fb254f52f176f5b57d jdk8u152-b00
+072df97b6e2af59f5e2433ae6b2dbecb16b03cd8 jdk8u152-b01
+dbf817e782805bffcb9a0d84f452349926329d62 jdk8u152-b02
+824988d089dde02e15f04c3b994115f78b9408c9 jdk8u152-b03
+4c95cacb8ec77cbda2ae1d4e070b39ec6b527769 jdk8u152-b04
+9c692f8574178a5505efe39cdff1ea92d4f95cbd jdk8u152-b05
+a160009bbe1417d85f1c0eec890fdb17391b3637 jdk8u141-b00
+072e084bceeedeb75467e40ca77786ac9ef5227a jdk8u151-b00
+e9c7ecc5a9fcdcb31d4796b72493960c271dcb31 jdk8u161-b00
+3b1bfef6f82b72cc7e8d73a60d1faaf7818be6f3 jdk8u161-b01
+fef2bdb968d7caa0d4bd1714bd4571ca21edb25d jdk8u161-b02
+3742cb9c55fd997075a52581497829bd6f6b978a jdk8u161-b03
+3299bb548705c586c17fc31c815bb222e6a63370 jdk8u161-b04
 e03f9868f7df1e3db537f3b61704658e8a9dafb5 jdk8u162-b00
 538bdf24383954cd2356e39e8081c2cb3ac27281 jdk8u162-b01
 18e0bc77adafd0e5e459e381b6993bb0625b05be jdk8u162-b02
--- a/THIRD_PARTY_README	Tue Oct 24 13:07:11 2017 -0700
+++ b/THIRD_PARTY_README	Tue Oct 24 23:16:46 2017 -0700
@@ -7,7 +7,7 @@
 
 --- begin of LICENSE ---
 
-Copyright (c) 2000-2011 France Télécom
+Copyright (c) 2000-2011 France T??l??com
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -849,7 +849,7 @@
 --- begin of LICENSE ---
 
 Copyright notice
-Copyright © 2011 Ecma International
+Copyright ?? 2011 Ecma International
 Ecma International
 Rue du Rhone 114
 CH-1204 Geneva
@@ -916,7 +916,7 @@
 
 --- begin of LICENSE ---
 
-Copyright © 2001,2003 Keith Packard
+Copyright ?? 2001,2003 Keith Packard
 
 Permission to use, copy, modify, distribute, and sell this software and its
 documentation for any purpose is hereby granted without fee, provided that the
@@ -2212,16 +2212,16 @@
 Unicode Terms of Use
 
 For the general privacy policy governing access to this site, see the Unicode
-Privacy Policy. For trademark usage, see the Unicode® Consortium Name and
+Privacy Policy. For trademark usage, see the Unicode?? Consortium Name and
 Trademark Usage Policy.
 
 A. Unicode Copyright.
-   1. Copyright © 1991-2013 Unicode, Inc. All rights reserved.
+   1. Copyright ?? 1991-2013 Unicode, Inc. All rights reserved.
 
    2. Certain documents and files on this website contain a legend indicating
       that "Modification is permitted." Any person is hereby authorized,
       without fee, to modify such documents and files to create derivative
-      works conforming to the Unicode® Standard, subject to Terms and
+      works conforming to the Unicode?? Standard, subject to Terms and
       Conditions herein.
 
     3. Any person is hereby authorized, without fee, to view, use, reproduce,
@@ -2287,14 +2287,14 @@
 
 E.Trademarks & Logos.
    1. The Unicode Word Mark and the Unicode Logo are trademarks of Unicode,
-      Inc.  “The Unicode Consortium” and “Unicode, Inc.” are trade names of
+      Inc.  ???The Unicode Consortium??? and ???Unicode, Inc.??? are trade names of
       Unicode, Inc.  Use of the information and materials found on this
-      website indicates your acknowledgement of Unicode, Inc.’s exclusive
+      website indicates your acknowledgement of Unicode, Inc.???s exclusive
       worldwide rights in the Unicode Word Mark, the Unicode Logo, and the
       Unicode trade names.
 
-   2. The Unicode Consortium Name and Trademark Usage Policy (“Trademark
-      Policy”) are incorporated herein by reference and you agree to abide by
+   2. The Unicode Consortium Name and Trademark Usage Policy (???Trademark
+      Policy???) are incorporated herein by reference and you agree to abide by
       the provisions of the Trademark Policy, which may be changed from time
       to time in the sole discretion of Unicode, Inc.
 
@@ -2317,12 +2317,12 @@
 
    2. Modification by Unicode.  Unicode shall have the right to modify this
       Agreement at any time by posting it to this site. The user may not
-      assign any part of this Agreement without Unicode’s prior written
+      assign any part of this Agreement without Unicode???s prior written
       consent.
 
    3. Taxes. The user agrees to pay any taxes arising from access to this
       website or use of the information herein, except for those based on
-      Unicode’s net income.
+      Unicode???s net income.
 
    4. Severability.  If any provision of this Agreement is declared invalid or
       unenforceable, the remaining provisions of this Agreement shall remain
@@ -2351,7 +2351,7 @@
 
 COPYRIGHT AND PERMISSION NOTICE
 
-Copyright © 1991-2012 Unicode, Inc. All rights reserved. Distributed under the
+Copyright ?? 1991-2012 Unicode, Inc. All rights reserved. Distributed under the
 Terms of Use in http://www.unicode.org/copyright.html.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
--- a/src/macosx/native/apple/security/KeystoreImpl.m	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/macosx/native/apple/security/KeystoreImpl.m	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -432,6 +432,11 @@
                 goto errOut;
             }
             passwordStrRef = CFStringCreateWithCharacters(kCFAllocatorDefault, passwordChars, passwordLen);
+
+            // clear the password and release
+            memset(passwordChars, 0, passwordLen);
+            (*env)->ReleaseCharArrayElements(env, passwordObj, passwordChars,
+                JNI_ABORT);
         }
     }
 
@@ -518,8 +523,19 @@
 
     if (passwordObj) {
         passwordLen = (*env)->GetArrayLength(env, passwordObj);
-        passwordChars = (*env)->GetCharArrayElements(env, passwordObj, NULL);
-        passwordStrRef = CFStringCreateWithCharacters(kCFAllocatorDefault, passwordChars, passwordLen);
+
+        if (passwordLen > 0) {
+            passwordChars = (*env)->GetCharArrayElements(env, passwordObj, NULL);
+            if (passwordChars == NULL) {
+                goto errOut;
+            }
+            passwordStrRef = CFStringCreateWithCharacters(kCFAllocatorDefault, passwordChars, passwordLen);
+
+            // clear the password and release
+            memset(passwordChars, 0, passwordLen);
+            (*env)->ReleaseCharArrayElements(env, passwordObj, passwordChars,
+                JNI_ABORT);
+        }
     }
 
     paramBlock.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
--- a/src/share/classes/com/sun/crypto/provider/DESKey.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/com/sun/crypto/provider/DESKey.java	Tue Oct 24 23:16:46 2017 -0700
@@ -76,7 +76,7 @@
         DESKeyGenerator.setParityBit(this.key, 0);
     }
 
-    public byte[] getEncoded() {
+    public synchronized byte[] getEncoded() {
         // Return a copy of the key, rather than a reference,
         // so that the key data cannot be modified from outside
         return this.key.clone();
@@ -151,9 +151,11 @@
      */
     protected void finalize() throws Throwable {
         try {
-            if (this.key != null) {
-                java.util.Arrays.fill(this.key, (byte)0x00);
-                this.key = null;
+            synchronized (this) {
+                if (this.key != null) {
+                    java.util.Arrays.fill(this.key, (byte)0x00);
+                    this.key = null;
+                }
             }
         } finally {
             super.finalize();
--- a/src/share/classes/com/sun/crypto/provider/DESedeKey.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/com/sun/crypto/provider/DESedeKey.java	Tue Oct 24 23:16:46 2017 -0700
@@ -78,7 +78,7 @@
         DESKeyGenerator.setParityBit(this.key, 16);
     }
 
-    public byte[] getEncoded() {
+    public synchronized byte[] getEncoded() {
         return this.key.clone();
     }
 
@@ -152,9 +152,11 @@
      */
     protected void finalize() throws Throwable {
         try {
-            if (this.key != null) {
-                java.util.Arrays.fill(this.key, (byte)0x00);
-                this.key = null;
+            synchronized (this) {
+                if (this.key != null) {
+                    java.util.Arrays.fill(this.key, (byte)0x00);
+                    this.key = null;
+                }
             }
         } finally {
             super.finalize();
--- a/src/share/classes/com/sun/crypto/provider/PBEKey.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/com/sun/crypto/provider/PBEKey.java	Tue Oct 24 23:16:46 2017 -0700
@@ -72,7 +72,7 @@
         type = keytype;
     }
 
-    public byte[] getEncoded() {
+    public synchronized byte[] getEncoded() {
         return this.key.clone();
     }
 
@@ -147,9 +147,11 @@
      */
     protected void finalize() throws Throwable {
         try {
-            if (this.key != null) {
-                java.util.Arrays.fill(this.key, (byte)0x00);
-                this.key = null;
+            synchronized (this) {
+                if (this.key != null) {
+                    java.util.Arrays.fill(this.key, (byte)0x00);
+                    this.key = null;
+                }
             }
         } finally {
             super.finalize();
--- a/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Tue Oct 24 23:16:46 2017 -0700
@@ -190,7 +190,7 @@
         return key;
     }
 
-    public byte[] getEncoded() {
+    public synchronized byte[] getEncoded() {
         return key.clone();
     }
 
@@ -202,7 +202,7 @@
         return iterCount;
     }
 
-    public char[] getPassword() {
+    public synchronized char[] getPassword() {
         return passwd.clone();
     }
 
@@ -264,13 +264,15 @@
      */
     protected void finalize() throws Throwable {
         try {
-            if (this.passwd != null) {
-                java.util.Arrays.fill(this.passwd, '0');
-                this.passwd = null;
-            }
-            if (this.key != null) {
-                java.util.Arrays.fill(this.key, (byte)0x00);
-                this.key = null;
+            synchronized (this) {
+                if (this.passwd != null) {
+                    java.util.Arrays.fill(this.passwd, '0');
+                    this.passwd = null;
+                }
+                if (this.key != null) {
+                    java.util.Arrays.fill(this.key, (byte)0x00);
+                    this.key = null;
+                }
             }
         } finally {
             super.finalize();
--- a/src/share/classes/com/sun/jmx/remote/internal/RMIExporter.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/com/sun/jmx/remote/internal/RMIExporter.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 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
@@ -25,6 +25,7 @@
 
 package com.sun.jmx.remote.internal;
 
+import sun.misc.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/share/classes/com/sun/jmx/remote/util/EnvHelp.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,6 +1,6 @@
 
 /*
- * 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
@@ -70,6 +70,61 @@
             "jmx.remote.rmi.server.credential.types";
 
     /**
+    * 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>
+    * The filter pattern must be in same format as used in
+    * {@link java.io.ObjectInputFilter.Config.createFilter}
+    * <p>
+    * 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 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.RMIConnectorClient}
+     * 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>Name of the attribute that specifies a default class loader
      * object.
      * The value associated with this attribute is a ClassLoader object</p>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/jndi/dns/DNSDatagramSocketFactory.java	Tue Oct 24 23:16:46 2017 -0700
@@ -0,0 +1,246 @@
+/*
+ * 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 com.sun.jndi.dns;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.ProtocolFamily;
+import java.net.SocketException;
+import java.net.InetSocketAddress;
+import java.nio.channels.DatagramChannel;
+import java.util.Objects;
+import java.util.Random;
+
+class DNSDatagramSocketFactory {
+    static final int DEVIATION = 3;
+    static final int THRESHOLD = 6;
+    static final int BIT_DEVIATION = 2;
+    static final int HISTORY = 32;
+    static final int MAX_RANDOM_TRIES = 5;
+    /**
+     * The dynamic allocation port range (aka ephemeral ports), as configured
+     * on the system. Use nested class for lazy evaluation.
+     */
+    static final class EphemeralPortRange {
+        private EphemeralPortRange() {}
+        static final int LOWER = sun.net.PortConfig.getLower();
+        static final int UPPER = sun.net.PortConfig.getUpper();
+        static final int RANGE = UPPER - LOWER + 1;
+    }
+
+    // Records a subset of max {@code capacity} previously used ports
+    static final class PortHistory {
+        final int capacity;
+        final int[] ports;
+        final Random random;
+        int index;
+        PortHistory(int capacity, Random random) {
+            this.random = random;
+            this.capacity = capacity;
+            this.ports = new int[capacity];
+        }
+        // returns true if the history contains the specified port.
+        public boolean contains(int port) {
+            int p = 0;
+            for (int i=0; i<capacity; i++) {
+                if ((p = ports[i]) == 0 || p == port) break;
+            }
+            return p == port;
+        }
+        // Adds the port to the history - doesn't check whether the port
+        // is already present. Always adds the port and always return true.
+        public boolean add(int port) {
+            if (ports[index] != 0) { // at max capacity
+                // remove one port at random and store the new port there
+                ports[random.nextInt(capacity)] = port;
+            } else { // there's a free slot
+                ports[index] = port;
+            }
+            if (++index == capacity) index = 0;
+            return true;
+        }
+        // Adds the port to the history if not already present.
+        // Return true if the port was added, false if the port was already
+        // present.
+        public boolean offer(int port) {
+            if (contains(port)) return false;
+            else return add(port);
+        }
+    }
+
+    int lastport = 0;
+    int suitablePortCount;
+    int unsuitablePortCount;
+    final ProtocolFamily family; // null (default) means dual stack
+    final int thresholdCount; // decision point
+    final int deviation;
+    final Random random;
+    final PortHistory history;
+
+    DNSDatagramSocketFactory() {
+        this(new Random());
+    }
+
+    DNSDatagramSocketFactory(Random random) {
+        this(Objects.requireNonNull(random), null, DEVIATION, THRESHOLD);
+    }
+    DNSDatagramSocketFactory(Random random,
+                             ProtocolFamily family,
+                             int deviation,
+                             int threshold) {
+        this.random = Objects.requireNonNull(random);
+        this.history = new PortHistory(HISTORY, random);
+        this.family = family;
+        this.deviation = Math.max(1, deviation);
+        this.thresholdCount = Math.max(2, threshold);
+    }
+
+    /**
+     * Opens a datagram socket listening to the wildcard address on a
+     * random port. If the underlying OS supports UDP port randomization
+     * out of the box (if binding a socket to port 0 binds it to a random
+     * port) then the underlying OS implementation is used. Otherwise, this
+     * method will allocate and bind a socket on a randomly selected ephemeral
+     * port in the dynamic range.
+     * @return A new DatagramSocket bound to a random port.
+     * @throws SocketException if the socket cannot be created.
+     */
+    public synchronized DatagramSocket open() throws SocketException {
+        int lastseen = lastport;
+        DatagramSocket s;
+
+        boolean thresholdCrossed = unsuitablePortCount > thresholdCount;
+        if (thresholdCrossed) {
+            // Underlying stack does not support random UDP port out of the box.
+            // Use our own algorithm to allocate a random UDP port
+            s = openRandom();
+            if (s != null) return s;
+
+            // couldn't allocate a random port: reset all counters and fall
+            // through.
+            unsuitablePortCount = 0; suitablePortCount = 0; lastseen = 0;
+        }
+
+        // Allocate an ephemeral port (port 0)
+        s = openDefault();
+        lastport = s.getLocalPort();
+        if (lastseen == 0) {
+            history.offer(lastport);
+            return s;
+        }
+
+        thresholdCrossed = suitablePortCount > thresholdCount;
+        boolean farEnough = Integer.bitCount(lastseen ^ lastport) > BIT_DEVIATION
+                            && Math.abs(lastport - lastseen) > deviation;
+        boolean recycled = history.contains(lastport);
+        boolean suitable = (thresholdCrossed || farEnough && !recycled);
+        if (suitable && !recycled) history.add(lastport);
+
+        if (suitable) {
+            if (!thresholdCrossed) {
+                suitablePortCount++;
+            } else if (!farEnough || recycled) {
+                unsuitablePortCount = 1;
+                suitablePortCount = thresholdCount/2;
+            }
+            // Either the underlying stack supports random UDP port allocation,
+            // or the new port is sufficiently distant from last port to make
+            // it look like it is. Let's use it.
+            return s;
+        }
+
+        // Undecided... the new port was too close. Let's allocate a random
+        // port using our own algorithm
+        assert !thresholdCrossed;
+        DatagramSocket ss = openRandom();
+        if (ss == null) return s;
+        unsuitablePortCount++;
+        s.close();
+        return ss;
+    }
+
+    private DatagramSocket openDefault() throws SocketException {
+        if (family != null) {
+            try {
+                DatagramChannel c = DatagramChannel.open(family);
+                try {
+                    DatagramSocket s = c.socket();
+                    s.bind(null);
+                    return s;
+                } catch (Throwable x) {
+                    c.close();
+                    throw x;
+                }
+            } catch (SocketException x) {
+                throw x;
+            } catch (IOException x) {
+                SocketException e = new SocketException(x.getMessage());
+                e.initCause(x);
+                throw e;
+            }
+        }
+        return new DatagramSocket();
+    }
+
+    synchronized boolean isUsingNativePortRandomization() {
+        return  unsuitablePortCount <= thresholdCount
+                && suitablePortCount > thresholdCount;
+    }
+
+    synchronized boolean isUsingJavaPortRandomization() {
+        return unsuitablePortCount > thresholdCount ;
+    }
+
+    synchronized boolean isUndecided() {
+        return !isUsingJavaPortRandomization()
+                && !isUsingNativePortRandomization();
+    }
+
+    private DatagramSocket openRandom() {
+        int maxtries = MAX_RANDOM_TRIES;
+        while (maxtries-- > 0) {
+            int port = EphemeralPortRange.LOWER
+                    + random.nextInt(EphemeralPortRange.RANGE);
+            try {
+                if (family != null) {
+                    DatagramChannel c = DatagramChannel.open(family);
+                    try {
+                        DatagramSocket s = c.socket();
+                        s.bind(new InetSocketAddress(port));
+                        return s;
+                    } catch (Throwable x) {
+                        c.close();
+                        throw x;
+                    }
+                }
+                return new DatagramSocket(port);
+            } catch (IOException x) {
+                // try again until maxtries == 0;
+            }
+        }
+        return null;
+    }
+
+}
--- a/src/share/classes/com/sun/jndi/dns/DnsClient.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/com/sun/jndi/dns/DnsClient.java	Tue Oct 24 23:16:46 2017 -0700
@@ -85,7 +85,9 @@
     private int timeout;                // initial timeout on UDP queries in ms
     private int retries;                // number of UDP retries
 
-    private DatagramSocket udpSocket;
+    private final Object udpSocketLock = new Object();
+    private static final DNSDatagramSocketFactory factory =
+            new DNSDatagramSocketFactory(random);
 
     // Requests sent
     private Map<Integer, ResourceRecord> reqs;
@@ -105,14 +107,6 @@
             throws NamingException {
         this.timeout = timeout;
         this.retries = retries;
-        try {
-            udpSocket = new DatagramSocket();
-        } catch (java.net.SocketException e) {
-            NamingException ne = new ConfigurationException();
-            ne.setRootCause(e);
-            throw ne;
-        }
-
         this.servers = new InetAddress[servers.length];
         serverPorts = new int[servers.length];
 
@@ -142,6 +136,16 @@
         resps = Collections.synchronizedMap(new HashMap<Integer, byte[]>());
     }
 
+    DatagramSocket getDatagramSocket() throws NamingException {
+        try {
+            return factory.open();
+        } catch (java.net.SocketException e) {
+            NamingException ne = new ConfigurationException();
+            ne.setRootCause(e);
+            throw ne;
+        }
+    }
+
     protected void finalize() {
         close();
     }
@@ -150,7 +154,6 @@
     private Object queuesLock = new Object();
 
     public void close() {
-        udpSocket.close();
         synchronized (queuesLock) {
             reqs.clear();
             resps.clear();
@@ -392,44 +395,45 @@
 
         int minTimeout = 50; // msec after which there are no retries.
 
-        synchronized (udpSocket) {
-            DatagramPacket opkt = new DatagramPacket(
-                    pkt.getData(), pkt.length(), server, port);
-            DatagramPacket ipkt = new DatagramPacket(new byte[8000], 8000);
-            // Packets may only be sent to or received from this server address
-            udpSocket.connect(server, port);
-            int pktTimeout = (timeout * (1 << retry));
-            try {
-                udpSocket.send(opkt);
+        synchronized (udpSocketLock) {
+            try (DatagramSocket udpSocket = getDatagramSocket()) {
+                DatagramPacket opkt = new DatagramPacket(
+                        pkt.getData(), pkt.length(), server, port);
+                DatagramPacket ipkt = new DatagramPacket(new byte[8000], 8000);
+                // Packets may only be sent to or received from this server address
+                udpSocket.connect(server, port);
+                int pktTimeout = (timeout * (1 << retry));
+                try {
+                    udpSocket.send(opkt);
 
-                // timeout remaining after successive 'receive()'
-                int timeoutLeft = pktTimeout;
-                int cnt = 0;
-                do {
-                    if (debug) {
-                       cnt++;
-                        dprint("Trying RECEIVE(" +
-                                cnt + ") retry(" + (retry + 1) +
-                                ") for:" + xid  + "    sock-timeout:" +
-                                timeoutLeft + " ms.");
-                    }
-                    udpSocket.setSoTimeout(timeoutLeft);
-                    long start = System.currentTimeMillis();
-                    udpSocket.receive(ipkt);
-                    long end = System.currentTimeMillis();
+                    // timeout remaining after successive 'receive()'
+                    int timeoutLeft = pktTimeout;
+                    int cnt = 0;
+                    do {
+                        if (debug) {
+                           cnt++;
+                            dprint("Trying RECEIVE(" +
+                                    cnt + ") retry(" + (retry + 1) +
+                                    ") for:" + xid  + "    sock-timeout:" +
+                                    timeoutLeft + " ms.");
+                        }
+                        udpSocket.setSoTimeout(timeoutLeft);
+                        long start = System.currentTimeMillis();
+                        udpSocket.receive(ipkt);
+                        long end = System.currentTimeMillis();
 
-                    byte[] data = new byte[ipkt.getLength()];
-                    data = ipkt.getData();
-                    if (isMatchResponse(data, xid)) {
-                        return data;
-                    }
-                    timeoutLeft = pktTimeout - ((int) (end - start));
-                } while (timeoutLeft > minTimeout);
+                        byte[] data = ipkt.getData();
+                        if (isMatchResponse(data, xid)) {
+                            return data;
+                        }
+                        timeoutLeft = pktTimeout - ((int) (end - start));
+                    } while (timeoutLeft > minTimeout);
 
-            } finally {
-                udpSocket.disconnect();
+                } finally {
+                    udpSocket.disconnect();
+                }
+                return null; // no matching packet received within the timeout
             }
-            return null; // no matching packet received within the timeout
         }
     }
 
--- a/src/share/classes/com/sun/jndi/dns/ResourceRecord.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/com/sun/jndi/dns/ResourceRecord.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2002, 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
@@ -25,8 +25,13 @@
 
 package com.sun.jndi.dns;
 
+import javax.naming.CommunicationException;
 import javax.naming.InvalidNameException;
 
+import java.io.IOException;
+
+import java.nio.charset.StandardCharsets;
+
 
 /**
  * The ResourceRecord class represents a DNS resource record.
@@ -84,6 +89,11 @@
         null, "IN", null, null, "HS"
     };
 
+    /*
+     * Maximum number of compression references in labels.
+     * Used to detect compression loops.
+     */
+    private static final int MAXIMUM_COMPRESSION_REFERENCES = 16;
 
     byte[] msg;                 // DNS message
     int msgLen;                 // msg size (in octets)
@@ -110,12 +120,12 @@
      * false, the rdata is not decoded (and getRdata() will return null)
      * unless this is an SOA record.
      *
-     * @throws InvalidNameException if a decoded domain name isn't valid.
+     * @throws CommunicationException if a decoded domain name isn't valid.
      * @throws ArrayIndexOutOfBoundsException given certain other corrupt data.
      */
     ResourceRecord(byte[] msg, int msgLen, int offset,
                    boolean qSection, boolean decodeRdata)
-            throws InvalidNameException {
+            throws CommunicationException {
 
         this.msg = msg;
         this.msgLen = msgLen;
@@ -235,7 +245,7 @@
      * Decodes the binary format of the RR.
      * May throw ArrayIndexOutOfBoundsException given corrupt data.
      */
-    private void decode(boolean decodeRdata) throws InvalidNameException {
+    private void decode(boolean decodeRdata) throws CommunicationException {
         int pos = offset;       // index of next unread octet
 
         name = new DnsName();                           // NAME
@@ -316,7 +326,7 @@
     /*
      * Returns the name encoded at msg[pos], including the root label.
      */
-    private DnsName decodeName(int pos) throws InvalidNameException {
+    private DnsName decodeName(int pos) throws CommunicationException {
         DnsName n = new DnsName();
         decodeName(pos, n);
         return n;
@@ -326,22 +336,50 @@
      * Prepends to "n" the domain name encoded at msg[pos], including the root
      * label.  Returns the index into "msg" following the name.
      */
-    private int decodeName(int pos, DnsName n) throws InvalidNameException {
-        if (msg[pos] == 0) {                            // end of name
-            n.add(0, "");
-            return (pos + 1);
-        } else if ((msg[pos] & 0xC0) != 0) {            // name compression
-            decodeName(getUShort(pos) & 0x3FFF, n);
-            return (pos + 2);
-        } else {                                        // append a label
-            int len = msg[pos++];
-            try {
-                n.add(0, new String(msg, pos, len, "ISO-8859-1"));
-            } catch (java.io.UnsupportedEncodingException e) {
-                // assert false : "ISO-Latin-1 charset unavailable";
+    private int decodeName(int pos, DnsName n) throws CommunicationException {
+        int endPos = -1;
+        int level = 0;
+        try {
+            while (true) {
+                if (level > MAXIMUM_COMPRESSION_REFERENCES)
+                    throw new IOException("Too many compression references");
+                int typeAndLen = msg[pos] & 0xFF;
+                if (typeAndLen == 0) {                  // end of name
+                    ++pos;
+                    n.add(0, "");
+                    break;
+                } else if (typeAndLen <= 63) {          // regular label
+                    ++pos;
+                    n.add(0, new String(msg, pos, typeAndLen,
+                        StandardCharsets.ISO_8859_1));
+                    pos += typeAndLen;
+                } else if ((typeAndLen & 0xC0) == 0xC0) { // name compression
+                    ++level;
+                    // cater for the case where the name pointed to is itself
+                    // compressed: we don't want endPos to be reset by the second
+                    // compression level.
+                    int ppos = pos;
+                    if (endPos == -1) endPos = pos + 2;
+                    pos = getUShort(pos) & 0x3FFF;
+                    if (debug) {
+                        dprint("decode: name compression at " + ppos
+                                + " -> " + pos + " endPos=" + endPos);
+                        assert endPos > 0;
+                        assert pos < ppos;
+                        assert pos >= Header.HEADER_SIZE;
+                    }
+                } else
+                    throw new IOException("Invalid label type: " + typeAndLen);
             }
-            return decodeName(pos + len, n);
+        } catch (IOException | InvalidNameException e) {
+            CommunicationException ce =new CommunicationException(
+                "DNS error: malformed packet");
+            ce.initCause(e);
+            throw ce;
         }
+        if (endPos == -1)
+            endPos = pos;
+        return endPos;
     }
 
     /*
@@ -352,7 +390,7 @@
      * The rdata of records with unknown type/class combinations is
      * returned in a newly-allocated byte array.
      */
-    private Object decodeRdata(int pos) throws InvalidNameException {
+    private Object decodeRdata(int pos) throws CommunicationException {
         if (rrclass == CLASS_INTERNET) {
             switch (rrtype) {
             case TYPE_A:
@@ -378,6 +416,11 @@
             }
         }
         // Unknown RR type/class
+        if (debug) {
+            dprint("Unknown RR type for RR data: " + rrtype + " rdlen=" + rdlen
+                   + ", pos=" + pos +", msglen=" + msg.length + ", remaining="
+                   + (msg.length-pos));
+        }
         byte[] rd = new byte[rdlen];
         System.arraycopy(msg, pos, rd, 0, rdlen);
         return rd;
@@ -386,7 +429,7 @@
     /*
      * Returns the rdata of an MX record that is encoded at msg[pos].
      */
-    private String decodeMx(int pos) throws InvalidNameException {
+    private String decodeMx(int pos) throws CommunicationException {
         int preference = getUShort(pos);
         pos += 2;
         DnsName name = decodeName(pos);
@@ -396,7 +439,7 @@
     /*
      * Returns the rdata of an SOA record that is encoded at msg[pos].
      */
-    private String decodeSoa(int pos) throws InvalidNameException {
+    private String decodeSoa(int pos) throws CommunicationException {
         DnsName mname = new DnsName();
         pos = decodeName(pos, mname);
         DnsName rname = new DnsName();
@@ -421,7 +464,7 @@
      * Returns the rdata of an SRV record that is encoded at msg[pos].
      * See RFC 2782.
      */
-    private String decodeSrv(int pos) throws InvalidNameException {
+    private String decodeSrv(int pos) throws CommunicationException {
         int priority = getUShort(pos);
         pos += 2;
         int weight =   getUShort(pos);
@@ -436,7 +479,7 @@
      * Returns the rdata of an NAPTR record that is encoded at msg[pos].
      * See RFC 2915.
      */
-    private String decodeNaptr(int pos) throws InvalidNameException {
+    private String decodeNaptr(int pos) throws CommunicationException {
         int order = getUShort(pos);
         pos += 2;
         int preference = getUShort(pos);
@@ -586,4 +629,15 @@
 
         return buf.toString();
     }
+
+    //-------------------------------------------------------------------------
+
+    private static final boolean debug = false;
+
+    private static void dprint(String mess) {
+        if (debug) {
+            System.err.println("DNS: " + mess);
+        }
+    }
+
 }
--- a/src/share/classes/com/sun/security/auth/module/LdapLoginModule.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/com/sun/security/auth/module/LdapLoginModule.java	Tue Oct 24 23:16:46 2017 -0700
@@ -751,7 +751,8 @@
 
         if (authFirst || authOnly) {
 
-            String id = replaceUsernameToken(identityMatcher, authcIdentity);
+            String id =
+                replaceUsernameToken(identityMatcher, authcIdentity, username);
 
             // Prepare to bind using user's username and password
             ldapEnvironment.put(Context.SECURITY_CREDENTIALS, password);
@@ -878,8 +879,13 @@
         }
 
         try {
-            NamingEnumeration<SearchResult> results = ctx.search("",
-                replaceUsernameToken(filterMatcher, userFilter), constraints);
+            // Sanitize username and substitute into LDAP filter
+            String canonicalUserFilter =
+                replaceUsernameToken(filterMatcher, userFilter,
+                    escapeUsernameChars());
+
+            NamingEnumeration<SearchResult> results =
+                ctx.search("", canonicalUserFilter, constraints);
 
             // Extract the distinguished name of the user's entry
             // (Use the first entry if more than one is returned)
@@ -927,12 +933,61 @@
     }
 
     /**
+     * Modify the supplied username to encode characters that must be escaped
+     * according to RFC 4515: LDAP: String Representation of Search Filters.
+     *
+     * The following characters are encoded as a backslash "\" (ASCII 0x5c)
+     * followed by the two hexadecimal digits representing the value of the
+     * escaped character:
+     *     '*' (ASCII 0x2a)
+     *     '(' (ASCII 0x28)
+     *     ')' (ASCII 0x29)
+     *     '\' (ASCII 0x5c)
+     *     '\0'(ASCII 0x00)
+     *
+     * @return the modified username with its characters escaped as needed
+     */
+    private String escapeUsernameChars() {
+        int len = username.length();
+        StringBuilder escapedUsername = new StringBuilder(len + 16);
+
+        for (int i = 0; i < len; i++) {
+            char c = username.charAt(i);
+            switch (c) {
+            case '*':
+                escapedUsername.append("\\\\2A");
+                break;
+            case '(':
+                escapedUsername.append("\\\\28");
+                break;
+            case ')':
+                escapedUsername.append("\\\\29");
+                break;
+            case '\\':
+                escapedUsername.append("\\\\5C");
+                break;
+            case '\0':
+                escapedUsername.append("\\\\00");
+                break;
+            default:
+                escapedUsername.append(c);
+            }
+        }
+
+        return escapedUsername.toString();
+    }
+
+
+    /**
      * Replace the username token
      *
+     * @param matcher the replacement pattern
      * @param string the target string
+     * @param username the supplied username
      * @return the modified string
      */
-    private String replaceUsernameToken(Matcher matcher, String string) {
+    private String replaceUsernameToken(Matcher matcher, String string,
+        String username) {
         return matcher != null ? matcher.replaceAll(username) : string;
     }
 
--- a/src/share/classes/java/awt/color/ICC_ColorSpace.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/java/awt/color/ICC_ColorSpace.java	Tue Oct 24 23:16:46 2017 -0700
@@ -128,6 +128,18 @@
     }
 
     /**
+     * Validate ICC_ColorSpace read from an object input stream
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws ClassNotFoundException, java.io.IOException {
+
+        s.defaultReadObject();
+        if (thisProfile == null) {
+            thisProfile = ICC_Profile.getInstance(ColorSpace.CS_sRGB);
+        }
+    }
+
+    /**
     * Returns the ICC_Profile for this ICC_ColorSpace.
     * @return the ICC_Profile for this ICC_ColorSpace.
     */
--- a/src/share/classes/java/io/ObjectInputStream.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/java/io/ObjectInputStream.java	Tue Oct 24 23:16:46 2017 -0700
@@ -45,7 +45,6 @@
 
 import sun.misc.SharedSecrets;
 import sun.misc.ObjectInputFilter;
-import sun.misc.ObjectStreamClassValidator;
 import sun.reflect.misc.ReflectUtil;
 import sun.misc.JavaOISAccess;
 import sun.util.logging.PlatformLogger;
@@ -1749,9 +1748,6 @@
                 throw new StreamCorruptedException(
                     String.format("invalid type code: %02X", tc));
         }
-        if (descriptor != null) {
-            validateDescriptor(descriptor);
-        }
         return descriptor;
     }
 
@@ -3896,21 +3892,4 @@
             throw new AssertionError();
         }
     }
-
-    private void validateDescriptor(ObjectStreamClass descriptor) {
-        ObjectStreamClassValidator validating = validator;
-        if (validating != null) {
-            validating.validateDescriptor(descriptor);
-        }
-    }
-
-    // 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/share/classes/java/lang/invoke/DirectMethodHandle.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/java/lang/invoke/DirectMethodHandle.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -75,13 +75,20 @@
             mtype = mtype.insertParameterTypes(0, receiver);
         }
         if (!member.isField()) {
-            if (refKind == REF_invokeSpecial) {
-                member = member.asSpecial();
-                LambdaForm lform = preparedLambdaForm(member);
-                return new Special(mtype, lform, member);
-            } else {
-                LambdaForm lform = preparedLambdaForm(member);
-                return new DirectMethodHandle(mtype, lform, member);
+            switch (refKind) {
+                case REF_invokeSpecial: {
+                    member = member.asSpecial();
+                    LambdaForm lform = preparedLambdaForm(member);
+                    return new Special(mtype, lform, member);
+                }
+                case REF_invokeInterface: {
+                    LambdaForm lform = preparedLambdaForm(member);
+                    return new Interface(mtype, lform, member, receiver);
+                }
+                default: {
+                    LambdaForm lform = preparedLambdaForm(member);
+                    return new DirectMethodHandle(mtype, lform, member);
+                }
             }
         } else {
             LambdaForm lform = preparedFieldLambdaForm(member);
@@ -191,6 +198,7 @@
     private static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
         boolean needsInit = (which == LF_INVSTATIC_INIT);
         boolean doesAlloc = (which == LF_NEWINVSPECIAL);
+        boolean needsReceiverCheck = (which == LF_INVINTERFACE);
         String linkerName, lambdaName;
         switch (which) {
         case LF_INVVIRTUAL:    linkerName = "linkToVirtual";    lambdaName = "DMH.invokeVirtual";    break;
@@ -218,6 +226,7 @@
         int nameCursor = ARG_LIMIT;
         final int NEW_OBJ     = (doesAlloc ? nameCursor++ : -1);
         final int GET_MEMBER  = nameCursor++;
+        final int CHECK_RECEIVER = (needsReceiverCheck ? nameCursor++ : -1);
         final int LINKER_CALL = nameCursor++;
         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
         assert(names.length == nameCursor);
@@ -232,6 +241,10 @@
         }
         assert(findDirectMethodHandle(names[GET_MEMBER]) == names[DMH_THIS]);
         Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
+        if (needsReceiverCheck) {
+            names[CHECK_RECEIVER] = new Name(Lazy.NF_checkReceiver, names[DMH_THIS], names[ARG_BASE]);
+            outArgs[0] = names[CHECK_RECEIVER];
+        }
         assert(outArgs[outArgs.length-1] == names[GET_MEMBER]);  // look, shifted args!
         int result = LAST_RESULT;
         if (doesAlloc) {
@@ -375,6 +388,29 @@
         }
     }
 
+    /** This subclass represents invokeinterface instructions. */
+    static class Interface extends DirectMethodHandle {
+        private final Class<?> refc;
+        private Interface(MethodType mtype, LambdaForm form, MemberName member, Class<?> refc) {
+            super(mtype, form, member);
+            assert refc.isInterface() : refc;
+            this.refc = refc;
+        }
+        @Override
+        MethodHandle copyWith(MethodType mt, LambdaForm lf) {
+            return new Interface(mt, lf, member, refc);
+        }
+
+        Object checkReceiver(Object recv) {
+            if (!refc.isInstance(recv)) {
+                String msg = String.format("Class %s does not implement the requested interface %s",
+                        recv.getClass().getName(), refc.getName());
+                throw new IncompatibleClassChangeError(msg);
+            }
+            return recv;
+        }
+    }
+
     /** This subclass handles constructor references. */
     static class Constructor extends DirectMethodHandle {
         final MemberName initMethod;
@@ -657,7 +693,8 @@
                 NF_staticOffset,
                 NF_checkCast,
                 NF_allocateInstance,
-                NF_constructorMethod;
+                NF_constructorMethod,
+                NF_checkReceiver;
         static {
             try {
                 NamedFunction nfs[] = {
@@ -680,7 +717,9 @@
                         NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
                                 .getDeclaredMethod("allocateInstance", Object.class)),
                         NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
-                                .getDeclaredMethod("constructorMethod", Object.class))
+                                .getDeclaredMethod("constructorMethod", Object.class)),
+                        NF_checkReceiver = new NamedFunction(new MemberName(Interface.class
+                                .getDeclaredMethod("checkReceiver", Object.class)))
                 };
                 for (NamedFunction nf : nfs) {
                     // Each nf must be statically invocable or we get tied up in our bootstraps.
--- a/src/share/classes/java/util/ArrayList.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/java/util/ArrayList.java	Tue Oct 24 23:16:46 2017 -0700
@@ -225,7 +225,7 @@
             return Math.max(DEFAULT_CAPACITY, minCapacity);
         }
         return minCapacity;
-        }
+    }
 
     private void ensureCapacityInternal(int minCapacity) {
         ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
--- a/src/share/classes/java/util/HashMap.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/java/util/HashMap.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1398,7 +1398,7 @@
             // what we're actually creating.
             SharedSecrets.getJavaOISAccess().checkArray(s, Map.Entry[].class, cap);
             @SuppressWarnings({"rawtypes","unchecked"})
-                Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
+            Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
             table = tab;
 
             // Read the keys and values, and put the mappings in the HashMap
--- a/src/share/classes/java/util/ResourceBundle.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/java/util/ResourceBundle.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, 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
@@ -485,7 +485,7 @@
     }
 
     /**
-     * A wrapper of ClassLoader.getSystemClassLoader().
+     * A wrapper of Extension Class Loader
      */
     private static class RBClassLoader extends ClassLoader {
         private static final RBClassLoader INSTANCE = AccessController.doPrivileged(
@@ -494,7 +494,16 @@
                             return new RBClassLoader();
                         }
                     });
-        private static final ClassLoader loader = ClassLoader.getSystemClassLoader();
+        private static final ClassLoader loader;
+        static {
+            // Find the extension class loader.
+            ClassLoader ld = ClassLoader.getSystemClassLoader();
+            ClassLoader parent;
+            while ((parent = ld.getParent()) != null) {
+                ld = parent;
+            }
+            loader = ld;
+        }
 
         private RBClassLoader() {
         }
--- a/src/share/classes/java/util/logging/Level.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/java/util/logging/Level.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, 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
@@ -262,11 +262,17 @@
     }
 
     private String computeLocalizedLevelName(Locale newLocale) {
-        ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName, newLocale);
-        final String localizedName = rb.getString(name);
+        // If this is a custom Level, load resource bundles on the
+        // classpath and return.
+        if (!defaultBundle.equals(resourceBundleName)) {
+            return ResourceBundle.getBundle(resourceBundleName, newLocale,
+                       ClassLoader.getSystemClassLoader()).getString(name);
+        }
 
-        final boolean isDefaultBundle = defaultBundle.equals(resourceBundleName);
-        if (!isDefaultBundle) return localizedName;
+        // The default bundle "sun.util.logging.resources.logging" should only
+        // be loaded from the runtime; so use the extension class loader;
+        final ResourceBundle rb = ResourceBundle.getBundle(defaultBundle, newLocale);
+        final String localizedName = rb.getString(name);
 
         // This is a trick to determine whether the name has been translated
         // or not. If it has not been translated, we need to use Locale.ROOT
--- a/src/share/classes/java/util/logging/Logger.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/java/util/logging/Logger.java	Tue Oct 24 23:16:46 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
@@ -1817,8 +1817,7 @@
             public ResourceBundle run() {
                 try {
                     return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME,
-                                                    locale,
-                                                    ClassLoader.getSystemClassLoader());
+                                                    locale);
                 } catch (MissingResourceException e) {
                     throw new InternalError(e.toString());
                 }
--- a/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Tue Oct 24 23:16:46 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
@@ -33,6 +33,7 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import sun.misc.ObjectInputFilter;
 import java.io.ObjectOutputStream;
 import java.net.MalformedURLException;
 import java.rmi.server.RMIClientSocketFactory;
--- a/src/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java	Tue Oct 24 23:16:46 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
@@ -26,6 +26,7 @@
 package javax.management.remote.rmi;
 
 import java.io.IOException;
+import sun.misc.ObjectInputFilter;
 import java.rmi.NoSuchObjectException;
 import java.rmi.Remote;
 import java.rmi.RemoteException;
@@ -47,6 +48,11 @@
 import sun.rmi.server.DeserializationChecker;
 import sun.rmi.server.UnicastServerRef;
 import sun.rmi.server.UnicastServerRef2;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+import sun.rmi.transport.LiveRef;
+
 
 /**
  * <p>An {@link RMIServer} object that is exported through JRMP and that
@@ -59,8 +65,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>
@@ -101,31 +105,37 @@
 
         String[] credentialsTypes
                 = (String[]) this.env.get(EnvHelp.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 credentialsFilter
+                = (String) this.env.get(EnvHelp.CREDENTIALS_FILTER_PATTERN);
+
+        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(EnvHelp.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);
@@ -136,16 +146,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);
         }
     }
 
@@ -172,11 +180,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);
     }
 
     /**
@@ -206,7 +210,7 @@
         RMIConnection client =
             new RMIConnectionImpl(this, connectionId, getDefaultClassLoader(),
                                   subject, env);
-        export(client);
+        export(client, jmxRmiFilter);
         return client;
     }
 
@@ -223,56 +227,38 @@
      * 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/share/classes/javax/swing/UIDefaults.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/javax/swing/UIDefaults.java	Tue Oct 24 23:16:46 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
@@ -305,7 +305,8 @@
                     if (c != null) {
                         b = ResourceBundle.getBundle(bundleName, l, c);
                     } else {
-                        b = ResourceBundle.getBundle(bundleName, l);
+                        b = ResourceBundle.getBundle(bundleName, l,
+                                ClassLoader.getSystemClassLoader());
                     }
                     Enumeration keys = b.getKeys();
 
--- a/src/share/classes/javax/swing/text/DefaultEditorKit.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/javax/swing/text/DefaultEditorKit.java	Tue Oct 24 23:16:46 2017 -0700
@@ -109,7 +109,7 @@
      * @return the command list
      */
     public Action[] getActions() {
-        return defaultActions;
+        return defaultActions.clone();
     }
 
     /**
--- a/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Tue Oct 24 23:16:46 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
@@ -30,7 +30,7 @@
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.Serializable;
+import sun.misc.ObjectInputFilter;
 import java.lang.management.ManagementFactory;
 import java.net.InetAddress;
 import java.net.MalformedURLException;
@@ -43,7 +43,6 @@
 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;
@@ -83,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
@@ -141,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";
     }
 
     /**
@@ -181,7 +183,8 @@
         public Remote exportObject(Remote obj,
                 int port,
                 RMIClientSocketFactory csf,
-                RMIServerSocketFactory ssf)
+                RMIServerSocketFactory ssf,
+                ObjectInputFilter filter)
                 throws RemoteException {
 
             synchronized (this) {
@@ -192,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);
         }
@@ -434,6 +437,7 @@
 
         final String bindAddress =
                 props.getProperty(PropertyNames.HOST);
+        final String jmxRmiFilter = props.getProperty(PropertyNames.SERIAL_FILTER_PATTERN);
 
         if (log.debugOn()) {
             log.debug("startRemoteConnectorServer",
@@ -470,7 +474,7 @@
                     sslConfigFileName, enabledCipherSuitesList,
                     enabledProtocolsList, sslNeedClientAuth,
                     useAuthentication, loginConfigName,
-                    passwordFileName, accessFileName, bindAddress);
+                    passwordFileName, accessFileName, bindAddress, jmxRmiFilter);
             cs = data.jmxConnectorServer;
             url = data.jmxRemoteURL;
             log.config("startRemoteConnectorServer",
@@ -510,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(EnvHelp.CREDENTIAL_TYPES, new String[]{
-            String[].class.getName(), String.class.getName()
-        });
+        env.put(EnvHelp.CREDENTIALS_FILTER_PATTERN, String.class.getName() + ";!*");
 
         // The local connector server need only be available via the
         // loopback connection.
@@ -728,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
@@ -743,9 +746,11 @@
         PermanentExporter exporter = new PermanentExporter();
 
         env.put(RMIExporter.EXPORTER_ATTRIBUTE, exporter);
-        env.put(EnvHelp.CREDENTIAL_TYPES, new String[]{
-            String[].class.getName(), String.class.getName()
-        });
+        env.put(EnvHelp.CREDENTIALS_FILTER_PATTERN, String.class.getName() + ";!*");
+
+        if(jmxRmiFilter != null && !jmxRmiFilter.isEmpty()) {
+            env.put(EnvHelp.SERIAL_FILTER_PATTERN, jmxRmiFilter);
+        }
 
         boolean useSocketFactory = bindAddress != null && !useSsl;
 
--- a/src/share/classes/sun/management/jmxremote/SingleEntryRegistry.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/management/jmxremote/SingleEntryRegistry.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 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
@@ -46,7 +46,7 @@
 public class SingleEntryRegistry extends RegistryImpl {
     SingleEntryRegistry(int port, String name, Remote object)
             throws RemoteException {
-        super(port);
+        super(port, null, null, SingleEntryRegistry::singleRegistryFilter);
         this.name = name;
         this.object = object;
     }
--- a/src/share/classes/sun/misc/JavaObjectInputStreamAccess.java	Tue Oct 24 13:07:11 2017 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +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 sun.misc;
-
-import java.io.ObjectInputStream;
-
-/**
- * The interface to specify methods for accessing {@code ObjectInputStream}
- * @author sjiang
- */
-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);
-}
--- a/src/share/classes/sun/misc/ObjectStreamClassValidator.java	Tue Oct 24 13:07:11 2017 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +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 sun.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/share/classes/sun/misc/SharedSecrets.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/misc/SharedSecrets.java	Tue Oct 24 23:16:46 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
@@ -58,7 +58,6 @@
     private static JavaUtilZipFileAccess javaUtilZipFileAccess;
     private static JavaAWTAccess javaAWTAccess;
     private static JavaOISAccess javaOISAccess;
-    private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
 
     public static JavaUtilJarAccess javaUtilJarAccess() {
         if (javaUtilJarAccess == null) {
@@ -200,15 +199,4 @@
         }
         return javaAWTAccess;
     }
-
-    public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
-        if (javaObjectInputStreamAccess == null) {
-            unsafe.ensureClassInitialized(ObjectInputStream.class);
-        }
-        return javaObjectInputStreamAccess;
-    }
-
-    public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) {
-        javaObjectInputStreamAccess = access;
-    }
 }
--- a/src/share/classes/sun/rmi/registry/RegistryImpl.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/rmi/registry/RegistryImpl.java	Tue Oct 24 23:16:46 2017 -0700
@@ -170,7 +170,7 @@
             }
         } else {
             LiveRef lref = new LiveRef(id, port, csf, ssf);
-            setup(new UnicastServerRef2(lref, RegistryImpl::registryFilter));
+            setup(new UnicastServerRef2(lref, serialFilter));
         }
     }
 
--- a/src/share/classes/sun/rmi/server/MarshalInputStream.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/rmi/server/MarshalInputStream.java	Tue Oct 24 23:16:46 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
@@ -34,8 +34,6 @@
 import java.security.AccessControlException;
 import java.security.Permission;
 import java.rmi.server.RMIClassLoader;
-import sun.misc.ObjectStreamClassValidator;
-import sun.misc.SharedSecrets;
 
 /**
  * MarshalInputStream is an extension of ObjectInputStream.  When resolving
@@ -53,11 +51,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,
@@ -244,11 +237,6 @@
     protected Class<?> resolveProxyClass(String[] interfaces)
         throws IOException, ClassNotFoundException
     {
-        StreamChecker checker = streamChecker;
-        if (checker != null) {
-            checker.checkProxyInterfaceNames(interfaces);
-        }
-
         /*
          * Always read annotation written by MarshalOutputStream.
          */
@@ -328,28 +316,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/share/classes/sun/rmi/server/UnicastServerRef.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/rmi/server/UnicastServerRef.java	Tue Oct 24 23:16:46 2017 -0700
@@ -29,7 +29,6 @@
 import java.io.ObjectInput;
 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;
@@ -332,11 +331,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
@@ -605,84 +609,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/share/classes/sun/security/rsa/RSAPublicKeyImpl.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/rsa/RSAPublicKeyImpl.java	Tue Oct 24 23:16:46 2017 -0700
@@ -48,6 +48,7 @@
 public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
 
     private static final long serialVersionUID = 2644735423591199609L;
+    private static final BigInteger THREE = BigInteger.valueOf(3);
 
     private BigInteger n;       // modulus
     private BigInteger e;       // public exponent
@@ -61,6 +62,7 @@
         this.n = n;
         this.e = e;
         RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
+        checkExponentRange();
         // generate the encoding
         algid = RSAPrivateCrtKeyImpl.rsaId;
         try {
@@ -83,6 +85,19 @@
     public RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException {
         decode(encoded);
         RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
+        checkExponentRange();
+    }
+
+    private void checkExponentRange() throws InvalidKeyException {
+        // the exponent should be smaller than the modulus
+        if (e.compareTo(n) >= 0) {
+            throw new InvalidKeyException("exponent is larger than modulus");
+        }
+
+        // the exponent should be at least 3
+        if (e.compareTo(THREE) < 0) {
+            throw new InvalidKeyException("exponent is smaller than 3");
+        }
     }
 
     // see JCA doc
--- a/src/share/classes/sun/security/ssl/ClientHandshaker.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1381,12 +1381,12 @@
 
         // add elliptic curves and point format extensions
         if (cipherSuites.containsEC()) {
-            SupportedEllipticCurvesExtension ece =
-                SupportedEllipticCurvesExtension.createExtension(algorithmConstraints);
+            EllipticCurvesExtension ece =
+                EllipticCurvesExtension.createExtension(algorithmConstraints);
             if (ece != null) {
                 clientHelloMessage.extensions.add(ece);
                 clientHelloMessage.extensions.add(
-                   SupportedEllipticPointFormatsExtension.DEFAULT);
+                   EllipticPointFormatsExtension.DEFAULT);
             }
         }
 
--- a/src/share/classes/sun/security/ssl/ECDHCrypt.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/ssl/ECDHCrypt.java	Tue Oct 24 23:16:46 2017 -0700
@@ -60,7 +60,7 @@
         try {
             KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("EC");
             ECGenParameterSpec params =
-                    SupportedEllipticCurvesExtension.getECGenParamSpec(curveId);
+                    EllipticCurvesExtension.getECGenParamSpec(curveId);
             kpg.initialize(params, random);
             KeyPair kp = kpg.generateKeyPair();
             privateKey = kp.getPrivate();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/security/ssl/EllipticCurvesExtension.java	Tue Oct 24 23:16:46 2017 -0700
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2006, 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.ssl;
+
+import java.io.IOException;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.AlgorithmParameters;
+import java.security.AlgorithmConstraints;
+import java.security.CryptoPrimitive;
+import java.security.AccessController;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ArrayList;
+import javax.net.ssl.SSLProtocolException;
+
+import sun.security.action.GetPropertyAction;
+
+final class EllipticCurvesExtension extends HelloExtension {
+
+    /* Class and subclass dynamic debugging support */
+    private static final Debug debug = Debug.getInstance("ssl");
+
+    private static final int ARBITRARY_PRIME = 0xff01;
+    private static final int ARBITRARY_CHAR2 = 0xff02;
+
+    // speed up the searching
+    private static final Map<String, Integer> oidToIdMap = new HashMap<>();
+    private static final Map<Integer, String> idToOidMap = new HashMap<>();
+
+    // speed up the parameters construction
+    private static final Map<Integer,
+                AlgorithmParameters> idToParams = new HashMap<>();
+
+    // the supported elliptic curves
+    private static final int[] supportedCurveIds;
+
+    // the curves of the extension
+    private final int[] curveIds;
+
+    // See sun.security.util.CurveDB for the OIDs
+    private static enum NamedEllipticCurve {
+        T163_K1(1,  "sect163k1",    "1.3.132.0.1",      true),  // NIST K-163
+        T163_R1(2,  "sect163r1",    "1.3.132.0.2",      false),
+        T163_R2(3,  "sect163r2",    "1.3.132.0.15",     true),  // NIST B-163
+        T193_R1(4,  "sect193r1",    "1.3.132.0.24",     false),
+        T193_R2(5,  "sect193r2",    "1.3.132.0.25",     false),
+        T233_K1(6,  "sect233k1",    "1.3.132.0.26",     true),  // NIST K-233
+        T233_R1(7,  "sect233r1",    "1.3.132.0.27",     true),  // NIST B-233
+        T239_K1(8,  "sect239k1",    "1.3.132.0.3",      false),
+        T283_K1(9,  "sect283k1",    "1.3.132.0.16",     true),  // NIST K-283
+        T283_R1(10, "sect283r1",    "1.3.132.0.17",     true),  // NIST B-283
+        T409_K1(11, "sect409k1",    "1.3.132.0.36",     true),  // NIST K-409
+        T409_R1(12, "sect409r1",    "1.3.132.0.37",     true),  // NIST B-409
+        T571_K1(13, "sect571k1",    "1.3.132.0.38",     true),  // NIST K-571
+        T571_R1(14, "sect571r1",    "1.3.132.0.39",     true),  // NIST B-571
+
+        P160_K1(15, "secp160k1",    "1.3.132.0.9",      false),
+        P160_R1(16, "secp160r1",    "1.3.132.0.8",      false),
+        P160_R2(17, "secp160r2",    "1.3.132.0.30",     false),
+        P192_K1(18, "secp192k1",    "1.3.132.0.31",     false),
+        P192_R1(19, "secp192r1",    "1.2.840.10045.3.1.1", true), // NIST P-192
+        P224_K1(20, "secp224k1",    "1.3.132.0.32",     false),
+        P224_R1(21, "secp224r1",    "1.3.132.0.33",     true),  // NIST P-224
+        P256_K1(22, "secp256k1",    "1.3.132.0.10",     false),
+        P256_R1(23, "secp256r1",    "1.2.840.10045.3.1.7", true), // NIST P-256
+        P384_R1(24, "secp384r1",    "1.3.132.0.34",     true),  // NIST P-384
+        P521_R1(25, "secp521r1",    "1.3.132.0.35",     true);  // NIST P-521
+
+        int          id;
+        String       name;
+        String       oid;
+        boolean      isFips;
+
+        NamedEllipticCurve(int id, String name, String oid, boolean isFips) {
+            this.id = id;
+            this.name = name;
+            this.oid = oid;
+            this.isFips = isFips;
+
+            if (oidToIdMap.put(oid, id) != null ||
+                idToOidMap.put(id, oid) != null) {
+
+                throw new RuntimeException(
+                        "Duplicate named elliptic curve definition: " + name);
+            }
+        }
+
+        static NamedEllipticCurve getCurve(String name, boolean requireFips) {
+            for (NamedEllipticCurve curve : NamedEllipticCurve.values()) {
+                if (curve.name.equals(name) && (!requireFips || curve.isFips)) {
+                    return curve;
+                }
+            }
+
+            return null;
+        }
+    }
+
+    static {
+        boolean requireFips = SunJSSE.isFIPS();
+
+        // hack code to initialize NamedEllipticCurve
+        NamedEllipticCurve nec =
+                NamedEllipticCurve.getCurve("secp256r1", false);
+
+        // The value of the System Property defines a list of enabled named
+        // curves in preference order, separated with comma.  For example:
+        //
+        //      jdk.tls.namedGroups="secp521r1, secp256r1, secp384r1"
+        //
+        // If the System Property is not defined or the value is empty, the
+        // default curves and preferences will be used.
+        String property = AccessController.doPrivileged(
+                    new GetPropertyAction("jdk.tls.namedGroups"));
+        if (property != null && property.length() != 0) {
+            // remove double quote marks from beginning/end of the property
+            if (property.length() > 1 && property.charAt(0) == '"' &&
+                    property.charAt(property.length() - 1) == '"') {
+                property = property.substring(1, property.length() - 1);
+            }
+        }
+
+        ArrayList<Integer> idList;
+        if (property != null && property.length() != 0) {   // customized curves
+            String[] curves = property.split(",");
+            idList = new ArrayList<>(curves.length);
+            for (String curve : curves) {
+                curve = curve.trim();
+                if (!curve.isEmpty()) {
+                    NamedEllipticCurve namedCurve =
+                            NamedEllipticCurve.getCurve(curve, requireFips);
+                    if (namedCurve != null) {
+                        if (isAvailableCurve(namedCurve.id)) {
+                            idList.add(namedCurve.id);
+                        }
+                    }   // ignore unknown curves
+                }
+            }
+            if (idList.isEmpty() && JsseJce.isEcAvailable()) {
+                throw new IllegalArgumentException(
+                    "System property jdk.tls.namedGroups(" + property + ") " +
+                    "contains no supported elliptic curves");
+            }
+        } else {        // default curves
+            int[] ids;
+            if (requireFips) {
+                ids = new int[] {
+                    // only NIST curves in FIPS mode
+                    23, 24, 25, 9, 10, 11, 12, 13, 14,
+                };
+            } else {
+                ids = new int[] {
+                    // NIST curves first
+                    23, 24, 25, 9, 10, 11, 12, 13, 14,
+                    // non-NIST curves
+                    22,
+                };
+            }
+
+            idList = new ArrayList<>(ids.length);
+            for (int curveId : ids) {
+                if (isAvailableCurve(curveId)) {
+                    idList.add(curveId);
+                }
+            }
+        }
+
+        if (debug != null && idList.isEmpty()) {
+            debug.println(
+                "Initialized [jdk.tls.namedGroups|default] list contains " +
+                "no available elliptic curves. " +
+                (property != null ? "(" + property + ")" : "[Default]"));
+        }
+
+            supportedCurveIds = new int[idList.size()];
+            int i = 0;
+            for (Integer id : idList) {
+                supportedCurveIds[i++] = id;
+            }
+        }
+
+    // check whether the curve is supported by the underlying providers
+    private static boolean isAvailableCurve(int curveId) {
+        String oid = idToOidMap.get(curveId);
+        if (oid != null) {
+            AlgorithmParameters params = null;
+            try {
+                params = JsseJce.getAlgorithmParameters("EC");
+                params.init(new ECGenParameterSpec(oid));
+            } catch (Exception e) {
+                return false;
+            }
+
+            // cache the parameters
+            idToParams.put(curveId, params);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    private EllipticCurvesExtension(int[] curveIds) {
+        super(ExtensionType.EXT_ELLIPTIC_CURVES);
+        this.curveIds = curveIds;
+    }
+
+    EllipticCurvesExtension(HandshakeInStream s, int len)
+            throws IOException {
+        super(ExtensionType.EXT_ELLIPTIC_CURVES);
+        int k = s.getInt16();
+        if (((len & 1) != 0) || (k + 2 != len)) {
+            throw new SSLProtocolException("Invalid " + type + " extension");
+        }
+
+        // Note: unknown curves will be ignored later.
+        curveIds = new int[k >> 1];
+        for (int i = 0; i < curveIds.length; i++) {
+            curveIds[i] = s.getInt16();
+        }
+    }
+
+    // get the preferred active curve
+    static int getActiveCurves(AlgorithmConstraints constraints) {
+        return getPreferredCurve(supportedCurveIds, constraints);
+    }
+
+    static boolean hasActiveCurves(AlgorithmConstraints constraints) {
+        return getActiveCurves(constraints) >= 0;
+    }
+
+    static EllipticCurvesExtension createExtension(
+                AlgorithmConstraints constraints) {
+
+        ArrayList<Integer> idList = new ArrayList<>(supportedCurveIds.length);
+        for (int curveId : supportedCurveIds) {
+            if (constraints.permits(
+                    EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
+                                "EC", idToParams.get(curveId))) {
+                idList.add(curveId);
+            }
+        }
+
+        if (!idList.isEmpty()) {
+            int[] ids = new int[idList.size()];
+            int i = 0;
+            for (Integer id : idList) {
+                ids[i++] = id;
+            }
+
+            return new EllipticCurvesExtension(ids);
+        }
+
+        return null;
+    }
+
+    // get the preferred activated curve
+    int getPreferredCurve(AlgorithmConstraints constraints) {
+        return getPreferredCurve(curveIds, constraints);
+    }
+
+    // get a preferred activated curve
+    private static int getPreferredCurve(int[] curves,
+                AlgorithmConstraints constraints) {
+        for (int curveId : curves) {
+            if (isSupported(curveId) && constraints.permits(
+                    EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
+                                "EC", idToParams.get(curveId))) {
+                return curveId;
+            }
+        }
+
+        return -1;
+    }
+
+    boolean contains(int index) {
+        for (int curveId : curveIds) {
+            if (index == curveId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    int length() {
+        return 6 + (curveIds.length << 1);
+    }
+
+    @Override
+    void send(HandshakeOutStream s) throws IOException {
+        s.putInt16(type.id);
+        int k = curveIds.length << 1;
+        s.putInt16(k + 2);
+        s.putInt16(k);
+        for (int curveId : curveIds) {
+            s.putInt16(curveId);
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Extension " + type + ", curve names: {");
+        boolean first = true;
+        for (int curveId : curveIds) {
+            if (first) {
+                first = false;
+            } else {
+                sb.append(", ");
+            }
+            String curveName = getCurveName(curveId);
+            if (curveName != null) {
+                sb.append(curveName);
+            } else if (curveId == ARBITRARY_PRIME) {
+                sb.append("arbitrary_explicit_prime_curves");
+            } else if (curveId == ARBITRARY_CHAR2) {
+                sb.append("arbitrary_explicit_char2_curves");
+            } else {
+                sb.append("unknown curve " + curveId);
+            }
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+
+    // Test whether the given curve is supported.
+    static boolean isSupported(int index) {
+        for (int curveId : supportedCurveIds) {
+            if (index == curveId) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    static int getCurveIndex(ECParameterSpec params) {
+        String oid = JsseJce.getNamedCurveOid(params);
+        if (oid == null) {
+            return -1;
+        }
+        Integer n = oidToIdMap.get(oid);
+        return (n == null) ? -1 : n;
+    }
+
+    static String getCurveOid(int index) {
+        return idToOidMap.get(index);
+    }
+
+    static ECGenParameterSpec getECGenParamSpec(int index) {
+        AlgorithmParameters params = idToParams.get(index);
+        try {
+            return params.getParameterSpec(ECGenParameterSpec.class);
+        } catch (InvalidParameterSpecException ipse) {
+            // should be unlikely
+            String curveOid = getCurveOid(index);
+            return new ECGenParameterSpec(curveOid);
+        }
+    }
+
+    private static String getCurveName(int index) {
+        for (NamedEllipticCurve namedCurve : NamedEllipticCurve.values()) {
+            if (namedCurve.id == index) {
+                return namedCurve.name;
+            }
+        }
+
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/security/ssl/EllipticPointFormatsExtension.java	Tue Oct 24 23:16:46 2017 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2006, 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 sun.security.ssl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.net.ssl.SSLProtocolException;
+
+final class EllipticPointFormatsExtension extends HelloExtension {
+
+    final static int FMT_UNCOMPRESSED = 0;
+    final static int FMT_ANSIX962_COMPRESSED_PRIME = 1;
+    final static int FMT_ANSIX962_COMPRESSED_CHAR2 = 2;
+
+    static final HelloExtension DEFAULT =
+        new EllipticPointFormatsExtension(
+            new byte[] {FMT_UNCOMPRESSED});
+
+    private final byte[] formats;
+
+    private EllipticPointFormatsExtension(byte[] formats) {
+        super(ExtensionType.EXT_EC_POINT_FORMATS);
+        this.formats = formats;
+    }
+
+    EllipticPointFormatsExtension(HandshakeInStream s, int len)
+            throws IOException {
+        super(ExtensionType.EXT_EC_POINT_FORMATS);
+        formats = s.getBytes8();
+        // RFC 4492 says uncompressed points must always be supported.
+        // Check just to make sure.
+        boolean uncompressed = false;
+        for (int format : formats) {
+            if (format == FMT_UNCOMPRESSED) {
+                uncompressed = true;
+                break;
+            }
+        }
+        if (uncompressed == false) {
+            throw new SSLProtocolException
+                ("Peer does not support uncompressed points");
+        }
+    }
+
+    @Override
+    int length() {
+        return 5 + formats.length;
+    }
+
+    @Override
+    void send(HandshakeOutStream s) throws IOException {
+        s.putInt16(type.id);
+        s.putInt16(formats.length + 1);
+        s.putBytes8(formats);
+    }
+
+    private static String toString(byte format) {
+        int f = format & 0xff;
+        switch (f) {
+        case FMT_UNCOMPRESSED:
+            return "uncompressed";
+        case FMT_ANSIX962_COMPRESSED_PRIME:
+            return "ansiX962_compressed_prime";
+        case FMT_ANSIX962_COMPRESSED_CHAR2:
+            return "ansiX962_compressed_char2";
+        default:
+            return "unknown-" + f;
+        }
+    }
+
+    @Override
+    public String toString() {
+        List<String> list = new ArrayList<String>();
+        for (byte format : formats) {
+            list.add(toString(format));
+        }
+        return "Extension " + type + ", formats: " + list;
+    }
+}
--- a/src/share/classes/sun/security/ssl/HandshakeMessage.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/ssl/HandshakeMessage.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1010,7 +1010,7 @@
         ECParameterSpec params = publicKey.getParams();
         ECPoint point = publicKey.getW();
         pointBytes = JsseJce.encodePoint(point, params.getCurve());
-        curveId = SupportedEllipticCurvesExtension.getCurveIndex(params);
+        curveId = EllipticCurvesExtension.getCurveIndex(params);
 
         if (privateKey == null) {
             // ECDH_anon
@@ -1048,13 +1048,11 @@
         // the supported curves during the exchange of the Hello messages.
         if (curveType == CURVE_NAMED_CURVE) {
             curveId = input.getInt16();
-            if (SupportedEllipticCurvesExtension.isSupported(curveId)
-                    == false) {
+            if (!EllipticCurvesExtension.isSupported(curveId)) {
                 throw new SSLHandshakeException(
                     "Unsupported curveId: " + curveId);
             }
-            String curveOid =
-                SupportedEllipticCurvesExtension.getCurveOid(curveId);
+            String curveOid = EllipticCurvesExtension.getCurveOid(curveId);
             if (curveOid == null) {
                 throw new SSLHandshakeException(
                     "Unknown named curve: " + curveId);
--- a/src/share/classes/sun/security/ssl/Handshaker.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/ssl/Handshaker.java	Tue Oct 24 23:16:46 2017 -0700
@@ -647,7 +647,7 @@
                             boolean available = true;
                             if (suite.keyExchange.isEC) {
                                 if (!checkedCurves) {
-                                    hasCurves = SupportedEllipticCurvesExtension
+                                    hasCurves = EllipticCurvesExtension
                                         .hasActiveCurves(algorithmConstraints);
                                     checkedCurves = true;
 
@@ -738,7 +738,7 @@
                             boolean available = true;
                             if (suite.keyExchange.isEC) {
                                 if (!checkedCurves) {
-                                    hasCurves = SupportedEllipticCurvesExtension
+                                    hasCurves = EllipticCurvesExtension
                                         .hasActiveCurves(algorithmConstraints);
                                     checkedCurves = true;
 
--- a/src/share/classes/sun/security/ssl/HelloExtensions.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/ssl/HelloExtensions.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -49,8 +49,8 @@
  *      explicitly support.
  *  . ServerNameExtension: the server_name extension.
  *  . SignatureAlgorithmsExtension: the signature_algorithms extension.
- *  . SupportedEllipticCurvesExtension: the ECC supported curves extension.
- *  . SupportedEllipticPointFormatsExtension: the ECC supported point formats
+ *  . EllipticCurvesExtension: the ECC supported curves extension.
+ *  . EllipticPointFormatsExtension: the ECC supported point formats
  *      (compressed/uncompressed) extension.
  *
  * @since   1.6
@@ -79,10 +79,9 @@
             } else if (extType == ExtensionType.EXT_SIGNATURE_ALGORITHMS) {
                 extension = new SignatureAlgorithmsExtension(s, extlen);
             } else if (extType == ExtensionType.EXT_ELLIPTIC_CURVES) {
-                extension = new SupportedEllipticCurvesExtension(s, extlen);
+                extension = new EllipticCurvesExtension(s, extlen);
             } else if (extType == ExtensionType.EXT_EC_POINT_FORMATS) {
-                extension =
-                        new SupportedEllipticPointFormatsExtension(s, extlen);
+                extension = new EllipticPointFormatsExtension(s, extlen);
             } else if (extType == ExtensionType.EXT_RENEGOTIATION_INFO) {
                 extension = new RenegotiationInfoExtension(s, extlen);
             } else {
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java	Tue Oct 24 23:16:46 2017 -0700
@@ -93,7 +93,7 @@
     private ProtocolVersion clientRequestedVersion;
 
     // client supported elliptic curves
-    private SupportedEllipticCurvesExtension requestedCurves;
+    private EllipticCurvesExtension requestedCurves;
 
     // the preferable signature algorithm used by ServerKeyExchange message
     SignatureAndHashAlgorithm preferableSignatureAlgorithm;
@@ -683,7 +683,7 @@
                 throw new SSLException("Client did not resume a session");
             }
 
-            requestedCurves = (SupportedEllipticCurvesExtension)
+            requestedCurves = (EllipticCurvesExtension)
                         mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES);
 
             // We only need to handle the "signature_algorithm" extension
@@ -1422,7 +1422,7 @@
     private boolean setupEphemeralECDHKeys() {
         int index = (requestedCurves != null) ?
                 requestedCurves.getPreferredCurve(algorithmConstraints) :
-                SupportedEllipticCurvesExtension.getActiveCurves(algorithmConstraints);
+                EllipticCurvesExtension.getActiveCurves(algorithmConstraints);
         if (index < 0) {
             // no match found, cannot use this ciphersuite
             return false;
@@ -1477,8 +1477,8 @@
                 return false;
             }
             ECParameterSpec params = ((ECPublicKey)publicKey).getParams();
-            int id = SupportedEllipticCurvesExtension.getCurveIndex(params);
-            if ((id <= 0) || !SupportedEllipticCurvesExtension.isSupported(id) ||
+            int id = EllipticCurvesExtension.getCurveIndex(params);
+            if ((id <= 0) || !EllipticCurvesExtension.isSupported(id) ||
                 ((requestedCurves != null) && !requestedCurves.contains(id))) {
                 return false;
             }
--- a/src/share/classes/sun/security/ssl/SupportedEllipticCurvesExtension.java	Tue Oct 24 13:07:11 2017 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,397 +0,0 @@
-/*
- * Copyright (c) 2006, 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.ssl;
-
-import java.io.IOException;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECGenParameterSpec;
-import java.security.spec.InvalidParameterSpecException;
-import java.security.AlgorithmParameters;
-import java.security.AlgorithmConstraints;
-import java.security.CryptoPrimitive;
-import java.security.AccessController;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.ArrayList;
-import javax.net.ssl.SSLProtocolException;
-
-import sun.security.action.GetPropertyAction;
-
-final class SupportedEllipticCurvesExtension extends HelloExtension {
-
-    /* Class and subclass dynamic debugging support */
-    private static final Debug debug = Debug.getInstance("ssl");
-
-    private static final int ARBITRARY_PRIME = 0xff01;
-    private static final int ARBITRARY_CHAR2 = 0xff02;
-
-    // speed up the searching
-    private static final Map<String, Integer> oidToIdMap = new HashMap<>();
-    private static final Map<Integer, String> idToOidMap = new HashMap<>();
-
-    // speed up the parameters construction
-    private static final Map<Integer,
-                AlgorithmParameters> idToParams = new HashMap<>();
-
-    // the supported elliptic curves
-    private static final int[] supportedCurveIds;
-
-    // the curves of the extension
-    private final int[] curveIds;
-
-    // See sun.security.util.CurveDB for the OIDs
-    private static enum NamedEllipticCurve {
-        T163_K1(1,  "sect163k1",    "1.3.132.0.1",      true),  // NIST K-163
-        T163_R1(2,  "sect163r1",    "1.3.132.0.2",      false),
-        T163_R2(3,  "sect163r2",    "1.3.132.0.15",     true),  // NIST B-163
-        T193_R1(4,  "sect193r1",    "1.3.132.0.24",     false),
-        T193_R2(5,  "sect193r2",    "1.3.132.0.25",     false),
-        T233_K1(6,  "sect233k1",    "1.3.132.0.26",     true),  // NIST K-233
-        T233_R1(7,  "sect233r1",    "1.3.132.0.27",     true),  // NIST B-233
-        T239_K1(8,  "sect239k1",    "1.3.132.0.3",      false),
-        T283_K1(9,  "sect283k1",    "1.3.132.0.16",     true),  // NIST K-283
-        T283_R1(10, "sect283r1",    "1.3.132.0.17",     true),  // NIST B-283
-        T409_K1(11, "sect409k1",    "1.3.132.0.36",     true),  // NIST K-409
-        T409_R1(12, "sect409r1",    "1.3.132.0.37",     true),  // NIST B-409
-        T571_K1(13, "sect571k1",    "1.3.132.0.38",     true),  // NIST K-571
-        T571_R1(14, "sect571r1",    "1.3.132.0.39",     true),  // NIST B-571
-
-        P160_K1(15, "secp160k1",    "1.3.132.0.9",      false),
-        P160_R1(16, "secp160r1",    "1.3.132.0.8",      false),
-        P160_R2(17, "secp160r2",    "1.3.132.0.30",     false),
-        P192_K1(18, "secp192k1",    "1.3.132.0.31",     false),
-        P192_R1(19, "secp192r1",    "1.2.840.10045.3.1.1", true), // NIST P-192
-        P224_K1(20, "secp224k1",    "1.3.132.0.32",     false),
-        P224_R1(21, "secp224r1",    "1.3.132.0.33",     true),  // NIST P-224
-        P256_K1(22, "secp256k1",    "1.3.132.0.10",     false),
-        P256_R1(23, "secp256r1",    "1.2.840.10045.3.1.7", true), // NIST P-256
-        P384_R1(24, "secp384r1",    "1.3.132.0.34",     true),  // NIST P-384
-        P521_R1(25, "secp521r1",    "1.3.132.0.35",     true);  // NIST P-521
-
-        int          id;
-        String       name;
-        String       oid;
-        boolean      isFips;
-
-        NamedEllipticCurve(int id, String name, String oid, boolean isFips) {
-            this.id = id;
-            this.name = name;
-            this.oid = oid;
-            this.isFips = isFips;
-
-            if (oidToIdMap.put(oid, id) != null ||
-                idToOidMap.put(id, oid) != null) {
-
-                throw new RuntimeException(
-                        "Duplicate named elliptic curve definition: " + name);
-            }
-        }
-
-        static NamedEllipticCurve getCurve(String name, boolean requireFips) {
-            for (NamedEllipticCurve curve : NamedEllipticCurve.values()) {
-                if (curve.name.equals(name) && (!requireFips || curve.isFips)) {
-                    return curve;
-                }
-            }
-
-            return null;
-        }
-    }
-
-    static {
-        boolean requireFips = SunJSSE.isFIPS();
-
-        // hack code to initialize NamedEllipticCurve
-        NamedEllipticCurve nec =
-                NamedEllipticCurve.getCurve("secp256r1", false);
-
-        // The value of the System Property defines a list of enabled named
-        // curves in preference order, separated with comma.  For example:
-        //
-        //      jdk.tls.namedGroups="secp521r1, secp256r1, secp384r1"
-        //
-        // If the System Property is not defined or the value is empty, the
-        // default curves and preferences will be used.
-        String property = AccessController.doPrivileged(
-                    new GetPropertyAction("jdk.tls.namedGroups"));
-        if (property != null && property.length() != 0) {
-            // remove double quote marks from beginning/end of the property
-            if (property.length() > 1 && property.charAt(0) == '"' &&
-                    property.charAt(property.length() - 1) == '"') {
-                property = property.substring(1, property.length() - 1);
-            }
-        }
-
-        ArrayList<Integer> idList;
-        if (property != null && property.length() != 0) {   // customized curves
-            String[] curves = property.split(",");
-            idList = new ArrayList<>(curves.length);
-            for (String curve : curves) {
-                curve = curve.trim();
-                if (!curve.isEmpty()) {
-                    NamedEllipticCurve namedCurve =
-                            NamedEllipticCurve.getCurve(curve, requireFips);
-                    if (namedCurve != null) {
-                        if (isAvailableCurve(namedCurve.id)) {
-                            idList.add(namedCurve.id);
-                        }
-                    }   // ignore unknown curves
-                }
-            }
-            if (idList.isEmpty() && JsseJce.isEcAvailable()) {
-                throw new IllegalArgumentException(
-                    "System property jdk.tls.namedGroups(" + property + ") " +
-                    "contains no supported elliptic curves");
-            }
-        } else {        // default curves
-            int[] ids;
-            if (requireFips) {
-                ids = new int[] {
-                    // only NIST curves in FIPS mode
-                    23, 24, 25, 9, 10, 11, 12, 13, 14,
-                };
-            } else {
-                ids = new int[] {
-                    // NIST curves first
-                    23, 24, 25, 9, 10, 11, 12, 13, 14,
-                    // non-NIST curves
-                    22,
-                };
-            }
-
-            idList = new ArrayList<>(ids.length);
-            for (int curveId : ids) {
-                if (isAvailableCurve(curveId)) {
-                    idList.add(curveId);
-                }
-            }
-        }
-
-        if (debug != null && idList.isEmpty()) {
-            debug.println(
-                "Initialized [jdk.tls.namedGroups|default] list contains " +
-                "no available elliptic curves. " +
-                (property != null ? "(" + property + ")" : "[Default]"));
-        }
-
-            supportedCurveIds = new int[idList.size()];
-            int i = 0;
-            for (Integer id : idList) {
-                supportedCurveIds[i++] = id;
-            }
-        }
-
-    // check whether the curve is supported by the underlying providers
-    private static boolean isAvailableCurve(int curveId) {
-        String oid = idToOidMap.get(curveId);
-        if (oid != null) {
-            AlgorithmParameters params = null;
-            try {
-                params = JsseJce.getAlgorithmParameters("EC");
-                params.init(new ECGenParameterSpec(oid));
-            } catch (Exception e) {
-                return false;
-            }
-
-            // cache the parameters
-            idToParams.put(curveId, params);
-
-            return true;
-        }
-
-        return false;
-    }
-
-    private SupportedEllipticCurvesExtension(int[] curveIds) {
-        super(ExtensionType.EXT_ELLIPTIC_CURVES);
-        this.curveIds = curveIds;
-    }
-
-    SupportedEllipticCurvesExtension(HandshakeInStream s, int len)
-            throws IOException {
-        super(ExtensionType.EXT_ELLIPTIC_CURVES);
-        int k = s.getInt16();
-        if (((len & 1) != 0) || (k + 2 != len)) {
-            throw new SSLProtocolException("Invalid " + type + " extension");
-        }
-
-        // Note: unknown curves will be ignored later.
-        curveIds = new int[k >> 1];
-        for (int i = 0; i < curveIds.length; i++) {
-            curveIds[i] = s.getInt16();
-        }
-    }
-
-    // get the preferred active curve
-    static int getActiveCurves(AlgorithmConstraints constraints) {
-        return getPreferredCurve(supportedCurveIds, constraints);
-    }
-
-    static boolean hasActiveCurves(AlgorithmConstraints constraints) {
-        return getActiveCurves(constraints) >= 0;
-    }
-
-    static SupportedEllipticCurvesExtension createExtension(
-                AlgorithmConstraints constraints) {
-
-        ArrayList<Integer> idList = new ArrayList<>(supportedCurveIds.length);
-        for (int curveId : supportedCurveIds) {
-            if (constraints.permits(
-                    EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
-                                "EC", idToParams.get(curveId))) {
-                idList.add(curveId);
-            }
-        }
-
-        if (!idList.isEmpty()) {
-            int[] ids = new int[idList.size()];
-            int i = 0;
-            for (Integer id : idList) {
-                ids[i++] = id;
-            }
-
-            return new SupportedEllipticCurvesExtension(ids);
-        }
-
-        return null;
-    }
-
-    // get the preferred activated curve
-    int getPreferredCurve(AlgorithmConstraints constraints) {
-        return getPreferredCurve(curveIds, constraints);
-    }
-
-    // get a preferred activated curve
-    private static int getPreferredCurve(int[] curves,
-                AlgorithmConstraints constraints) {
-        for (int curveId : curves) {
-            if (isSupported(curveId) && constraints.permits(
-                    EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
-                                "EC", idToParams.get(curveId))) {
-                return curveId;
-            }
-        }
-
-        return -1;
-    }
-
-    boolean contains(int index) {
-        for (int curveId : curveIds) {
-            if (index == curveId) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    int length() {
-        return 6 + (curveIds.length << 1);
-    }
-
-    @Override
-    void send(HandshakeOutStream s) throws IOException {
-        s.putInt16(type.id);
-        int k = curveIds.length << 1;
-        s.putInt16(k + 2);
-        s.putInt16(k);
-        for (int curveId : curveIds) {
-            s.putInt16(curveId);
-        }
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("Extension " + type + ", curve names: {");
-        boolean first = true;
-        for (int curveId : curveIds) {
-            if (first) {
-                first = false;
-            } else {
-                sb.append(", ");
-            }
-            String curveName = getCurveName(curveId);
-            if (curveName != null) {
-                sb.append(curveName);
-            } else if (curveId == ARBITRARY_PRIME) {
-                sb.append("arbitrary_explicit_prime_curves");
-            } else if (curveId == ARBITRARY_CHAR2) {
-                sb.append("arbitrary_explicit_char2_curves");
-            } else {
-                sb.append("unknown curve " + curveId);
-            }
-        }
-        sb.append("}");
-        return sb.toString();
-    }
-
-    // Test whether the given curve is supported.
-    static boolean isSupported(int index) {
-        for (int curveId : supportedCurveIds) {
-            if (index == curveId) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    static int getCurveIndex(ECParameterSpec params) {
-        String oid = JsseJce.getNamedCurveOid(params);
-        if (oid == null) {
-            return -1;
-        }
-        Integer n = oidToIdMap.get(oid);
-        return (n == null) ? -1 : n;
-    }
-
-    static String getCurveOid(int index) {
-        return idToOidMap.get(index);
-    }
-
-    static ECGenParameterSpec getECGenParamSpec(int index) {
-        AlgorithmParameters params = idToParams.get(index);
-        try {
-            return params.getParameterSpec(ECGenParameterSpec.class);
-        } catch (InvalidParameterSpecException ipse) {
-            // should be unlikely
-            String curveOid = getCurveOid(index);
-            return new ECGenParameterSpec(curveOid);
-        }
-    }
-
-    private static String getCurveName(int index) {
-        for (NamedEllipticCurve namedCurve : NamedEllipticCurve.values()) {
-            if (namedCurve.id == index) {
-                return namedCurve.name;
-            }
-        }
-
-        return null;
-    }
-}
--- a/src/share/classes/sun/security/ssl/SupportedEllipticPointFormatsExtension.java	Tue Oct 24 13:07:11 2017 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2006, 2012, 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.ssl;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.net.ssl.SSLProtocolException;
-
-final class SupportedEllipticPointFormatsExtension extends HelloExtension {
-
-    final static int FMT_UNCOMPRESSED = 0;
-    final static int FMT_ANSIX962_COMPRESSED_PRIME = 1;
-    final static int FMT_ANSIX962_COMPRESSED_CHAR2 = 2;
-
-    static final HelloExtension DEFAULT =
-        new SupportedEllipticPointFormatsExtension(
-            new byte[] {FMT_UNCOMPRESSED});
-
-    private final byte[] formats;
-
-    private SupportedEllipticPointFormatsExtension(byte[] formats) {
-        super(ExtensionType.EXT_EC_POINT_FORMATS);
-        this.formats = formats;
-    }
-
-    SupportedEllipticPointFormatsExtension(HandshakeInStream s, int len)
-            throws IOException {
-        super(ExtensionType.EXT_EC_POINT_FORMATS);
-        formats = s.getBytes8();
-        // RFC 4492 says uncompressed points must always be supported.
-        // Check just to make sure.
-        boolean uncompressed = false;
-        for (int format : formats) {
-            if (format == FMT_UNCOMPRESSED) {
-                uncompressed = true;
-                break;
-            }
-        }
-        if (uncompressed == false) {
-            throw new SSLProtocolException
-                ("Peer does not support uncompressed points");
-        }
-    }
-
-    @Override
-    int length() {
-        return 5 + formats.length;
-    }
-
-    @Override
-    void send(HandshakeOutStream s) throws IOException {
-        s.putInt16(type.id);
-        s.putInt16(formats.length + 1);
-        s.putBytes8(formats);
-    }
-
-    private static String toString(byte format) {
-        int f = format & 0xff;
-        switch (f) {
-        case FMT_UNCOMPRESSED:
-            return "uncompressed";
-        case FMT_ANSIX962_COMPRESSED_PRIME:
-            return "ansiX962_compressed_prime";
-        case FMT_ANSIX962_COMPRESSED_CHAR2:
-            return "ansiX962_compressed_char2";
-        default:
-            return "unknown-" + f;
-        }
-    }
-
-    @Override
-    public String toString() {
-        List<String> list = new ArrayList<String>();
-        for (byte format : formats) {
-            list.add(toString(format));
-        }
-        return "Extension " + type + ", formats: " + list;
-    }
-}
--- a/src/share/classes/sun/security/tools/keytool/Main.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/tools/keytool/Main.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1711,11 +1711,9 @@
             if ("EC".equalsIgnoreCase(keyAlgName)) {
                 keysize = SecurityProviderConstants.DEF_EC_KEY_SIZE;
             } else if ("RSA".equalsIgnoreCase(keyAlgName)) {
-                // hardcode for now as DEF_RSA_KEY_SIZE is still 1024
-                keysize = 2048; // SecurityProviderConstants.DEF_RSA_KEY_SIZE;
+                keysize = SecurityProviderConstants.DEF_RSA_KEY_SIZE;
             } else if ("DSA".equalsIgnoreCase(keyAlgName)) {
-                // hardcode for now as DEF_DSA_KEY_SIZE is still 1024
-                keysize = 2048;
+                keysize = SecurityProviderConstants.DEF_DSA_KEY_SIZE;
             }
         }
 
--- a/src/share/classes/sun/security/util/AlgorithmDecomposer.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/util/AlgorithmDecomposer.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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,6 +27,8 @@
 
 import java.util.HashSet;
 import java.util.Set;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.regex.Pattern;
 
 /**
@@ -133,6 +135,23 @@
         return elements;
     }
 
+    /**
+     * Get aliases of the specified algorithm.
+     *
+     * May support more algorithms in the future.
+     */
+    public static Collection<String> getAliases(String algorithm) {
+        String[] aliases;
+        if (algorithm.equalsIgnoreCase("DH") ||
+                algorithm.equalsIgnoreCase("DiffieHellman")) {
+            aliases = new String[] {"DH", "DiffieHellman"};
+        } else {
+            aliases = new String[] {algorithm};
+        }
+
+        return Arrays.asList(aliases);
+    }
+
     private static void hasLoop(Set<String> elements, String find, String replace) {
         if (elements.contains(find)) {
             if (!elements.contains(replace)) {
--- a/src/share/classes/sun/security/util/DerValue.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/util/DerValue.java	Tue Oct 24 23:16:46 2017 -0700
@@ -491,20 +491,27 @@
      * @return the octet string held in this DER value
      */
     public byte[] getOctetString() throws IOException {
-        byte[] bytes;
 
         if (tag != tag_OctetString && !isConstructed(tag_OctetString)) {
             throw new IOException(
                 "DerValue.getOctetString, not an Octet String: " + tag);
         }
-        bytes = new byte[length];
-        // Note: do not tempt to call buffer.read(bytes) at all. There's a
+        // Note: do not attempt to call buffer.read(bytes) at all. There's a
         // known bug that it returns -1 instead of 0.
         if (length == 0) {
-            return bytes;
+            return new byte[0];
         }
-        if (buffer.read(bytes) != length)
+
+        // Only allocate the array if there are enough bytes available.
+        // This only works for ByteArrayInputStream.
+        // The assignment below ensures that buffer has the required type.
+        ByteArrayInputStream arrayInput = buffer;
+        if (arrayInput.available() < length) {
             throw new IOException("short read on DerValue buffer");
+        }
+        byte[] bytes = new byte[length];
+        arrayInput.read(bytes);
+
         if (isConstructed()) {
             DerInputStream in = new DerInputStream(bytes, 0, bytes.length,
                 buffer.allowBER);
--- a/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Tue Oct 24 23:16:46 2017 -0700
@@ -45,6 +45,7 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.Collection;
 import java.util.StringTokenizer;
 import java.util.TimeZone;
 import java.util.regex.Pattern;
@@ -106,7 +107,15 @@
     @Override
     public final boolean permits(Set<CryptoPrimitive> primitives,
             String algorithm, AlgorithmParameters parameters) {
-        return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
+        if (!checkAlgorithm(disabledAlgorithms, algorithm, decomposer)) {
+            return false;
+        }
+
+        if (parameters != null) {
+            return algorithmConstraints.permits(algorithm, parameters);
+        }
+
+        return true;
     }
 
     /*
@@ -242,7 +251,12 @@
                 List<Constraint> constraintList =
                         constraintsMap.getOrDefault(algorithm,
                                 new ArrayList<>(1));
-                constraintsMap.putIfAbsent(algorithm, constraintList);
+
+                // Consider the impact of algorithm aliases.
+                for (String alias : AlgorithmDecomposer.getAliases(algorithm)) {
+                    constraintsMap.putIfAbsent(alias, constraintList);
+                }
+
                 if (space <= 0) {
                     constraintList.add(new DisabledConstraint(algorithm));
                     continue;
@@ -351,6 +365,27 @@
             return true;
         }
 
+        // Check if constraints permit this AlgorithmParameters.
+        public boolean permits(String algorithm, AlgorithmParameters aps) {
+            List<Constraint> list = getConstraints(algorithm);
+            if (list == null) {
+                return true;
+            }
+
+            for (Constraint constraint : list) {
+                if (!constraint.permits(aps)) {
+                    if (debug != null) {
+                        debug.println("keySizeConstraint: failed algorithm " +
+                                "parameters constraint check " + aps);
+                    }
+
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
         // Check if constraints permit this cert.
         public void permits(String algorithm, ConstraintsParameters cp)
                 throws CertPathValidatorException {
@@ -445,6 +480,18 @@
         }
 
         /**
+         * Check if the algorithm constraint permits a given cryptographic
+         * parameters.
+         *
+         * @param parameters the cryptographic parameters
+         * @return 'true' if the cryptographic parameters is allowed,
+         *         'false' ortherwise.
+         */
+        public boolean permits(AlgorithmParameters parameters) {
+            return true;
+        }
+
+        /**
          * Check if an algorithm constraint is permitted with a given
          * ConstraintsParameters.
          *
@@ -528,6 +575,7 @@
          * call next() for any following constraints. If it does not, exit
          * as this constraint(s) does not restrict the operation.
          */
+        @Override
         public void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException {
             if (debug != null) {
@@ -551,100 +599,101 @@
      * This class handles the denyAfter constraint.  The date is in the UTC/GMT
      * timezone.
      */
-     private static class DenyAfterConstraint extends Constraint {
-         private Date denyAfterDate;
-         private static final SimpleDateFormat dateFormat =
-                 new SimpleDateFormat("EEE, MMM d HH:mm:ss z yyyy");
+    private static class DenyAfterConstraint extends Constraint {
+        private Date denyAfterDate;
+        private static final SimpleDateFormat dateFormat =
+                new SimpleDateFormat("EEE, MMM d HH:mm:ss z yyyy");
 
-         DenyAfterConstraint(String algo, int year, int month, int day) {
-             Calendar c;
+        DenyAfterConstraint(String algo, int year, int month, int day) {
+            Calendar c;
 
-             algorithm = algo;
+            algorithm = algo;
 
-             if (debug != null) {
-                 debug.println("DenyAfterConstraint read in as:  year " +
-                         year + ", month = " + month + ", day = " + day);
-             }
+            if (debug != null) {
+                debug.println("DenyAfterConstraint read in as:  year " +
+                        year + ", month = " + month + ", day = " + day);
+            }
 
-             c = new Calendar.Builder().setTimeZone(TimeZone.getTimeZone("GMT"))
-                     .setDate(year, month - 1, day).build();
+            c = new Calendar.Builder().setTimeZone(TimeZone.getTimeZone("GMT"))
+                    .setDate(year, month - 1, day).build();
 
-             if (year > c.getActualMaximum(Calendar.YEAR) ||
-                     year < c.getActualMinimum(Calendar.YEAR)) {
-                 throw new IllegalArgumentException(
-                         "Invalid year given in constraint: " + year);
-             }
-             if ((month - 1) > c.getActualMaximum(Calendar.MONTH) ||
-                     (month - 1) < c.getActualMinimum(Calendar.MONTH)) {
-                 throw new IllegalArgumentException(
-                         "Invalid month given in constraint: " + month);
-             }
-             if (day > c.getActualMaximum(Calendar.DAY_OF_MONTH) ||
-                     day < c.getActualMinimum(Calendar.DAY_OF_MONTH)) {
-                 throw new IllegalArgumentException(
-                         "Invalid Day of Month given in constraint: " + day);
-             }
+            if (year > c.getActualMaximum(Calendar.YEAR) ||
+                    year < c.getActualMinimum(Calendar.YEAR)) {
+                throw new IllegalArgumentException(
+                        "Invalid year given in constraint: " + year);
+            }
+            if ((month - 1) > c.getActualMaximum(Calendar.MONTH) ||
+                    (month - 1) < c.getActualMinimum(Calendar.MONTH)) {
+                throw new IllegalArgumentException(
+                        "Invalid month given in constraint: " + month);
+            }
+            if (day > c.getActualMaximum(Calendar.DAY_OF_MONTH) ||
+                    day < c.getActualMinimum(Calendar.DAY_OF_MONTH)) {
+                throw new IllegalArgumentException(
+                        "Invalid Day of Month given in constraint: " + day);
+            }
 
-             denyAfterDate = c.getTime();
-             if (debug != null) {
-                 debug.println("DenyAfterConstraint date set to: " +
-                         dateFormat.format(denyAfterDate));
-             }
-         }
+            denyAfterDate = c.getTime();
+            if (debug != null) {
+                debug.println("DenyAfterConstraint date set to: " +
+                        dateFormat.format(denyAfterDate));
+            }
+        }
 
-         /*
-          * Checking that the provided date is not beyond the constraint date.
-          * The provided date can be the PKIXParameter date if given,
-          * otherwise it is the current date.
-          *
-          * If the constraint disallows, call next() for any following
-          * constraints. Throw an exception if this is the last constraint.
-          */
-         @Override
-         public void permits(ConstraintsParameters cp)
-                 throws CertPathValidatorException {
-             Date currentDate;
-             String errmsg;
+        /*
+         * Checking that the provided date is not beyond the constraint date.
+         * The provided date can be the PKIXParameter date if given,
+         * otherwise it is the current date.
+         *
+         * If the constraint disallows, call next() for any following
+         * constraints. Throw an exception if this is the last constraint.
+         */
+        @Override
+        public void permits(ConstraintsParameters cp)
+                throws CertPathValidatorException {
+            Date currentDate;
+            String errmsg;
 
-             if (cp.getJARTimestamp() != null) {
-                 currentDate = cp.getJARTimestamp().getTimestamp();
-                 errmsg = "JAR Timestamp date: ";
-             } else if (cp.getPKIXParamDate() != null) {
-                 currentDate = cp.getPKIXParamDate();
-                 errmsg = "PKIXParameter date: ";
-             } else {
-                 currentDate = new Date();
-                 errmsg = "Current date: ";
-             }
+            if (cp.getJARTimestamp() != null) {
+                currentDate = cp.getJARTimestamp().getTimestamp();
+                errmsg = "JAR Timestamp date: ";
+            } else if (cp.getPKIXParamDate() != null) {
+                currentDate = cp.getPKIXParamDate();
+                errmsg = "PKIXParameter date: ";
+            } else {
+                currentDate = new Date();
+                errmsg = "Current date: ";
+            }
 
-             if (!denyAfterDate.after(currentDate)) {
-                 if (next(cp)) {
-                     return;
-                 }
-                 throw new CertPathValidatorException(
-                         "denyAfter constraint check failed: " + algorithm +
-                         " used with Constraint date: " +
-                         dateFormat.format(denyAfterDate) + "; " + errmsg +
-                         dateFormat.format(currentDate) + extendedMsg(cp),
-                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-             }
-         }
+            if (!denyAfterDate.after(currentDate)) {
+                if (next(cp)) {
+                    return;
+                }
+                throw new CertPathValidatorException(
+                        "denyAfter constraint check failed: " + algorithm +
+                        " used with Constraint date: " +
+                        dateFormat.format(denyAfterDate) + "; " + errmsg +
+                        dateFormat.format(currentDate) + extendedMsg(cp),
+                        null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+            }
+        }
 
-         /*
-          * Return result if the constraint's date is beyond the current date
-          * in UTC timezone.
-          */
-         public boolean permits(Key key) {
-             if (next(key)) {
-                 return true;
-             }
-             if (debug != null) {
-                 debug.println("DenyAfterConstraints.permits(): " + algorithm);
-             }
+        /*
+         * Return result if the constraint's date is beyond the current date
+         * in UTC timezone.
+         */
+        @Override
+        public boolean permits(Key key) {
+            if (next(key)) {
+                return true;
+            }
+            if (debug != null) {
+                debug.println("DenyAfterConstraints.permits(): " + algorithm);
+            }
 
-             return denyAfterDate.after(new Date());
-         }
-     }
+            return denyAfterDate.after(new Date());
+        }
+    }
 
     /*
      * The usage constraint is for the "usage" keyword.  It checks against the
@@ -658,6 +707,7 @@
             this.usages = usages;
         }
 
+        @Override
         public void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException {
             for (String usage : usages) {
@@ -747,6 +797,7 @@
          * constraint  Any permitted constraint will exit the linked list
          * to allow the operation.
          */
+        @Override
         public void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException {
             Key key = null;
@@ -771,6 +822,7 @@
 
         // Check if key constraint disable the specified key
         // Uses old style permit()
+        @Override
         public boolean permits(Key key) {
             // If we recursively find a constraint that permits us to use
             // this key, return true and skip any other constraint checks.
@@ -784,6 +836,30 @@
             return permitsImpl(key);
         }
 
+        @Override
+        public boolean permits(AlgorithmParameters parameters) {
+            String paramAlg = parameters.getAlgorithm();
+            if (!algorithm.equalsIgnoreCase(parameters.getAlgorithm())) {
+                // Consider the impact of the algorithm aliases.
+                Collection<String> aliases =
+                        AlgorithmDecomposer.getAliases(algorithm);
+                if (!aliases.contains(paramAlg)) {
+                    return true;
+                }
+            }
+
+            int keySize = KeyUtil.getKeySize(parameters);
+            if (keySize == 0) {
+                return false;
+            } else if (keySize > 0) {
+                return !((keySize < minSize) || (keySize > maxSize) ||
+                    (prohibitedSize == keySize));
+            }   // Otherwise, the key size is not accessible or determined.
+                // Conservatively, please don't disable such keys.
+
+            return true;
+        }
+
         private boolean permitsImpl(Key key) {
             // Verify this constraint is for this public key algorithm
             if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) {
@@ -811,6 +887,7 @@
             algorithm = algo;
         }
 
+        @Override
         public void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException {
             throw new CertPathValidatorException(
@@ -819,6 +896,7 @@
                     null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
         }
 
+        @Override
         public boolean permits(Key key) {
             return false;
         }
--- a/src/share/classes/sun/security/util/KeyUtil.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/util/KeyUtil.java	Tue Oct 24 23:16:46 2017 -0700
@@ -25,6 +25,7 @@
 
 package sun.security.util;
 
+import java.security.AlgorithmParameters;
 import java.security.Key;
 import java.security.PrivilegedAction;
 import java.security.AccessController;
@@ -35,6 +36,8 @@
 import java.security.interfaces.DSAParams;
 import java.security.SecureRandom;
 import java.security.spec.KeySpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
 import javax.crypto.SecretKey;
 import javax.crypto.interfaces.DHKey;
 import javax.crypto.interfaces.DHPublicKey;
@@ -100,6 +103,61 @@
     }
 
     /**
+     * Returns the key size of the given cryptographic parameters in bits.
+     *
+     * @param parameters the cryptographic parameters, cannot be null
+     * @return the key size of the given cryptographic parameters in bits,
+     *       or -1 if the key size is not accessible
+     */
+    public static final int getKeySize(AlgorithmParameters parameters) {
+
+        String algorithm = parameters.getAlgorithm();
+        switch (algorithm) {
+            case "EC":
+                try {
+                    ECKeySizeParameterSpec ps = parameters.getParameterSpec(
+                            ECKeySizeParameterSpec.class);
+                    if (ps != null) {
+                        return ps.getKeySize();
+                    }
+                } catch (InvalidParameterSpecException ipse) {
+                    // ignore
+                }
+
+                try {
+                    ECParameterSpec ps = parameters.getParameterSpec(
+                            ECParameterSpec.class);
+                    if (ps != null) {
+                        return ps.getOrder().bitLength();
+                    }
+                } catch (InvalidParameterSpecException ipse) {
+                    // ignore
+                }
+
+                // Note: the ECGenParameterSpec case should be covered by the
+                // ECParameterSpec case above.
+                // See ECUtil.getECParameterSpec(Provider, String).
+
+                break;
+            case "DiffieHellman":
+                try {
+                    DHParameterSpec ps = parameters.getParameterSpec(
+                            DHParameterSpec.class);
+                    if (ps != null) {
+                        return ps.getP().bitLength();
+                    }
+                } catch (InvalidParameterSpecException ipse) {
+                    // ignore
+                }
+                break;
+
+            // May support more AlgorithmParameters algorithms in the future.
+        }
+
+        return -1;
+    }
+
+    /**
      * Returns whether the key is valid or not.
      * <P>
      * Note that this method is only apply to DHPublicKey at present.
--- a/src/share/classes/sun/security/util/SecurityProviderConstants.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/classes/sun/security/util/SecurityProviderConstants.java	Tue Oct 24 23:16:46 2017 -0700
@@ -64,9 +64,9 @@
     static {
         String keyLengthStr = GetPropertyAction.privilegedGetProperty
             (KEY_LENGTH_PROP);
-        int dsaKeySize = 1024;
-        int rsaKeySize = 1024;
-        int dhKeySize = 1024;
+        int dsaKeySize = 2048;
+        int rsaKeySize = 2048;
+        int dhKeySize = 2048;
         int ecKeySize = 256;
 
         if (keyLengthStr != null) {
--- a/src/share/lib/management/management.properties	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/lib/management/management.properties	Tue Oct 24 23:16:46 2017 -0700
@@ -329,3 +329,38 @@
 #      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 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/share/lib/security/java.security-aix	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/lib/security/java.security-aix	Tue Oct 24 23:16:46 2017 -0700
@@ -585,7 +585,7 @@
 #
 # See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
 #
-jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
+jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024
 
 #
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
@@ -617,7 +617,7 @@
 #
 # Example:
 #   jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \
+jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \
     EC keySize < 224
 
 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
@@ -933,3 +933,24 @@
 #    java.rmi.dgc.VMID;\
 #    java.rmi.dgc.Lease;\
 #    maxdepth=5;maxarray=10000
+
+# CORBA ORBIorTypeCheckRegistryFilter
+# Type check enhancement for ORB::string_to_object processing
+#
+# An IOR type check filter, if configured, is used by an ORB during
+# an ORB::string_to_object invocation to check the veracity of the type encoded
+# in the ior string.
+#
+# The filter pattern consists of a semi-colon separated list of class names.
+# The configured list contains the binary class names of the IDL interface types
+# corresponding to the IDL stub class to be instantiated.
+# As such, a filter specifies a list of IDL stub classes that will be
+# allowed by an ORB when an ORB::string_to_object is invoked.
+# It is used to specify a white list configuration of acceptable
+# IDL stub types which may be contained in a stringified IOR
+# parameter passed as input to an ORB::string_to_object method.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+#com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name
--- a/src/share/lib/security/java.security-linux	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/lib/security/java.security-linux	Tue Oct 24 23:16:46 2017 -0700
@@ -585,7 +585,7 @@
 #
 # See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
 #
-jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
+jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024
 
 #
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
@@ -617,7 +617,7 @@
 #
 # Example:
 #   jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \
+jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \
     EC keySize < 224
 
 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
@@ -885,6 +885,8 @@
 # If the pattern is equal to the class name, it matches.
 # Otherwise, the status is UNDECIDED.
 #
+# Primitive types are not configurable with this filter.
+#
 #jdk.serialFilter=pattern;pattern
 
 #
@@ -896,9 +898,12 @@
 # to increase limits.
 # If the limits (maxdepth, maxrefs, or maxbytes) are exceeded, the object is rejected.
 #
-# Each non-array type is allowed or rejected if it matches one of the patterns,
-# evaluated from left to right, and is otherwise allowed. Arrays of any
-# component type, including subarrays and arrays of primitives, are allowed.
+# The maxdepth of any array passed to the RMI Registry is set to
+# 10000.  The maximum depth of the graph is set to 20.
+# These limits can be reduced via the maxarray, maxdepth limits.
+#
+#sun.rmi.registry.registryFilter=pattern;pattern
+
 #
 # Array construction of any component type, including subarrays and arrays of
 # primitives, are allowed unless the length is greater than the maxarray limit.
@@ -935,3 +940,23 @@
 #    java.rmi.dgc.Lease;\
 #    maxdepth=5;maxarray=10000
 
+# CORBA ORBIorTypeCheckRegistryFilter
+# Type check enhancement for ORB::string_to_object processing
+#
+# An IOR type check filter, if configured, is used by an ORB during
+# an ORB::string_to_object invocation to check the veracity of the type encoded
+# in the ior string.
+#
+# The filter pattern consists of a semi-colon separated list of class names.
+# The configured list contains the binary class names of the IDL interface types
+# corresponding to the IDL stub class to be instantiated.
+# As such, a filter specifies a list of IDL stub classes that will be
+# allowed by an ORB when an ORB::string_to_object is invoked.
+# It is used to specify a white list configuration of acceptable
+# IDL stub types which may be contained in a stringified IOR
+# parameter passed as input to an ORB::string_to_object method.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+#com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name
--- a/src/share/lib/security/java.security-macosx	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/lib/security/java.security-macosx	Tue Oct 24 23:16:46 2017 -0700
@@ -588,7 +588,7 @@
 #
 # See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
 #
-jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
+jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024
 
 #
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
@@ -620,7 +620,7 @@
 #
 # Example:
 #   jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \
+jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \
     EC keySize < 224
 
 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
@@ -937,3 +937,24 @@
 #    java.rmi.dgc.VMID;\
 #    java.rmi.dgc.Lease;\
 #    maxdepth=5;maxarray=10000
+
+# CORBA ORBIorTypeCheckRegistryFilter
+# Type check enhancement for ORB::string_to_object processing
+#
+# An IOR type check filter, if configured, is used by an ORB during
+# an ORB::string_to_object invocation to check the veracity of the type encoded
+# in the ior string.
+#
+# The filter pattern consists of a semi-colon separated list of class names.
+# The configured list contains the binary class names of the IDL interface types
+# corresponding to the IDL stub class to be instantiated.
+# As such, a filter specifies a list of IDL stub classes that will be
+# allowed by an ORB when an ORB::string_to_object is invoked.
+# It is used to specify a white list configuration of acceptable
+# IDL stub types which may be contained in a stringified IOR
+# parameter passed as input to an ORB::string_to_object method.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+#com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name
--- a/src/share/lib/security/java.security-solaris	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/lib/security/java.security-solaris	Tue Oct 24 23:16:46 2017 -0700
@@ -587,7 +587,7 @@
 #
 # See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
 #
-jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
+jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024
 
 #
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
@@ -619,7 +619,7 @@
 #
 # Example:
 #   jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \
+jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \
     EC keySize < 224
 
 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
@@ -936,3 +936,24 @@
 #    java.rmi.dgc.VMID;\
 #    java.rmi.dgc.Lease;\
 #    maxdepth=5;maxarray=10000
+
+# CORBA ORBIorTypeCheckRegistryFilter
+# Type check enhancement for ORB::string_to_object processing
+#
+# An IOR type check filter, if configured, is used by an ORB during
+# an ORB::string_to_object invocation to check the veracity of the type encoded
+# in the ior string.
+#
+# The filter pattern consists of a semi-colon separated list of class names.
+# The configured list contains the binary class names of the IDL interface types
+# corresponding to the IDL stub class to be instantiated.
+# As such, a filter specifies a list of IDL stub classes that will be
+# allowed by an ORB when an ORB::string_to_object is invoked.
+# It is used to specify a white list configuration of acceptable
+# IDL stub types which may be contained in a stringified IOR
+# parameter passed as input to an ORB::string_to_object method.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+#com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name
--- a/src/share/lib/security/java.security-windows	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/lib/security/java.security-windows	Tue Oct 24 23:16:46 2017 -0700
@@ -588,7 +588,7 @@
 #
 # See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
 #
-jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024
+jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024
 
 #
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
@@ -620,7 +620,7 @@
 #
 # Example:
 #   jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
-jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768, \
+jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \
     EC keySize < 224
 
 # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS)
@@ -937,3 +937,24 @@
 #    java.rmi.dgc.VMID;\
 #    java.rmi.dgc.Lease;\
 #    maxdepth=5;maxarray=10000
+
+# CORBA ORBIorTypeCheckRegistryFilter
+# Type check enhancement for ORB::string_to_object processing
+#
+# An IOR type check filter, if configured, is used by an ORB during
+# an ORB::string_to_object invocation to check the veracity of the type encoded
+# in the ior string.
+#
+# The filter pattern consists of a semi-colon separated list of class names.
+# The configured list contains the binary class names of the IDL interface types
+# corresponding to the IDL stub class to be instantiated.
+# As such, a filter specifies a list of IDL stub classes that will be
+# allowed by an ORB when an ORB::string_to_object is invoked.
+# It is used to specify a white list configuration of acceptable
+# IDL stub types which may be contained in a stringified IOR
+# parameter passed as input to an ORB::string_to_object method.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+#com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name
--- a/src/share/native/sun/font/layout/LookupTables.cpp	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/native/sun/font/layout/LookupTables.cpp	Tue Oct 24 23:16:46 2017 -0700
@@ -52,9 +52,9 @@
 const LookupSegment *BinarySearchLookupTable::lookupSegment(const LETableReference &base, const LookupSegment *segments, LEGlyphID glyph, LEErrorCode &success) const
 {
 
-    le_int16  unity = SWAPW(unitSize);
-    le_int16  probe = SWAPW(searchRange);
-    le_int16  extra = SWAPW(rangeShift);
+    le_uint16  unity = SWAPW(unitSize);
+    le_uint16  probe = SWAPW(searchRange);
+    le_uint16  extra = SWAPW(rangeShift);
     TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
     LEReferenceTo<LookupSegment> entry(base, success, segments);
     LEReferenceTo<LookupSegment> trial(entry, success, extra);
@@ -84,9 +84,9 @@
 
 const LookupSingle *BinarySearchLookupTable::lookupSingle(const LETableReference &base, const LookupSingle *entries, LEGlyphID glyph, LEErrorCode &success) const
 {
-    le_int16  unity = SWAPW(unitSize);
-    le_int16  probe = SWAPW(searchRange);
-    le_int16  extra = SWAPW(rangeShift);
+    le_uint16  unity = SWAPW(unitSize);
+    le_uint16  probe = SWAPW(searchRange);
+    le_uint16  extra = SWAPW(rangeShift);
     TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
     LEReferenceTo<LookupSingle> entry(base, success, entries);
     LEReferenceTo<LookupSingle> trial(entry, success, extra);
--- a/src/share/native/sun/font/layout/LookupTables.h	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/native/sun/font/layout/LookupTables.h	Tue Oct 24 23:16:46 2017 -0700
@@ -74,11 +74,11 @@
 
 struct BinarySearchLookupTable : LookupTable
 {
-    le_int16 unitSize;
-    le_int16 nUnits;
-    le_int16 searchRange;
-    le_int16 entrySelector;
-    le_int16 rangeShift;
+    le_uint16 unitSize;
+    le_uint16 nUnits;
+    le_uint16 searchRange;
+    le_uint16 entrySelector;
+    le_uint16 rangeShift;
 
     const LookupSegment *lookupSegment(const LETableReference &base, const LookupSegment *segments, LEGlyphID glyph, LEErrorCode &success) const;
 
--- a/src/share/native/sun/java2d/cmm/lcms/LCMS.c	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/native/sun/java2d/cmm/lcms/LCMS.c	Tue Oct 24 23:16:46 2017 -0700
@@ -644,7 +644,12 @@
 {
     jclass clsLcmsProfile;
     jobject cmmProfile;
-    jfieldID fid = (*env)->GetFieldID (env,
+    jfieldID fid;
+
+    if (pf == NULL) {
+        return NULL;
+    }
+    fid = (*env)->GetFieldID (env,
         (*env)->GetObjectClass(env, pf),
         "cmmProfile", "Lsun/java2d/cmm/Profile;");
     if (fid == NULL) {
--- a/src/share/native/sun/security/jgss/wrapper/GSSLibStub.c	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/native/sun/security/jgss/wrapper/GSSLibStub.c	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, 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
@@ -830,7 +830,7 @@
 {
   OM_uint32 minor, major;
   gss_cred_id_t credHdl ;
-  gss_ctx_id_t contextHdl;
+  gss_ctx_id_t contextHdl, contextHdlSave;
   gss_name_t targetName;
   gss_OID mech;
   OM_uint32 flags, aFlags;
@@ -847,7 +847,7 @@
   TRACE0("[GSSLibStub_initContext]");
 
   credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
-  contextHdl = (gss_ctx_id_t) jlong_to_ptr(
+  contextHdl = contextHdlSave = (gss_ctx_id_t) jlong_to_ptr(
     (*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext));
   targetName = (gss_name_t) jlong_to_ptr(pName);
   mech = (gss_OID) jlong_to_ptr((*env)->GetLongField(env, jobj, FID_GSSLibStub_pMech));
@@ -882,10 +882,17 @@
   TRACE2("[GSSLibStub_initContext] after: pContext=%ld, outToken len=%ld",
             (long)contextHdl, (long)outToken.length);
 
+  // update context handle with the latest value if changed
+  // this is to work with both MIT and Solaris. Former deletes half-built
+  // context if error occurs
+  if (contextHdl != contextHdlSave) {
+    (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext,
+                         ptr_to_jlong(contextHdl));
+    TRACE1("[GSSLibStub_initContext] set pContext=%ld", (long)contextHdl);
+  }
+
   if (GSS_ERROR(major) == GSS_S_COMPLETE) {
     /* update member values if needed */
-    (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext,
-                        ptr_to_jlong(contextHdl));
     (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags);
     TRACE1("[GSSLibStub_initContext] set flags=0x%x", aFlags);
 
@@ -939,7 +946,7 @@
 {
   OM_uint32 minor, major;
   OM_uint32 minor2, major2;
-  gss_ctx_id_t contextHdl;
+  gss_ctx_id_t contextHdl, contextHdlSave;
   gss_cred_id_t credHdl;
   gss_buffer_desc inToken;
   gss_channel_bindings_t cb;
@@ -959,7 +966,7 @@
 
   TRACE0("[GSSLibStub_acceptContext]");
 
-  contextHdl = (gss_ctx_id_t)jlong_to_ptr(
+  contextHdl = contextHdlSave = (gss_ctx_id_t)jlong_to_ptr(
     (*env)->GetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext));
   credHdl = (gss_cred_id_t) jlong_to_ptr(pCred);
   initGSSBuffer(env, jinToken, &inToken);
@@ -996,19 +1003,22 @@
   TRACE3("[GSSLibStub_acceptContext] after: pCred=%ld, pContext=%ld, pDelegCred=%ld",
         (long)credHdl, (long)contextHdl, (long) delCred);
 
+  // update context handle with the latest value if changed
+  // this is to work with both MIT and Solaris. Former deletes half-built
+  // context if error occurs
+  if (contextHdl != contextHdlSave) {
+    (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext,
+                         ptr_to_jlong(contextHdl));
+    TRACE1("[GSSLibStub_acceptContext] set pContext=%ld", (long)contextHdl);
+  }
+
   if (GSS_ERROR(major) == GSS_S_COMPLETE) {
     /* update member values if needed */
-    (*env)->SetLongField(env, jcontextSpi, FID_NativeGSSContext_pContext,
-                        ptr_to_jlong(contextHdl));
-    TRACE1("[GSSLibStub_acceptContext] set pContext=%ld",
-            (long)contextHdl);
-
     // WORKAROUND for a Heimdal bug
     if (delCred == GSS_C_NO_CREDENTIAL) {
         aFlags &= 0xfffffffe;
     }
     (*env)->SetIntField(env, jcontextSpi, FID_NativeGSSContext_flags, aFlags);
-
     TRACE1("[GSSLibStub_acceptContext] set flags=0x%x", aFlags);
 
     if (setTarget) {
--- a/src/share/sample/vm/jvm-clr/invoker.cpp	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/share/sample/vm/jvm-clr/invoker.cpp	Tue Oct 24 23:16:46 2017 -0700
@@ -152,7 +152,7 @@
 
     int nReturn = invokeCLR( wszApplication);
 
-    delete wszApplication;
+    delete[] wszApplication;
 
     return nReturn;
 }
--- a/src/solaris/native/sun/awt/gtk2_interface.c	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/solaris/native/sun/awt/gtk2_interface.c	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, 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
@@ -843,46 +843,41 @@
     }
 
     /*
-     * Strip the AT-SPI GTK_MODULEs if present
+     * Strip the AT-SPI GTK_MODULES if present
      */
     gtk_modules_env = getenv ("GTK_MODULES");
+    if ((gtk_modules_env && strstr(gtk_modules_env, "atk-bridge")) ||
+        (gtk_modules_env && strstr(gtk_modules_env, "gail"))) {
+        /* careful, strtok modifies its args */
+        gchar *tmp_env = strdup(gtk_modules_env);
+        if (tmp_env) {
+            /* the new env will be smaller than the old one */
+            gchar *s, *new_env = SAFE_SIZE_STRUCT_ALLOC(malloc,
+                    sizeof(ENV_PREFIX), 1, strlen (gtk_modules_env));
 
-    if (gtk_modules_env && strstr (gtk_modules_env, "atk-bridge") ||
-        gtk_modules_env && strstr (gtk_modules_env, "gail"))
-    {
-        /* the new env will be smaller than the old one */
-        gchar *s, *new_env = SAFE_SIZE_STRUCT_ALLOC(malloc,
-                sizeof(ENV_PREFIX), 1, strlen (gtk_modules_env));
-
-        if (new_env != NULL )
-        {
-            /* careful, strtok modifies its args */
-            gchar *tmp_env = strdup (gtk_modules_env);
-            strcpy(new_env, ENV_PREFIX);
+            if (new_env) {
+                strcpy(new_env, ENV_PREFIX);
 
-            /* strip out 'atk-bridge' and 'gail' */
-            size_t PREFIX_LENGTH = strlen(ENV_PREFIX);
-            while (s = strtok(tmp_env, ":"))
-            {
-                if ((!strstr (s, "atk-bridge")) && (!strstr (s, "gail")))
-                {
-                    if (strlen (new_env) > PREFIX_LENGTH) {
-                        new_env = strcat (new_env, ":");
+                /* strip out 'atk-bridge' and 'gail' */
+                size_t PREFIX_LENGTH = strlen(ENV_PREFIX);
+                gchar *tmp_ptr = NULL;
+                for (s = strtok_r(tmp_env, ":", &tmp_ptr); s;
+                     s = strtok_r(NULL, ":", &tmp_ptr)) {
+                    if ((!strstr(s, "atk-bridge")) && (!strstr(s, "gail"))) {
+                        if (strlen(new_env) > PREFIX_LENGTH) {
+                            new_env = strcat(new_env, ":");
+                        }
+                        new_env = strcat(new_env, s);
                     }
-                    new_env = strcat(new_env, s);
                 }
-                if (tmp_env)
-                {
-                    free (tmp_env);
-                    tmp_env = NULL; /* next call to strtok arg1==NULL */
+                if (putenv(new_env) != 0) {
+                    /* no free() on success, putenv() doesn't copy string */
+                    free(new_env);
                 }
             }
-            putenv (new_env);
-            free (new_env);
-            free (tmp_env);
+            free(tmp_env);
         }
     }
-
     /*
      * GTK should be initialized with gtk_init_check() before use.
      *
--- a/src/windows/native/sun/java2d/d3d/D3DGraphicsDevice.cpp	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/windows/native/sun/java2d/d3d/D3DGraphicsDevice.cpp	Tue Oct 24 23:16:46 2017 -0700
@@ -98,7 +98,7 @@
 
     jstring ret = JNU_NewStringPlatform(env, pAdapterId);
 
-    delete pAdapterId;
+    delete[] pAdapterId;
 
     return ret;
 }
--- a/src/windows/native/sun/windows/WPrinterJob.cpp	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/windows/native/sun/windows/WPrinterJob.cpp	Tue Oct 24 23:16:46 2017 -0700
@@ -508,14 +508,14 @@
           names = env->NewObjectArray(cReturned, cls, NULL);
       }
       if (names == NULL || cls == NULL) {
-          delete buf;
+          delete[] buf;
           return names;
       }
 
       for (int i = 0; i < cReturned; i++) {
           utf_str = JNU_NewStringPlatform(env, buf+(buf_len*i));
             if (utf_str == NULL) {
-                delete buf;
+                delete[] buf;
                 return names;
             }
             env->SetObjectArrayElement(names, i, utf_str);
--- a/src/windows/native/sun/windows/awt_Palette.cpp	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/windows/native/sun/windows/awt_Palette.cpp	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -148,7 +148,7 @@
         pEntry->peFlags = PC_EXPLICIT;
     }
     hPal = ::CreatePalette(pLogPal);
-    delete pLogPal;
+    delete[] pLogPal;
     if ( hPal == 0 ) {
         return 0;
     }
--- a/src/windows/native/sun/windows/awt_Robot.cpp	Tue Oct 24 13:07:11 2017 -0700
+++ b/src/windows/native/sun/windows/awt_Robot.cpp	Tue Oct 24 23:16:46 2017 -0700
@@ -278,7 +278,7 @@
 
     // copy pixels into Java array
     env->SetIntArrayRegion(pixelArray, 0, numPixels, (jint *)pixelData);
-    delete pinfo;
+    delete[] pinfo;
 
     // free all the GDI objects we made
     ::SelectObject(hdcMem, hOldBitmap);
--- a/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/test/com/sun/crypto/provider/KeyAgreement/TestExponentSize.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, 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
@@ -83,10 +83,10 @@
         KeyPair kp;
         KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", "SunJCE");
 
-        // Sun's default uses a default psize of 1024 and
+        // Sun's default uses a default psize of 2048 and
         // lsize of (pSize / 2) but at least 384 bits
         kp = kpg.generateKeyPair();
-        checkKeyPair(kp, Sizes.ten24, Sizes.five12);
+        checkKeyPair(kp, Sizes.twenty48, Sizes.ten24);
 
         DHPublicKey publicKey = (DHPublicKey)kp.getPublic();
         BigInteger p = publicKey.getParams().getP();
@@ -98,15 +98,15 @@
 
         kpg.initialize(new DHParameterSpec(p, g, Sizes.ten24.getIntSize()));
         kp = kpg.generateKeyPair();
-        checkKeyPair(kp, Sizes.ten24, Sizes.ten24);
+        checkKeyPair(kp, Sizes.twenty48, Sizes.ten24);
 
         kpg.initialize(new DHParameterSpec(p, g, Sizes.five12.getIntSize()));
         kp = kpg.generateKeyPair();
-        checkKeyPair(kp, Sizes.ten24, Sizes.five12);
+        checkKeyPair(kp, Sizes.twenty48, Sizes.five12);
 
         kpg.initialize(new DHParameterSpec(p, g, Sizes.two56.getIntSize()));
         kp = kpg.generateKeyPair();
-        checkKeyPair(kp, Sizes.ten24, Sizes.two56);
+        checkKeyPair(kp, Sizes.twenty48, Sizes.two56);
 
         kpg.initialize(Sizes.five12.getIntSize());
         kp = kpg.generateKeyPair();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/com/sun/jndi/dns/Parser.java	Tue Oct 24 23:16:46 2017 -0700
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2014, Red Hat, Inc.
+ * 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 8035105
+ * @summary DNS resource record parsing
+ */
+
+import com.sun.jndi.dns.ResourceRecord;
+import javax.naming.CommunicationException;
+import javax.naming.InvalidNameException;;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import java.io.IOException;
+
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+
+public class Parser {
+    static Constructor<ResourceRecord> rrConstructor;
+    static {
+        try {
+            rrConstructor = ResourceRecord.class.getDeclaredConstructor(
+                byte[].class, int.class, int.class, boolean.class,
+                boolean.class);
+            rrConstructor.setAccessible(true);
+        } catch (Exception e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    static ResourceRecord parse(String data, int offset, boolean qSection)
+        throws Throwable {
+        byte[] bytes = data.getBytes(ISO_8859_1);
+        try {
+            return rrConstructor.newInstance(
+                bytes, bytes.length, offset, qSection, !qSection);
+        } catch (InvocationTargetException e) {
+            throw e.getCause();
+        }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        ResourceRecord rr;
+
+        rr = parse("\003www\007example\003com\000\000\002\000\001",
+            0, true);
+        if (!rr.getName().toString().equals("www.example.com."))
+            throw new AssertionError(rr.getName().toString());
+        if (rr.getRrclass() != 1)
+            throw new AssertionError("RCLASS: " + rr.getRrclass());
+        if (rr.getType() != 2)
+            throw new AssertionError("RTYPE: " + rr.getType());
+
+        String longLabel = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +
+            "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+
+        rr = parse("\077" + longLabel + "\077" + longLabel +
+            "\077" + longLabel + "\061" + longLabel.substring(0, 49) +
+            "\007example\003com\000\000\002\000\001",
+             0, true);
+        if (!rr.getName().toString().equals(longLabel +
+            '.' + longLabel + '.' + longLabel +
+            '.' + longLabel.substring(0, 49) + ".example.com."))
+            throw new AssertionError(rr.getName().toString());
+        if (rr.getRrclass() != 1)
+            throw new AssertionError("RCLASS: " + rr.getRrclass());
+        if (rr.getType() != 2)
+            throw new AssertionError("RTYPE: " + rr.getType());
+
+        rr = parse("1-2-3-4-5-6-" +
+            "\003www\007example\003com\000\000\002\000\001" +
+            "\300\014\000\002\000\001\000\001\121\200" +
+            "\000\005\002ns\300\020",
+            33, false);
+        if (!rr.getName().toString().equals("www.example.com."))
+            throw new AssertionError(rr.getName().toString());
+        if (rr.getRrclass() != 1)
+            throw new AssertionError("RCLASS: " + rr.getRrclass());
+        if (rr.getType() != 2)
+            throw new AssertionError("RTYPE: " + rr.getType());
+        if (!rr.getRdata().toString().equals("ns.example.com."))
+            throw new AssertionError("RDATA: " + rr.getRdata());
+
+        try {
+            parse("1-2-3-4-5-6-" +
+                "\003www\007example\003com\000\000\002\000\001" +
+                "\300\014\000\002\000\001\300\051\300\047" +
+                "\000\005\002ns\300\051",
+                33, false);
+            throw new AssertionError();
+        } catch (CommunicationException e) {
+            if (!e.getMessage().equals("DNS error: malformed packet")
+                || e.getCause().getClass() != IOException.class
+                || !e.getCause().getMessage().equals(
+                    "Too many compression references"))
+                throw e;
+        }
+
+        try {
+            String longLabel62 = "\076" + longLabel.substring(1);
+            parse(longLabel62 + longLabel62 + longLabel62 + longLabel62 +
+                "\002XX\000\000\002\000\001", 0, true);
+            throw new AssertionError();
+        } catch (CommunicationException e) {
+            if (!e.getMessage().equals("DNS error: malformed packet")
+                || e.getCause().getClass() != InvalidNameException.class
+                || !e.getCause().getMessage().equals("Name too long"))
+                throw e;
+        }
+        try {
+            parse("\100Y" + longLabel + "\000\000\002\000\001", 0, true);
+            throw new AssertionError();
+        } catch (CommunicationException e) {
+            if (!e.getMessage().equals("DNS error: malformed packet")
+                || e.getCause().getClass() != IOException.class
+                || !e.getCause().getMessage().equals("Invalid label type: 64"))
+                throw e;
+        }
+    }
+}
--- a/test/java/rmi/testlibrary/TestSocketFactory.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/test/java/rmi/testlibrary/TestSocketFactory.java	Tue Oct 24 23:16:46 2017 -0700
@@ -45,20 +45,43 @@
 import java.util.Set;
 
 import org.testng.Assert;
-import org.testng.TestNG;
 import org.testng.annotations.Test;
 import org.testng.annotations.DataProvider;
 
+/*
+ * @test
+ * @summary TestSocket Factory and tests of the basic trigger, match, and replace functions
+ * @run testng TestSocketFactory
+ * @bug 8186539
+ */
 
 /**
  * A RMISocketFactory utility factory to log RMI stream contents and to
- * match and replace output stream contents to simulate failures.
+ * trigger, and then match and replace output stream contents to simulate failures.
+ * <p>
+ * The trigger is a sequence of bytes that must be found before looking
+ * for the bytes to match and replace.  If the trigger sequence is empty
+ * matching is immediately enabled. While waiting for the trigger to be found
+ * bytes written to the streams are written through to the output stream.
+ * The when triggered and when a trigger is non-empty, matching looks for
+ * the sequence of bytes supplied.  If the sequence is empty, no matching or
+ * replacement is performed.
+ * While waiting for a complete match, the partial matched bytes are not
+ * written to the output stream.  When the match is incomplete, the partial
+ * matched bytes are written to the output.  When a match is complete the
+ * full replacement byte array is written to the output.
+ * <p>
+ * The trigger, match, and replacement bytes arrays can be changed at any
+ * time and immediately reset and restart matching.  Changes are propagated
+ * to all of the sockets created from the factories immediately.
  */
 public class TestSocketFactory extends RMISocketFactory
         implements RMIClientSocketFactory, RMIServerSocketFactory, Serializable {
 
     private static final long serialVersionUID = 1L;
 
+    private volatile transient byte[] triggerBytes;
+
     private volatile transient byte[] matchBytes;
 
     private volatile transient byte[] replaceBytes;
@@ -67,6 +90,8 @@
 
     private transient final List<InterposeServerSocket> serverSockets = new ArrayList<>();
 
+    static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
     public static final boolean DEBUG = false;
 
     /**
@@ -82,28 +107,51 @@
     }
 
     /**
-     * Create a socket factory that creates InputStreams that log
-     * and OutputStreams that log .
+     * Create a socket factory that creates InputStreams
+     * and OutputStreams that log.
      */
     public TestSocketFactory() {
-        this.matchBytes = new byte[0];
-        this.replaceBytes = this.matchBytes;
-        System.out.printf("Creating TestSocketFactory()%n");
+        this.triggerBytes = EMPTY_BYTE_ARRAY;
+        this.matchBytes = EMPTY_BYTE_ARRAY;
+        this.replaceBytes = EMPTY_BYTE_ARRAY;
+    }
+
+    /**
+     * Set the match and replacement bytes, with an empty trigger.
+     * The match and replacements are propagated to all existing sockets.
+     *
+     * @param matchBytes bytes to match
+     * @param replaceBytes bytes to replace the matched bytes
+     */
+    public void setMatchReplaceBytes(byte[] matchBytes, byte[] replaceBytes) {
+        setMatchReplaceBytes(EMPTY_BYTE_ARRAY, matchBytes, replaceBytes);
     }
 
-    public void setMatchReplaceBytes(byte[] matchBytes, byte[] replaceBytes) {
+    /**
+     * Set the trigger, match, and replacement bytes.
+     * The trigger, match, and replacements are propagated to all existing sockets.
+     *
+     * @param triggerBytes array of bytes to use as a trigger, may be zero length
+     * @param matchBytes bytes to match after the trigger has been seen
+     * @param replaceBytes bytes to replace the matched bytes
+     */
+    public void setMatchReplaceBytes(byte[] triggerBytes, byte[] matchBytes,
+                                     byte[] replaceBytes) {
+        this.triggerBytes = Objects.requireNonNull(triggerBytes, "triggerBytes");
         this.matchBytes = Objects.requireNonNull(matchBytes, "matchBytes");
         this.replaceBytes = Objects.requireNonNull(replaceBytes, "replaceBytes");
-        sockets.forEach( s -> s.setMatchReplaceBytes(matchBytes, replaceBytes));
-        serverSockets.forEach( s -> s.setMatchReplaceBytes(matchBytes, replaceBytes));
-
+        sockets.forEach( s -> s.setMatchReplaceBytes(triggerBytes, matchBytes,
+                replaceBytes));
+        serverSockets.forEach( s -> s.setMatchReplaceBytes(triggerBytes, matchBytes,
+                replaceBytes));
     }
 
     @Override
     public Socket createSocket(String host, int port) throws IOException {
         Socket socket = RMISocketFactory.getDefaultSocketFactory()
                 .createSocket(host, port);
-        InterposeSocket s = new InterposeSocket(socket, matchBytes, replaceBytes);
+        InterposeSocket s = new InterposeSocket(socket,
+                triggerBytes, matchBytes, replaceBytes);
         sockets.add(s);
         return s;
     }
@@ -122,7 +170,8 @@
 
         ServerSocket serverSocket = RMISocketFactory.getDefaultSocketFactory()
                 .createServerSocket(port);
-        InterposeServerSocket ss = new InterposeServerSocket(serverSocket, matchBytes, replaceBytes);
+        InterposeServerSocket ss = new InterposeServerSocket(serverSocket,
+                triggerBytes, matchBytes, replaceBytes);
         serverSockets.add(ss);
         return ss;
     }
@@ -139,13 +188,15 @@
     /**
      * An InterposeSocket wraps a socket that produces InputStreams
      * and OutputStreams that log the traffic.
-     * The OutputStreams it produces match an array of bytes and replace them.
+     * The OutputStreams it produces watch for a trigger and then
+     * match an array of bytes and replace them.
      * Useful for injecting protocol and content errors.
      */
     public static class InterposeSocket extends Socket {
         private final Socket socket;
         private InputStream in;
         private MatchReplaceOutputStream out;
+        private volatile byte[] triggerBytes;
         private volatile byte[] matchBytes;
         private volatile byte[] replaceBytes;
         private final ByteArrayOutputStream inLogStream;
@@ -153,8 +204,28 @@
         private final String name;
         private static volatile int num = 0;    // index for created InterposeSockets
 
+        /**
+         * Construct a socket that interposes on a socket to match and replace.
+         * The trigger is empty.
+         * @param socket the underlying socket
+         * @param matchBytes the bytes that must match
+         * @param replaceBytes the replacement bytes
+         */
         public InterposeSocket(Socket socket, byte[] matchBytes, byte[] replaceBytes) {
+            this(socket, EMPTY_BYTE_ARRAY, matchBytes, replaceBytes);
+        }
+
+        /**
+         * Construct a socket that interposes on a socket to match and replace.
+         * @param socket the underlying socket
+         * @param triggerBytes array of bytes to enable matching
+         * @param matchBytes the bytes that must match
+         * @param replaceBytes the replacement bytes
+         */
+        public InterposeSocket(Socket socket, byte[]
+                triggerBytes, byte[] matchBytes, byte[] replaceBytes) {
             this.socket = socket;
+            this.triggerBytes = Objects.requireNonNull(triggerBytes, "triggerBytes");
             this.matchBytes = Objects.requireNonNull(matchBytes, "matchBytes");
             this.replaceBytes = Objects.requireNonNull(replaceBytes, "replaceBytes");
             this.inLogStream = new ByteArrayOutputStream();
@@ -164,10 +235,32 @@
                     + socket.getLocalPort() + " <  " + socket.getPort();
         }
 
+        /**
+         * Set the match and replacement bytes, with an empty trigger.
+         * The match and replacements are propagated to all existing sockets.
+         *
+         * @param matchBytes bytes to match
+         * @param replaceBytes bytes to replace the matched bytes
+         */
         public void setMatchReplaceBytes(byte[] matchBytes, byte[] replaceBytes) {
+            this.setMatchReplaceBytes(EMPTY_BYTE_ARRAY, matchBytes, replaceBytes);
+        }
+
+        /**
+         * Set the trigger, match, and replacement bytes.
+         * The trigger, match, and replacements are propagated to the
+         * MatchReplaceOutputStream.
+         *
+         * @param triggerBytes array of bytes to use as a trigger, may be zero length
+         * @param matchBytes bytes to match after the trigger has been seen
+         * @param replaceBytes bytes to replace the matched bytes
+         */
+        public void setMatchReplaceBytes(byte[] triggerBytes, byte[] matchBytes,
+                                         byte[] replaceBytes) {
+            this.triggerBytes = triggerBytes;
             this.matchBytes = matchBytes;
             this.replaceBytes = replaceBytes;
-            out.setMatchReplaceBytes(matchBytes, replaceBytes);
+            out.setMatchReplaceBytes(triggerBytes, matchBytes, replaceBytes);
         }
 
         @Override
@@ -263,7 +356,8 @@
                 OutputStream o = socket.getOutputStream();
                 String name = Thread.currentThread().getName() + ": "
                         + socket.getLocalPort() + "  > " + socket.getPort();
-                out = new MatchReplaceOutputStream(o, name, outLogStream, matchBytes, replaceBytes);
+                out = new MatchReplaceOutputStream(o, name, outLogStream,
+                        triggerBytes, matchBytes, replaceBytes);
                 DEBUG("Created new MatchReplaceOutputStream: %s%n", name);
             }
             return out;
@@ -293,20 +387,63 @@
      */
     public static class InterposeServerSocket extends ServerSocket {
         private final ServerSocket socket;
+        private volatile byte[] triggerBytes;
         private volatile byte[] matchBytes;
         private volatile byte[] replaceBytes;
         private final List<InterposeSocket> sockets = new ArrayList<>();
 
-        public InterposeServerSocket(ServerSocket socket, byte[] matchBytes, byte[] replaceBytes) throws IOException {
+        /**
+         * Construct a server socket that interposes on a socket to match and replace.
+         * The trigger is empty.
+         * @param socket the underlying socket
+         * @param matchBytes the bytes that must match
+         * @param replaceBytes the replacement bytes
+         */
+        public InterposeServerSocket(ServerSocket socket, byte[] matchBytes,
+                                     byte[] replaceBytes) throws IOException {
+            this(socket, EMPTY_BYTE_ARRAY, matchBytes, replaceBytes);
+        }
+
+        /**
+         * Construct a server socket that interposes on a socket to match and replace.
+         * @param socket the underlying socket
+         * @param triggerBytes array of bytes to enable matching
+         * @param matchBytes the bytes that must match
+         * @param replaceBytes the replacement bytes
+         */
+        public InterposeServerSocket(ServerSocket socket, byte[] triggerBytes,
+                                     byte[] matchBytes, byte[] replaceBytes) throws IOException {
             this.socket = socket;
+            this.triggerBytes = Objects.requireNonNull(triggerBytes, "triggerBytes");
             this.matchBytes = Objects.requireNonNull(matchBytes, "matchBytes");
             this.replaceBytes = Objects.requireNonNull(replaceBytes, "replaceBytes");
         }
 
+        /**
+         * Set the match and replacement bytes, with an empty trigger.
+         * The match and replacements are propagated to all existing sockets.
+         *
+         * @param matchBytes bytes to match
+         * @param replaceBytes bytes to replace the matched bytes
+         */
         public void setMatchReplaceBytes(byte[] matchBytes, byte[] replaceBytes) {
+            setMatchReplaceBytes(EMPTY_BYTE_ARRAY, matchBytes, replaceBytes);
+        }
+
+        /**
+         * Set the trigger, match, and replacement bytes.
+         * The trigger, match, and replacements are propagated to all existing sockets.
+         *
+         * @param triggerBytes array of bytes to use as a trigger, may be zero length
+         * @param matchBytes bytes to match after the trigger has been seen
+         * @param replaceBytes bytes to replace the matched bytes
+         */
+        public void setMatchReplaceBytes(byte[] triggerBytes, byte[] matchBytes,
+                                         byte[] replaceBytes) {
+            this.triggerBytes = triggerBytes;
             this.matchBytes = matchBytes;
             this.replaceBytes = replaceBytes;
-            sockets.forEach(s -> s.setMatchReplaceBytes(matchBytes, replaceBytes));
+            sockets.forEach(s -> s.setMatchReplaceBytes(triggerBytes, matchBytes, replaceBytes));
         }
         /**
          * Return a snapshot of the current list of sockets created from this server socket.
@@ -433,22 +570,33 @@
     }
 
     /**
-     * An OutputStream that replaces one string of bytes with another.
+     * An OutputStream that looks for a trigger to enable matching and
+     * replaces one string of bytes with another.
      * If any range matches, the match starts after the partial match.
      */
     static class MatchReplaceOutputStream extends OutputStream {
         private final OutputStream out;
         private final String name;
+        private volatile byte[] triggerBytes;
         private volatile byte[] matchBytes;
         private volatile byte[] replaceBytes;
+        int triggerIndex;
         int matchIndex;
         private int bytesOut = 0;
         private final OutputStream log;
 
         MatchReplaceOutputStream(OutputStream out, String name, OutputStream log,
                                  byte[] matchBytes, byte[] replaceBytes) {
+            this(out, name, log, EMPTY_BYTE_ARRAY, matchBytes, replaceBytes);
+        }
+
+        MatchReplaceOutputStream(OutputStream out, String name, OutputStream log,
+                                 byte[] triggerBytes, byte[] matchBytes,
+                                 byte[] replaceBytes) {
             this.out = out;
             this.name = name;
+            this.triggerBytes = Objects.requireNonNull(triggerBytes, "triggerBytes");
+            triggerIndex = 0;
             this.matchBytes = Objects.requireNonNull(matchBytes, "matchBytes");
             this.replaceBytes = Objects.requireNonNull(replaceBytes, "replaceBytes");
             matchIndex = 0;
@@ -456,8 +604,15 @@
         }
 
         public void setMatchReplaceBytes(byte[] matchBytes, byte[] replaceBytes) {
-            this.matchBytes = matchBytes;
-            this.replaceBytes = replaceBytes;
+            setMatchReplaceBytes(EMPTY_BYTE_ARRAY, matchBytes, replaceBytes);
+        }
+
+        public void setMatchReplaceBytes(byte[] triggerBytes, byte[] matchBytes,
+                                         byte[] replaceBytes) {
+            this.triggerBytes = Objects.requireNonNull(triggerBytes, "triggerBytes");
+            triggerIndex = 0;
+            this.matchBytes = Objects.requireNonNull(matchBytes, "matchBytes");
+            this.replaceBytes = Objects.requireNonNull(replaceBytes, "replaceBytes");
             matchIndex = 0;
         }
 
@@ -465,38 +620,65 @@
         public void write(int b) throws IOException {
             b = b & 0xff;
             if (matchBytes.length == 0) {
+                // fast path, no match
                 out.write(b);
                 log.write(b);
                 bytesOut++;
                 return;
             }
-            if (b == (matchBytes[matchIndex] & 0xff)) {
-                if (++matchIndex >= matchBytes.length) {
-                    matchIndex = 0;
-                    DEBUG( "TestSocketFactory MatchReplace %s replaced %d bytes at offset: %d (x%04x)%n",
-                            name, replaceBytes.length, bytesOut, bytesOut);
-                    out.write(replaceBytes);
-                    log.write(replaceBytes);
-                    bytesOut += replaceBytes.length;
-                }
+            // if trigger not satisfied, keep looking
+            if (triggerBytes.length != 0 && triggerIndex < triggerBytes.length) {
+                out.write(b);
+                log.write(b);
+                bytesOut++;
+
+                triggerIndex = (b == (triggerBytes[triggerIndex] & 0xff))
+                        ? ++triggerIndex    // matching advance
+                        : 0;
             } else {
-                if (matchIndex > 0) {
-                    // mismatch, write out any that matched already
-                    if (matchIndex > 0) // Only non-trivial matches
-                        DEBUG( "Partial match %s matched %d bytes at offset: %d (0x%04x), expected: x%02x, actual: x%02x%n",
-                                name, matchIndex, bytesOut, bytesOut,  matchBytes[matchIndex], b);
-                    out.write(matchBytes, 0, matchIndex);
-                    log.write(matchBytes, 0, matchIndex);
-                    bytesOut += matchIndex;
-                    matchIndex = 0;
+                // trigger not used or has been satisfied
+                if (b == (matchBytes[matchIndex] & 0xff)) {
+                    if (++matchIndex >= matchBytes.length) {
+                        matchIndex = 0;
+                        triggerIndex = 0;       // match/replace ok, reset trigger
+                        DEBUG("TestSocketFactory MatchReplace %s replaced %d bytes " +
+                                "at offset: %d (x%04x)%n",
+                                name, replaceBytes.length, bytesOut, bytesOut);
+                        out.write(replaceBytes);
+                        log.write(replaceBytes);
+                        bytesOut += replaceBytes.length;
+                    }
+                } else {
+                    if (matchIndex > 0) {
+                        // mismatch, write out any that matched already
+                        DEBUG("Partial match %s matched %d bytes at offset: %d (0x%04x), expected: x%02x, actual: x%02x%n",
+                            name, matchIndex, bytesOut, bytesOut, matchBytes[matchIndex], b);
+                        out.write(matchBytes, 0, matchIndex);
+                        log.write(matchBytes, 0, matchIndex);
+                        bytesOut += matchIndex;
+                        matchIndex = 0;
+                    }
+                    if (b == (matchBytes[matchIndex] & 0xff)) {
+                        matchIndex++;
+                    } else {
+                        out.write(b);
+                        log.write(b);
+                        bytesOut++;
+                    }
                 }
-                if (b == (matchBytes[matchIndex] & 0xff)) {
-                    matchIndex++;
-                } else {
-                    out.write(b);
-                    log.write(b);
-                    bytesOut++;
-                }
+            }
+        }
+
+        public void flush() throws IOException {
+            if (matchIndex > 0) {
+                // write out any that matched already to avoid consumer hang.
+                // Match/replace across a flush is not supported.
+                DEBUG( "Flush partial match %s matched %d bytes at offset: %d (0x%04x)%n",
+                        name, matchIndex, bytesOut, bytesOut);
+                out.write(matchBytes, 0, matchIndex);
+                log.write(matchBytes, 0, matchIndex);
+                bytesOut += matchIndex;
+                matchIndex = 0;
             }
         }
 
@@ -506,18 +688,44 @@
         }
     }
 
-    private static byte[] orig = new byte[]{
+    private static byte[] obj1Data = new byte[] {
+            0x7e, 0x7e, 0x7e,
             (byte) 0x80, 0x05,
-            0x73, 0x72, 0x00, 0x12, // TC_OBJECT, TC_CLASSDESC, length = 18
-            0x6A, 0x61, 0x76, 0x61, 0x2E, 0x72, 0x6D, 0x69, 0x2E, // "java.rmi."
-            0x64, 0x67, 0x63, 0x2E, 0x4C, 0x65, 0x61, 0x73, 0x65  // "dgc.Lease"
+            0x7f, 0x7f, 0x7f,
+            0x73, 0x72, 0x00, 0x10, // TC_OBJECT, TC_CLASSDESC, length = 16
+            (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'.',
+            (byte)'l', (byte)'a', (byte)'n', (byte)'g', (byte)'.',
+            (byte)'n', (byte)'u', (byte)'m', (byte)'b', (byte)'e', (byte)'r'
+    };
+    private static byte[] obj1Result = new byte[] {
+            0x7e, 0x7e, 0x7e,
+            (byte) 0x80, 0x05,
+            0x7f, 0x7f, 0x7f,
+            0x73, 0x72, 0x00, 0x11, // TC_OBJECT, TC_CLASSDESC, length = 17
+            (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'.',
+            (byte)'l', (byte)'a', (byte)'n', (byte)'g', (byte)'.',
+            (byte)'I', (byte)'n', (byte)'t', (byte)'e', (byte)'g', (byte)'e', (byte)'r'
     };
-    private static byte[] repl = new byte[]{
-            (byte) 0x80, 0x05,
-            0x73, 0x72, 0x00, 0x12, // TC_OBJECT, TC_CLASSDESC, length = 18
-            0x6A, 0x61, 0x76, 0x61, 0x2E, (byte) 'l', (byte) 'a', (byte) 'n', (byte) 'g',
-            0x2E, (byte) 'R', (byte) 'u', (byte) 'n', (byte) 'n', (byte) 'a', (byte) 'b', (byte) 'l',
-            (byte) 'e'
+    private static byte[] obj1Trigger = new byte[] {
+            (byte) 0x80, 0x05
+    };
+    private static byte[] obj1Trigger2 = new byte[] {
+            0x7D, 0x7D, 0x7D, 0x7D,
+    };
+    private static byte[] obj1Trigger3 = new byte[] {
+            0x7F,
+    };
+    private static byte[] obj1Match = new byte[] {
+            0x73, 0x72, 0x00, 0x10, // TC_OBJECT, TC_CLASSDESC, length = 16
+            (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'.',
+            (byte)'l', (byte)'a', (byte)'n', (byte)'g', (byte)'.',
+            (byte)'n', (byte)'u', (byte)'m', (byte)'b', (byte)'e', (byte)'r'
+    };
+    private static byte[] obj1Repl = new byte[] {
+            0x73, 0x72, 0x00, 0x11, // TC_OBJECT, TC_CLASSDESC, length = 17
+            (byte)'j', (byte)'a', (byte)'v', (byte)'a', (byte)'.',
+            (byte)'l', (byte)'a', (byte)'n', (byte)'g', (byte)'.',
+            (byte)'I', (byte)'n', (byte)'t', (byte)'e', (byte)'g', (byte)'e', (byte)'r'
     };
 
     @DataProvider(name = "MatchReplaceData")
@@ -532,26 +740,42 @@
         byte[] bytes6 = new byte[]{1, 2, 0x10, 0x20, 0x30};
 
         return new Object[][]{
-                {new byte[]{}, new byte[]{}, empty, empty},
-                {new byte[]{}, new byte[]{}, byte1, byte1},
-                {new byte[]{3, 4}, new byte[]{4, 3}, byte1, bytes2}, //swap bytes
-                {new byte[]{3, 4}, new byte[]{0x10, 0x20, 0x30, 0x40}, byte1, bytes4}, // insert
-                {new byte[]{1, 2, 0x10, 0x20}, new byte[]{}, bytes4, bytes5}, // delete head
-                {new byte[]{0x40, 5, 6}, new byte[]{}, bytes4, bytes6},   // delete tail
-                {new byte[]{0x40, 0x50}, new byte[]{0x60, 0x50}, bytes4, bytes4}, // partial match, replace nothing
-                {bytes4a, bytes3, bytes4, bytes4}, // long partial match, not replaced
-                {orig, repl, orig, repl},
+                {EMPTY_BYTE_ARRAY, new byte[]{}, new byte[]{},
+                        empty, empty},
+                {EMPTY_BYTE_ARRAY, new byte[]{}, new byte[]{},
+                        byte1, byte1},
+                {EMPTY_BYTE_ARRAY, new byte[]{3, 4}, new byte[]{4, 3},
+                        byte1, bytes2}, //swap bytes
+                {EMPTY_BYTE_ARRAY, new byte[]{3, 4}, new byte[]{0x10, 0x20, 0x30, 0x40},
+                        byte1, bytes4}, // insert
+                {EMPTY_BYTE_ARRAY, new byte[]{1, 2, 0x10, 0x20}, new byte[]{},
+                        bytes4, bytes5}, // delete head
+                {EMPTY_BYTE_ARRAY, new byte[]{0x40, 5, 6}, new byte[]{},
+                        bytes4, bytes6},   // delete tail
+                {EMPTY_BYTE_ARRAY, new byte[]{0x40, 0x50}, new byte[]{0x60, 0x50},
+                        bytes4, bytes4}, // partial match, replace nothing
+                {EMPTY_BYTE_ARRAY, bytes4a, bytes3,
+                        bytes4, bytes4}, // long partial match, not replaced
+                {EMPTY_BYTE_ARRAY, obj1Match, obj1Repl,
+                        obj1Match, obj1Repl},
+                {obj1Trigger, obj1Match, obj1Repl,
+                        obj1Data, obj1Result},
+                {obj1Trigger3, obj1Match, obj1Repl,
+                        obj1Data, obj1Result}, // different trigger, replace
+                {obj1Trigger2, obj1Match, obj1Repl,
+                        obj1Data, obj1Data},  // no trigger, no replace
         };
     }
 
-    @Test(enabled = true, dataProvider = "MatchReplaceData")
-    static void test3(byte[] match, byte[] replace,
+    @Test(dataProvider = "MatchReplaceData")
+    public static void test1(byte[] trigger, byte[] match, byte[] replace,
                       byte[] input, byte[] expected) {
-        System.out.printf("match: %s, replace: %s%n", Arrays.toString(match), Arrays.toString(replace));
+        System.out.printf("trigger: %s, match: %s, replace: %s%n", Arrays.toString(trigger),
+                Arrays.toString(match), Arrays.toString(replace));
         try (ByteArrayOutputStream output = new ByteArrayOutputStream();
         ByteArrayOutputStream log = new ByteArrayOutputStream();
              OutputStream out = new MatchReplaceOutputStream(output, "test3",
-                     log, match, replace)) {
+                     log, trigger, match, replace)) {
             out.write(input);
             byte[] actual = output.toByteArray();
 
@@ -564,7 +788,4 @@
             Assert.fail("unexpected exception", ioe);
         }
     }
-
-
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java	Tue Oct 24 23:16:46 2017 -0700
@@ -0,0 +1,327 @@
+/*
+ * 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 8159377
+ * @library /lib/testlibrary
+ * @summary Tests ObjectFilter on default agent
+ * @author Harsha Wardhana B
+ * @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 java.util.concurrent.TimeUnit;
+
+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);
+
+        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;
+                            }, 10, TimeUnit.SECONDS);
+                    if (bindError.get()) {
+                        throw new BindException("Process could not be started");
+                    } else if (error.get()) {
+                        throw new RuntimeException();
+                    }
+                } catch (Exception ex) {
+                    if (p != null) {
+                        p.destroy();
+                        p.waitFor();
+                    }
+                    throw ex;
+                }
+            }
+        }
+
+        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/javax/management/remote/mandatory/connection/NewRMIClientFilterTest.java	Tue Oct 24 23:16:46 2017 -0700
@@ -0,0 +1,146 @@
+/*
+ * 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 8159377
+ * @summary Tests ObjectInputFilter on RMIServer.newClient
+ * @author Harsha Wardhana B
+ * @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 com.sun.jmx.remote.util.EnvHelp;
+
+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(EnvHelp.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(EnvHelp.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/javax/management/remote/mandatory/connection/mgmt1.properties	Tue Oct 24 23:16:46 2017 -0700
@@ -0,0 +1,34 @@
+# ################ 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 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.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/management/remote/mandatory/connection/mgmt2.properties	Tue Oct 24 23:16:46 2017 -0700
@@ -0,0 +1,34 @@
+# ################ 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 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/test/javax/management/remote/mandatory/connectorServer/RMIExporterTest.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/test/javax/management/remote/mandatory/connectorServer/RMIExporterTest.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 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
@@ -46,6 +46,7 @@
 import javax.management.remote.JMXConnectorServerFactory;
 import javax.management.remote.JMXServiceURL;
 import com.sun.jmx.remote.internal.RMIExporter;
+import sun.misc.ObjectInputFilter;
 
 public class RMIExporterTest {
 
@@ -59,7 +60,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/javax/management/remote/nonLocalAccess/NonLocalJMXRemoteTest.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/test/javax/management/remote/nonLocalAccess/NonLocalJMXRemoteTest.java	Tue Oct 24 23:16:46 2017 -0700
@@ -44,14 +44,37 @@
  * This tests the SingleEntryRegistry implemented by JMX.
  * This test is a manual test and uses JMX running on a *different* host.
  * JMX can be enabled in any Java runtime; for example:
- * login or ssh to the different host and invoke rmiregistry with arguments below.
+ *
+ * Note: Use remote host with latest JDK update release for invoking rmiregistry.
+ *
+ * Note: Test should be ran twice once using arg1 and once using arg2.
+ *
+ * login or ssh to the remote host and invoke rmiregistry with arg1.
  * It will not show any output.
- * {@code $JDK_HOME/bin/rmiregistry \
+ * Execute the test, after test completes execution, stop the server.
+ *
+ * repeat above step using arg2 and execute the test.
+ *
+ *
+ * arg1: {@code $JDK_HOME/bin/rmiregistry \
  *         -J-Dcom.sun.management.jmxremote.port=8888 \
  *         -J-Dcom.sun.management.jmxremote.local.only=false \
  *         -J-Dcom.sun.management.jmxremote.ssl=false \
  *         -J-Dcom.sun.management.jmxremote.authenticate=false
  * }
+ *
+ *
+ * replace "jmx-registry-host" with the hostname or IP address of the remote host
+ * for property "-J-Dcom.sun.management.jmxremote.host" below.
+ *
+ * arg2: {@code $JDK_HOME/bin/rmiregistry \
+ *         -J-Dcom.sun.management.jmxremote.port=8888 \
+ *         -J-Dcom.sun.management.jmxremote.local.only=false \
+ *         -J-Dcom.sun.management.jmxremote.ssl=false \
+ *         -J-Dcom.sun.management.jmxremote.authenticate=false \
+ *         -J-Dcom.sun.management.jmxremote.host="jmx-registry-host"
+ * }
+ *
  * On the first host modify the @run command above to replace "jmx-registry-host"
  * with the hostname or IP address of the different host and run the test with jtreg.
  */
@@ -132,6 +155,7 @@
             if (asIndex < 0 ||
                     disallowIndex < 0 ||
                     nonLocalHostIndex < 0 ) {
+                System.out.println("Exception message is " + msg);
                 throw new RuntimeException("exception message is malformed", t);
             }
             System.out.printf("Found expected AccessException: %s%n%n", t);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/testlibrary/CompilerUtils.java	Tue Oct 24 23:16:46 2017 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.tools.JavaCompiler;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+
+/**
+ * This class consists exclusively of static utility methods for invoking the
+ * java compiler.
+ */
+
+public final class CompilerUtils {
+    private static final String TEST_JAVA_HOME = System.getProperty("test.jdk");
+    private static final String FS = File.separator;
+    private static final String JAVAC = TEST_JAVA_HOME + FS + "bin" + FS + "javac";
+
+    private CompilerUtils() { }
+
+    /**
+     * Compile all the java sources in {@code <source>/**} to
+     * {@code <destination>/**}. The destination directory will be created if
+     * it doesn't exist.
+     *
+     * All warnings/errors emitted by the compiler are output to System.out/err.
+     *
+     * @return true if the compilation is successful
+     *
+     * @throws IOException
+     *         if there is an I/O error scanning the source tree or
+     *         creating the destination directory
+     * @throws UnsupportedOperationException
+     *         if there is no system java compiler
+     */
+    public static boolean compile(Path source, Path destination, String ... options)
+        throws IOException
+    {
+        List<Path> sources
+            = Files.find(source, Integer.MAX_VALUE,
+                (file, attrs) -> (file.toString().endsWith(".java")))
+                .collect(Collectors.toList());
+
+        Files.createDirectories(destination);
+        List<String> opts = Arrays.asList(options);
+        List<String> compileargs = new ArrayList<String> ();
+        compileargs.add(JAVAC);
+        compileargs.add("-d");
+        compileargs.add(destination.toString());
+        for(String opt: opts) {
+            compileargs.add(opt);
+        }
+        for(Path p: sources) {
+            compileargs.add(p.toString());
+        }
+
+        OutputAnalyzer output = null;
+        try {
+            String[] sarr = compileargs.toArray(new String[0]);
+            output = ProcessTools.executeCommand(sarr);
+            output.shouldHaveExitValue(0);
+        } catch (Throwable t) {
+            throw new RuntimeException("Javac failed", t);
+        }
+
+        return true;
+    }
+}
--- a/test/sun/net/www/http/HttpClient/B8025710.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/test/sun/net/www/http/HttpClient/B8025710.java	Tue Oct 24 23:16:46 2017 -0700
@@ -37,6 +37,7 @@
  * @test
  * @bug 8025710
  * @summary Proxied https connection reuse by HttpClient can send CONNECT to the server
+ * @run main/othervm B8025710
  */
 public class B8025710 {
 
@@ -47,6 +48,9 @@
     private static final String passphrase = "passphrase";
 
     public static void main(String[] args) throws Exception {
+        // test uses legacy MD5 based cert
+        Security.setProperty("jdk.certpath.disabledAlgorithms", "");
+        Security.setProperty("jdk.tls.disabledAlgorithms", "");
         new B8025710().runTest();
 
         if (connectInServer.get())
--- a/test/sun/security/pkcs11/PKCS11Test.java	Tue Oct 24 13:07:11 2017 -0700
+++ b/test/sun/security/pkcs11/PKCS11Test.java	Tue Oct 24 23:16:46 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, 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
@@ -509,6 +509,8 @@
             PKCS11_BASE + "/nss/lib/windows-i586/".replace('/', SEP)});
         osMap.put("Windows-amd64-64", new String[]{
             PKCS11_BASE + "/nss/lib/windows-amd64/".replace('/', SEP)});
+        osMap.put("MacOSX-x86_64-64", new String[]{
+            PKCS11_BASE + "/nss/lib/macosx-x86_64/"});
     }
 
     private final static char[] hexDigits = "0123456789abcdef".toCharArray();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/ssl/DHKeyExchange/LegacyDHEKeyExchange.java	Tue Oct 24 23:16:46 2017 -0700
@@ -0,0 +1,325 @@
+/*
+ * 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.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8148108
+ * @summary Disable Diffie-Hellman keys less than 1024 bits
+ * @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy LegacyDHEKeyExchange
+ */
+
+import java.io.*;
+import javax.net.ssl.*;
+
+public class LegacyDHEKeyExchange {
+
+    /*
+     * =============================================================
+     * Set the various variables needed for the tests, then
+     * specify what tests to run on each side.
+     */
+
+    /*
+     * Should we run the client or server in a separate thread?
+     * Both sides can throw exceptions, but do you have a preference
+     * as to which side should be the main thread.
+     */
+    static boolean separateServerThread = false;
+
+    /*
+     * Where do we find the keystores?
+     */
+    static String pathToStores = "../etc";
+    static String keyStoreFile = "keystore";
+    static String trustStoreFile = "truststore";
+    static String passwd = "passphrase";
+
+    /*
+     * Is the server ready to serve?
+     */
+    volatile static boolean serverReady = false;
+
+    /*
+     * Turn on SSL debugging?
+     */
+    static boolean debug = false;
+
+    /*
+     * If the client or server is doing some kind of object creation
+     * that the other side depends on, and that thread prematurely
+     * exits, you may experience a hang.  The test harness will
+     * terminate all hung threads after its timeout has expired,
+     * currently 3 minutes by default, but you might try to be
+     * smart about it....
+     */
+
+    /*
+     * Define the server side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    void doServerSide() throws Exception {
+        SSLServerSocketFactory sslssf =
+            (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+        SSLServerSocket sslServerSocket =
+            (SSLServerSocket) sslssf.createServerSocket(serverPort);
+
+        serverPort = sslServerSocket.getLocalPort();
+
+        /*
+         * Signal Client, we're ready for his connect.
+         */
+        serverReady = true;
+
+        try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) {
+            InputStream sslIS = sslSocket.getInputStream();
+            OutputStream sslOS = sslSocket.getOutputStream();
+
+            sslIS.read();
+            sslOS.write(85);
+            sslOS.flush();
+
+            throw new Exception(
+                "Legacy DH keys (< 1024) should be restricted");
+        } catch (SSLHandshakeException she) {
+            // ignore, client should terminate the connection
+        } finally {
+            sslServerSocket.close();
+        }
+    }
+
+    /*
+     * Define the client side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    void doClientSide() throws Exception {
+
+        /*
+         * Wait for server to get started.
+         */
+        while (!serverReady) {
+            Thread.sleep(50);
+        }
+
+        SSLSocketFactory sslsf =
+            (SSLSocketFactory) SSLSocketFactory.getDefault();
+        SSLSocket sslSocket = (SSLSocket)
+            sslsf.createSocket("localhost", serverPort);
+
+        String[] suites = new String [] {"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"};
+        sslSocket.setEnabledCipherSuites(suites);
+
+        try {
+            InputStream sslIS = sslSocket.getInputStream();
+            OutputStream sslOS = sslSocket.getOutputStream();
+
+            sslOS.write(280);
+            sslOS.flush();
+            sslIS.read();
+
+            throw new Exception("Legacy DH keys (< 1024) should be restricted");
+        } catch (SSLHandshakeException she) {
+            // ignore, should be caused by algorithm constraints
+        } finally {
+            sslSocket.close();
+        }
+    }
+
+    /*
+     * =============================================================
+     * The remainder is just support stuff
+     */
+
+    // use any free port by default
+    volatile int serverPort = 0;
+
+    volatile Exception serverException = null;
+    volatile Exception clientException = null;
+
+    public static void main(String[] args) throws Exception {
+        String keyFilename =
+            System.getProperty("test.src", ".") + "/" + pathToStores +
+                "/" + keyStoreFile;
+        String trustFilename =
+            System.getProperty("test.src", ".") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+        System.setProperty("javax.net.ssl.keyStore", keyFilename);
+        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+        System.setProperty("javax.net.ssl.trustStore", trustFilename);
+        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+        if (debug) {
+            System.setProperty("javax.net.debug", "all");
+        }
+
+        /*
+         * Start the tests.
+         */
+        new LegacyDHEKeyExchange();
+    }
+
+    Thread clientThread = null;
+    Thread serverThread = null;
+
+    /*
+     * Primary constructor, used to drive remainder of the test.
+     *
+     * Fork off the other side, then do your work.
+     */
+    LegacyDHEKeyExchange() throws Exception {
+        Exception startException = null;
+        try {
+            if (separateServerThread) {
+                startServer(true);
+                startClient(false);
+            } else {
+                startClient(true);
+                startServer(false);
+            }
+        } catch (Exception e) {
+            startException = e;
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            if (serverThread != null) {
+                serverThread.join();
+            }
+        } else {
+            if (clientThread != null) {
+                clientThread.join();
+            }
+        }
+
+        /*
+         * When we get here, the test is pretty much over.
+         * Which side threw the error?
+         */
+        Exception local;
+        Exception remote;
+
+        if (separateServerThread) {
+            remote = serverException;
+            local = clientException;
+        } else {
+            remote = clientException;
+            local = serverException;
+        }
+
+        Exception exception = null;
+
+        /*
+         * Check various exception conditions.
+         */
+        if ((local != null) && (remote != null)) {
+            // If both failed, return the curthread's exception.
+            local.initCause(remote);
+            exception = local;
+        } else if (local != null) {
+            exception = local;
+        } else if (remote != null) {
+            exception = remote;
+        } else if (startException != null) {
+            exception = startException;
+        }
+
+        /*
+         * If there was an exception *AND* a startException,
+         * output it.
+         */
+        if (exception != null) {
+            if (exception != startException && startException != null) {
+                exception.addSuppressed(startException);
+            }
+            throw exception;
+        }
+
+        // Fall-through: no exception to throw!
+    }
+
+    void startServer(boolean newThread) throws Exception {
+        if (newThread) {
+            serverThread = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        doServerSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our server thread just died.
+                         *
+                         * Release the client, if not active already...
+                         */
+                        System.err.println("Server died...");
+                        serverReady = true;
+                        serverException = e;
+                    }
+                }
+            };
+            serverThread.start();
+        } else {
+            try {
+                doServerSide();
+            } catch (Exception e) {
+                serverException = e;
+            } finally {
+                serverReady = true;
+            }
+        }
+    }
+
+    void startClient(boolean newThread) throws Exception {
+        if (newThread) {
+            clientThread = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        doClientSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our client thread just died.
+                         */
+                        System.err.println("Client died...");
+                        clientException = e;
+                    }
+                }
+            };
+            clientThread.start();
+        } else {
+            try {
+                doClientSide();
+            } catch (Exception e) {
+                clientException = e;
+            }
+        }
+    }
+}