提交 9b651bb0 编写于 作者: A asaha

Merge

...@@ -685,4 +685,6 @@ a01d217a232906e82f80e5bc3db4d60c4c74716e jdk8u131-b02 ...@@ -685,4 +685,6 @@ a01d217a232906e82f80e5bc3db4d60c4c74716e jdk8u131-b02
0f7d02f565658a89b073ee77c296f33148c50da3 jdk8u131-b04 0f7d02f565658a89b073ee77c296f33148c50da3 jdk8u131-b04
af0e709d28f9124dd2c37069e0bf4c0751248c61 jdk8u131-b05 af0e709d28f9124dd2c37069e0bf4c0751248c61 jdk8u131-b05
3c7f99282d1b5e29f7466bf25fb6878bfebfc58a jdk8u131-b06 3c7f99282d1b5e29f7466bf25fb6878bfebfc58a jdk8u131-b06
f5d0aadb4d1ca74eda4e98cc0030f1618ef4c870 jdk8u131-b07
6e362e6002abc39c63fc8ab4bcebf08e273f5a94 jdk8u131-b08
a160009bbe1417d85f1c0eec890fdb17391b3637 jdk8u141-b00 a160009bbe1417d85f1c0eec890fdb17391b3637 jdk8u141-b00
...@@ -27,7 +27,6 @@ package com.sun.jndi.ldap.pool; ...@@ -27,7 +27,6 @@ package com.sun.jndi.ldap.pool;
import java.util.ArrayList; // JDK 1.2 import java.util.ArrayList; // JDK 1.2
import java.util.List; import java.util.List;
import java.util.Iterator;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
...@@ -290,23 +289,28 @@ final class Connections implements PoolCallback { ...@@ -290,23 +289,28 @@ final class Connections implements PoolCallback {
* @param threshold an entry idle since this time has expired. * @param threshold an entry idle since this time has expired.
* @return true if no more connections in list * @return true if no more connections in list
*/ */
synchronized boolean expire(long threshold) { boolean expire(long threshold) {
Iterator<ConnectionDesc> iter = conns.iterator(); List<ConnectionDesc> clonedConns;
ConnectionDesc entry; synchronized(this) {
while (iter.hasNext()) { clonedConns = new ArrayList<>(conns);
entry = iter.next(); }
if (entry.expire(threshold)) { List<ConnectionDesc> expired = new ArrayList<>();
d("expire(): removing ", entry);
td("Expired ", entry);
iter.remove(); // remove from pool
// Don't need to call notify() because we're for (ConnectionDesc entry : clonedConns) {
// removing only idle connections. If there were d("expire(): ", entry);
// idle connections, then there should be no waiters. if (entry.expire(threshold)) {
expired.add(entry);
td("expire(): Expired ", entry);
} }
} }
return conns.isEmpty(); // whether whole list has 'expired'
synchronized (this) {
conns.removeAll(expired);
// Don't need to call notify() because we're
// removing only idle connections. If there were
// idle connections, then there should be no waiters.
return conns.isEmpty(); // whether whole list has 'expired'
}
} }
/** /**
......
...@@ -25,11 +25,11 @@ ...@@ -25,11 +25,11 @@
package com.sun.jndi.ldap.pool; package com.sun.jndi.ldap.pool;
import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.io.PrintStream; import java.io.PrintStream;
...@@ -166,17 +166,25 @@ final public class Pool { ...@@ -166,17 +166,25 @@ final public class Pool {
* and removed. * and removed.
*/ */
public void expire(long threshold) { public void expire(long threshold) {
Collection<ConnectionsRef> copy;
synchronized (map) { synchronized (map) {
Iterator<ConnectionsRef> iter = map.values().iterator(); copy = new ArrayList<>(map.values());
Connections conns; }
while (iter.hasNext()) {
conns = iter.next().getConnections(); ArrayList<ConnectionsRef> removed = new ArrayList<>();
if (conns.expire(threshold)) { Connections conns;
d("expire(): removing ", conns); for (ConnectionsRef ref : copy) {
iter.remove(); conns = ref.getConnections();
} if (conns.expire(threshold)) {
d("expire(): removing ", conns);
removed.add(ref);
} }
} }
synchronized (map) {
map.values().removeAll(removed);
}
expungeStaleConnections(); expungeStaleConnections();
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1774,12 +1774,19 @@ public class ObjectInputStream ...@@ -1774,12 +1774,19 @@ public class ObjectInputStream
} catch (ClassNotFoundException ex) { } catch (ClassNotFoundException ex) {
resolveEx = ex; resolveEx = ex;
} }
skipCustomData();
desc.initProxy(cl, resolveEx, readClassDesc(false)); // Call filterCheck on the class before reading anything else
filterCheck(cl, -1);
skipCustomData();
// Call filterCheck on the definition try {
filterCheck(desc.forClass(), -1); totalObjectRefs++;
depth++;
desc.initProxy(cl, resolveEx, readClassDesc(false));
} finally {
depth--;
}
handles.finish(descHandle); handles.finish(descHandle);
passHandle = descHandle; passHandle = descHandle;
...@@ -1824,12 +1831,19 @@ public class ObjectInputStream ...@@ -1824,12 +1831,19 @@ public class ObjectInputStream
} catch (ClassNotFoundException ex) { } catch (ClassNotFoundException ex) {
resolveEx = ex; resolveEx = ex;
} }
skipCustomData();
desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false)); // Call filterCheck on the class before reading anything else
filterCheck(cl, -1);
skipCustomData();
// Call filterCheck on the definition try {
filterCheck(desc.forClass(), -1); totalObjectRefs++;
depth++;
desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
} finally {
depth--;
}
handles.finish(descHandle); handles.finish(descHandle);
passHandle = descHandle; passHandle = descHandle;
......
...@@ -342,11 +342,11 @@ class Thread implements Runnable { ...@@ -342,11 +342,11 @@ class Thread implements Runnable {
/** /**
* Initializes a Thread with the current AccessControlContext. * Initializes a Thread with the current AccessControlContext.
* @see #init(ThreadGroup,Runnable,String,long,AccessControlContext) * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext,boolean)
*/ */
private void init(ThreadGroup g, Runnable target, String name, private void init(ThreadGroup g, Runnable target, String name,
long stackSize) { long stackSize) {
init(g, target, name, stackSize, null); init(g, target, name, stackSize, null, true);
} }
/** /**
...@@ -359,9 +359,12 @@ class Thread implements Runnable { ...@@ -359,9 +359,12 @@ class Thread implements Runnable {
* zero to indicate that this parameter is to be ignored. * zero to indicate that this parameter is to be ignored.
* @param acc the AccessControlContext to inherit, or * @param acc the AccessControlContext to inherit, or
* AccessController.getContext() if null * AccessController.getContext() if null
* @param inheritThreadLocals if {@code true}, inherit initial values for
* inheritable thread-locals from the constructing thread
*/ */
private void init(ThreadGroup g, Runnable target, String name, private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc) { long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
if (name == null) { if (name == null) {
throw new NullPointerException("name cannot be null"); throw new NullPointerException("name cannot be null");
} }
...@@ -412,7 +415,7 @@ class Thread implements Runnable { ...@@ -412,7 +415,7 @@ class Thread implements Runnable {
acc != null ? acc : AccessController.getContext(); acc != null ? acc : AccessController.getContext();
this.target = target; this.target = target;
setPriority(priority); setPriority(priority);
if (parent.inheritableThreadLocals != null) if (inheritThreadLocals && parent.inheritableThreadLocals != null)
this.inheritableThreadLocals = this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */ /* Stash the specified stack size in case the VM cares */
...@@ -466,7 +469,7 @@ class Thread implements Runnable { ...@@ -466,7 +469,7 @@ class Thread implements Runnable {
* This is not a public constructor. * This is not a public constructor.
*/ */
Thread(Runnable target, AccessControlContext acc) { Thread(Runnable target, AccessControlContext acc) {
init(null, target, "Thread-" + nextThreadNum(), 0, acc); init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
} }
/** /**
......
/* /*
* Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -43,6 +43,9 @@ import sun.security.action.GetPropertyAction; ...@@ -43,6 +43,9 @@ import sun.security.action.GetPropertyAction;
final class SupportedEllipticCurvesExtension extends HelloExtension { 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_PRIME = 0xff01;
private static final int ARBITRARY_CHAR2 = 0xff02; private static final int ARBITRARY_CHAR2 = 0xff02;
...@@ -159,6 +162,11 @@ final class SupportedEllipticCurvesExtension extends HelloExtension { ...@@ -159,6 +162,11 @@ final class SupportedEllipticCurvesExtension extends HelloExtension {
} // ignore unknown curves } // 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 } else { // default curves
int[] ids; int[] ids;
if (requireFips) { if (requireFips) {
...@@ -183,18 +191,19 @@ final class SupportedEllipticCurvesExtension extends HelloExtension { ...@@ -183,18 +191,19 @@ final class SupportedEllipticCurvesExtension extends HelloExtension {
} }
} }
if (idList.isEmpty()) { if (debug != null && idList.isEmpty()) {
throw new IllegalArgumentException( debug.println(
"System property jdk.tls.namedGroups(" + property + ") " + "Initialized [jdk.tls.namedGroups|default] list contains " +
"contains no supported elliptic curves"); "no available elliptic curves. " +
} else { (property != null ? "(" + property + ")" : "[Default]"));
}
supportedCurveIds = new int[idList.size()]; supportedCurveIds = new int[idList.size()];
int i = 0; int i = 0;
for (Integer id : idList) { for (Integer id : idList) {
supportedCurveIds[i++] = id; supportedCurveIds[i++] = id;
} }
} }
}
// check whether the curve is supported by the underlying providers // check whether the curve is supported by the underlying providers
private static boolean isAvailableCurve(int curveId) { private static boolean isAvailableCurve(int curveId) {
......
/* /*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -33,10 +33,11 @@ import java.lang.invoke.SerializedLambda; ...@@ -33,10 +33,11 @@ import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Set; import java.util.List;
import java.util.concurrent.atomic.LongAdder; import java.util.concurrent.atomic.LongAdder;
import sun.misc.ObjectInputFilter; import sun.misc.ObjectInputFilter;
...@@ -155,26 +156,33 @@ public class SerialFilterTest implements Serializable { ...@@ -155,26 +156,33 @@ public class SerialFilterTest implements Serializable {
Runnable runnable = (Runnable & Serializable) SerialFilterTest::noop; Runnable runnable = (Runnable & Serializable) SerialFilterTest::noop;
Object[][] objects = { Object[][] objects = {
{ null, 0, -1, 0, 0, 0, { null, 0, -1, 0, 0, 0,
new HashSet<>()}, // no callback, no values Arrays.asList()}, // no callback, no values
{ objArray, 3, 7, 8, 2, 55, { objArray, 3, 7, 9, 2, 55,
new HashSet<>(Arrays.asList(objArray.getClass()))}, Arrays.asList(objArray.getClass(), objArray.getClass())},
{ Object[].class, 1, -1, 1, 1, 40, { Object[].class, 1, -1, 1, 1, 38,
new HashSet<>(Arrays.asList(Object[].class))}, Arrays.asList(Object[].class)},
{ new SerialFilterTest(), 1, -1, 1, 1, 37, { new SerialFilterTest(), 1, -1, 1, 1, 35,
new HashSet<>(Arrays.asList(SerialFilterTest.class))}, Arrays.asList(SerialFilterTest.class)},
{ new LongAdder(), 2, -1, 1, 1, 93, { new LongAdder(), 2, -1, 2, 1, 93,
new HashSet<>(Arrays.asList(LongAdder.class, serClass))}, Arrays.asList(serClass, LongAdder.class)},
{ new byte[14], 2, 14, 1, 1, 27, { new byte[14], 2, 14, 2, 1, 27,
new HashSet<>(Arrays.asList(byteArray.getClass()))}, Arrays.asList(byteArray.getClass(), byteArray.getClass())},
{ runnable, 13, 0, 10, 2, 514, { runnable, 13, 0, 13, 2, 514,
new HashSet<>(Arrays.asList(java.lang.invoke.SerializedLambda.class, Arrays.asList(java.lang.invoke.SerializedLambda.class,
objArray.getClass(),
objArray.getClass(),
SerialFilterTest.class, SerialFilterTest.class,
objArray.getClass()))}, java.lang.invoke.SerializedLambda.class)},
{ deepHashSet(10), 48, -1, 49, 11, 619, { deepHashSet(10), 48, -1, 50, 11, 619,
new HashSet<>(Arrays.asList(HashSet.class))}, Arrays.asList(HashSet.class)},
{ proxy.getClass(), 3, -1, 1, 1, 114, { proxy.getClass(), 3, -1, 2, 2, 112,
new HashSet<>(Arrays.asList(Runnable.class, Arrays.asList(Runnable.class,
java.lang.reflect.Proxy.class))}, java.lang.reflect.Proxy.class,
java.lang.reflect.Proxy.class)},
{ new F(), 6, -1, 6, 6, 202,
Arrays.asList(F.class, E.class, D.class,
C.class, B.class, A.class)},
}; };
return objects; return objects;
} }
...@@ -213,11 +221,12 @@ public class SerialFilterTest implements Serializable { ...@@ -213,11 +221,12 @@ public class SerialFilterTest implements Serializable {
@Test(dataProvider="Objects") @Test(dataProvider="Objects")
public static void t1(Object object, public static void t1(Object object,
long count, long maxArray, long maxRefs, long maxDepth, long maxBytes, long count, long maxArray, long maxRefs, long maxDepth, long maxBytes,
Set<Class<?>> classes) throws IOException { List<Class<?>> classes) throws IOException {
byte[] bytes = writeObjects(object); byte[] bytes = writeObjects(object);
Validator validator = new Validator(); Validator validator = new Validator();
validate(bytes, validator); validate(bytes, validator);
System.out.printf("v: %s%n", validator); System.out.printf("v: %s%n", validator);
Assert.assertEquals(validator.count, count, "callback count wrong"); Assert.assertEquals(validator.count, count, "callback count wrong");
Assert.assertEquals(validator.classes, classes, "classes mismatch"); Assert.assertEquals(validator.classes, classes, "classes mismatch");
Assert.assertEquals(validator.maxArray, maxArray, "maxArray mismatch"); Assert.assertEquals(validator.maxArray, maxArray, "maxArray mismatch");
...@@ -411,7 +420,7 @@ public class SerialFilterTest implements Serializable { ...@@ -411,7 +420,7 @@ public class SerialFilterTest implements Serializable {
*/ */
static class Validator implements ObjectInputFilter { static class Validator implements ObjectInputFilter {
long count; // Count of calls to checkInput long count; // Count of calls to checkInput
HashSet<Class<?>> classes = new HashSet<>(); List<Class<?>> classes = new ArrayList<>();
long maxArray = -1; long maxArray = -1;
long maxRefs; long maxRefs;
long maxDepth; long maxDepth;
...@@ -422,16 +431,20 @@ public class SerialFilterTest implements Serializable { ...@@ -422,16 +431,20 @@ public class SerialFilterTest implements Serializable {
@Override @Override
public ObjectInputFilter.Status checkInput(FilterInfo filter) { public ObjectInputFilter.Status checkInput(FilterInfo filter) {
Class<?> serialClass = filter.serialClass();
System.out.printf(" checkInput: class: %s, arrayLen: %d, refs: %d, depth: %d, bytes; %d%n",
serialClass, filter.arrayLength(), filter.references(),
filter.depth(), filter.streamBytes());
count++; count++;
if (filter.serialClass() != null) { if (serialClass != null) {
if (filter.serialClass().getName().contains("$$Lambda$")) { if (serialClass.getName().contains("$$Lambda$")) {
// TBD: proper identification of serialized Lambdas? // TBD: proper identification of serialized Lambdas?
// Fold the serialized Lambda into the SerializedLambda type // Fold the serialized Lambda into the SerializedLambda type
classes.add(SerializedLambda.class); classes.add(SerializedLambda.class);
} else if (Proxy.isProxyClass(filter.serialClass())) { } else if (Proxy.isProxyClass(serialClass)) {
classes.add(Proxy.class); classes.add(Proxy.class);
} else { } else {
classes.add(filter.serialClass()); classes.add(serialClass);
} }
} }
...@@ -591,7 +604,8 @@ public class SerialFilterTest implements Serializable { ...@@ -591,7 +604,8 @@ public class SerialFilterTest implements Serializable {
// a stream of exactly the size requested. // a stream of exactly the size requested.
return genMaxBytesObject(allowed, value); return genMaxBytesObject(allowed, value);
} else if (pattern.startsWith("maxrefs=")) { } else if (pattern.startsWith("maxrefs=")) {
Object[] array = new Object[allowed ? (int)value - 1 : (int)value]; // 4 references to classes in addition to the array contents
Object[] array = new Object[allowed ? (int)value - 4 : (int)value - 3];
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
array[i] = otherObject; array[i] = otherObject;
} }
...@@ -740,4 +754,25 @@ public class SerialFilterTest implements Serializable { ...@@ -740,4 +754,25 @@ public class SerialFilterTest implements Serializable {
return streamBytes; return streamBytes;
} }
} }
// Deeper superclass hierarchy
static class A implements Serializable {
private static final long serialVersionUID = 1L;
};
static class B extends A {
private static final long serialVersionUID = 2L;
}
static class C extends B {
private static final long serialVersionUID = 3L;
}
static class D extends C {
private static final long serialVersionUID = 4L;
}
static class E extends D {
private static final long serialVersionUID = 5L;
}
static class F extends E {
private static final long serialVersionUID = 6L;
}
} }
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Basic test for Thread(ThreadGroup,Runnable,String,long,boolean)
*/
import sun.misc.SharedSecrets;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
public class ITLConstructor {
static InheritableThreadLocal<Integer> n = new InheritableThreadLocal<Integer>() {
protected Integer initialValue() {
return 0;
}
protected Integer childValue(Integer parentValue) {
return parentValue + 1;
}
};
static final int CHILD_THREAD_COUNT = 10;
public static void main(String args[]) throws Exception {
test();
}
static void test() throws Exception {
// concurrent access to separate indexes is ok
int[] x = new int[CHILD_THREAD_COUNT];
Thread child = createThread(new AnotherRunnable(0, x));
child.start();
child.join(); // waits for *all* threads to complete
// Check results
for(int i=0; i<CHILD_THREAD_COUNT; i++) {
int expectedValue = 1;
if (x[i] != expectedValue)
throw (new Exception("Got x[" + i + "] = " + x[i]
+ ", expected: " + expectedValue));
}
}
static class AnotherRunnable implements Runnable {
final int threadId;
final int[] x;
AnotherRunnable(int threadId, int[] x) {
this.threadId = threadId;
this.x = x;
}
public void run() {
int itlValue = n.get();
if (threadId < CHILD_THREAD_COUNT-1) {
Thread child = createThread(
new AnotherRunnable(threadId+1, x));
child.start();
try {
child.join();
} catch(InterruptedException e) {
throw(new RuntimeException("Interrupted", e));
}
}
x[threadId] = itlValue+1;
}
}
static Thread createThread(final Runnable r) {
final AccessControlContext acc = AccessController.getContext();
// 4290486: doPrivileged is needed to create a thread in
// an environment that restricts "modifyThreadGroup".
return AccessController.doPrivileged(
new PrivilegedAction<Thread>() {
public Thread run() {
return SharedSecrets.getJavaLangAccess()
.newThreadWithAcc(r, acc);
}
}
);
}
}
/*
* 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 8173783
* @summary 6u141 IllegalArgumentException: jdk.tls.namedGroups
* run main/othervm HelloExtensionsTest
* run main/othervm HelloExtensionsTest -Djdk.tls.namedGroups="bug, bug"
* run main/othervm HelloExtensionsTest -Djdk.tls.namedGroups="secp521r1"
*
*/
import javax.crypto.*;
import javax.net.ssl.*;
import javax.net.ssl.SSLEngineResult.*;
import java.io.*;
import java.nio.*;
import java.security.*;
public class HelloExtensionsTest {
private static boolean debug = false;
private static boolean proceed = true;
private static boolean EcAvailable = isEcAvailable();
static String pathToStores = "../etc";
private static String keyStoreFile = "keystore";
private static String trustStoreFile = "truststore";
private static String passwd = "passphrase";
private static String keyFilename =
System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + keyStoreFile;
private static String trustFilename =
System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + trustStoreFile;
private static void checkDone(SSLEngine ssle) throws Exception {
if (!ssle.isInboundDone()) {
throw new Exception("isInboundDone isn't done");
}
if (!ssle.isOutboundDone()) {
throw new Exception("isOutboundDone isn't done");
}
}
private static void runTest(SSLEngine ssle) throws Exception {
/*
A client hello message captured via wireshark by selecting
a TLSv1.2 Client Hello record and clicking through to the
TLSv1.2 Record Layer line and then selecting the hex stream
via "copy -> bytes -> hex stream".
For Record purposes, here's the ClientHello :
*** ClientHello, TLSv1.2
RandomCookie: GMT: 1469560450 bytes = { 108, 140, 12, 202,
2, 213, 10, 236, 143, 223, 58, 162, 228, 155, 239, 3, 98,
232, 89, 41, 116, 120, 13, 37, 105, 153, 97, 241 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1,
sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1,
sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1,
sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1,
secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms:
SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA,
SHA256withECDSA, SHA256withRSA, Unknown (hash:0x3, signature:0x3),
Unknown (hash:0x3, signature:0x1), SHA1withECDSA,
SHA1withRSA, SHA1withDSA
Extension server_name, server_name:
[host_name: bugs.openjdk.java.net]
*/
String hello = "16030300df010000db03035898b7826c8c0cc" +
"a02d50aec8fdf3aa2e49bef0362e8592974780d25699961f" +
"100003ac023c027003cc025c02900670040c009c013002fc" +
"004c00e00330032c02bc02f009cc02dc031009e00a2c008c" +
"012000ac003c00d0016001300ff01000078000a003400320" +
"0170001000300130015000600070009000a0018000b000c0" +
"019000d000e000f001000110002001200040005001400080" +
"016000b00020100000d00180016060306010503050104030" +
"401030303010203020102020000001a00180000156275677" +
"32e6f70656e6a646b2e6a6176612e6e6574";
byte[] msg_clihello = hexStringToByteArray(hello);
ByteBuffer bf_clihello = ByteBuffer.wrap(msg_clihello);
SSLSession session = ssle.getSession();
int appBufferMax = session.getApplicationBufferSize();
int netBufferMax = session.getPacketBufferSize();
ByteBuffer serverIn = ByteBuffer.allocate(appBufferMax + 50);
ByteBuffer serverOut = ByteBuffer.wrap("I'm Server".getBytes());
ByteBuffer sTOc = ByteBuffer.allocate(netBufferMax);
ssle.beginHandshake();
// unwrap the clientHello message.
SSLEngineResult result = ssle.unwrap(bf_clihello, serverIn);
System.out.println("server unwrap " + result);
runDelegatedTasks(result, ssle);
if (!proceed) {
//expected exception occurred. Don't process anymore
return;
}
// one more step, ensure the clientHello message is parsed.
SSLEngineResult.HandshakeStatus status = ssle.getHandshakeStatus();
if ( status == HandshakeStatus.NEED_UNWRAP) {
result = ssle.unwrap(bf_clihello, serverIn);
System.out.println("server unwrap " + result);
runDelegatedTasks(result, ssle);
} else if ( status == HandshakeStatus.NEED_WRAP) {
result = ssle.wrap(serverOut, sTOc);
System.out.println("server wrap " + result);
runDelegatedTasks(result, ssle);
} else {
throw new Exception("unexpected handshake status " + status);
}
// enough, stop
}
/*
* If the result indicates that we have outstanding tasks to do,
* go ahead and run them in this thread.
*/
private static void runDelegatedTasks(SSLEngineResult result,
SSLEngine engine) throws Exception {
if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
Runnable runnable;
try {
while ((runnable = engine.getDelegatedTask()) != null) {
log("\trunning delegated task...");
runnable.run();
}
} catch (ExceptionInInitializerError e) {
String v = System.getProperty("jdk.tls.namedGroups");
if (!EcAvailable || v == null) {
// we weren't expecting this if no EC providers
throw new RuntimeException("Unexpected Error :" + e);
}
if (v != null && v.contains("bug")) {
// OK - we were expecting this Error
log("got expected error for bad jdk.tls.namedGroups");
proceed = false;
return;
} else {
System.out.println("Unexpected error. " +
"jdk.tls.namedGroups value: " + v);
throw e;
}
}
HandshakeStatus hsStatus = engine.getHandshakeStatus();
if (hsStatus == HandshakeStatus.NEED_TASK) {
throw new Exception(
"handshake shouldn't need additional tasks");
}
log("\tnew HandshakeStatus: " + hsStatus);
}
}
private static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
private static boolean isEcAvailable() {
try {
Signature.getInstance("SHA1withECDSA");
Signature.getInstance("NONEwithECDSA");
KeyAgreement.getInstance("ECDH");
KeyFactory.getInstance("EC");
KeyPairGenerator.getInstance("EC");
AlgorithmParameters.getInstance("EC");
} catch (Exception e) {
log("EC not available. Received: " + e);
return false;
}
return true;
}
public static void main(String args[]) throws Exception {
SSLEngine ssle = createSSLEngine(keyFilename, trustFilename);
runTest(ssle);
System.out.println("Test Passed.");
}
/*
* Create an initialized SSLContext to use for this test.
*/
static private SSLEngine createSSLEngine(String keyFile, String trustFile)
throws Exception {
SSLEngine ssle;
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore ts = KeyStore.getInstance("JKS");
char[] passphrase = "passphrase".toCharArray();
ks.load(new FileInputStream(keyFile), passphrase);
ts.load(new FileInputStream(trustFile), passphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, passphrase);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
ssle = sslCtx.createSSLEngine();
ssle.setUseClientMode(false);
return ssle;
}
private static void log(String str) {
if (debug) {
System.out.println(str);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册