--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java Mon Aug 15 08:15:02 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -53,10 +53,37 @@
private final int blockLen;
/**
- * Standard constructor, creates a new HmacCore instance using the
- * specified MessageDigest object.
+ * Standard constructor, creates a new HmacCore instance instantiating
+ * a MessageDigest of the specified name.
*/
- HmacCore(MessageDigest md, int bl) {
+ HmacCore(String digestAlgo, int bl) throws NoSuchAlgorithmException {
+ MessageDigest md = MessageDigest.getInstance(digestAlgo);
+ if (!(md instanceof Cloneable)) {
+ // use SUN provider if the most preferred one does not support
+ // cloning
+ Provider sun = Security.getProvider("SUN");
+ if (sun != null) {
+ md = MessageDigest.getInstance(digestAlgo, sun);
+ } else {
+ String noCloneProv = md.getProvider().getName();
+ // if no Sun provider, use provider list
+ Provider[] provs = Security.getProviders();
+ for (Provider p : provs) {
+ try {
+ if (!p.getName().equals(noCloneProv)) {
+ MessageDigest md2 =
+ MessageDigest.getInstance(digestAlgo, p);
+ if (md2 instanceof Cloneable) {
+ md = md2;
+ break;
+ }
+ }
+ } catch (NoSuchAlgorithmException nsae) {
+ continue;
+ }
+ }
+ }
+ }
this.md = md;
this.blockLen = bl;
this.k_ipad = new byte[blockLen];
@@ -65,14 +92,6 @@
}
/**
- * Standard constructor, creates a new HmacCore instance instantiating
- * a MessageDigest of the specified name.
- */
- HmacCore(String digestAlgorithm, int bl) throws NoSuchAlgorithmException {
- this(MessageDigest.getInstance(digestAlgorithm), bl);
- }
-
- /**
* Returns the length of the HMAC in bytes.
*
* @return the HMAC length in bytes.
--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Mon Aug 15 08:15:02 2016 -0700
@@ -846,7 +846,7 @@
}
}
- private static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
+ static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
/**
* All subclasses must provide such a value describing their type signature.
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Mon Aug 15 08:15:02 2016 -0700
@@ -259,7 +259,7 @@
}
private static void maybeCompile(LambdaForm lform, MemberName m) {
- if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
+ if (lform.vmentry == null && VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
// Help along bootstrapping...
lform.compileToBytecode();
}
@@ -562,25 +562,36 @@
return lform;
}
+ private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
+
private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
boolean isStatic = (formOp >= AF_GETSTATIC);
boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
boolean needsCast = (ftypeKind == FT_CHECKED_REF);
- Wrapper fw = (needsCast ? Wrapper.OBJECT : Wrapper.values()[ftypeKind]);
+ Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
Class<?> ft = fw.primitiveType();
assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
- String tname = fw.primitiveSimpleName();
- String ctname = Character.toUpperCase(tname.charAt(0)) + tname.substring(1);
- if (isVolatile) ctname += "Volatile";
- String getOrPut = (isGetter ? "get" : "put");
- String linkerName = (getOrPut + ctname); // getObject, putIntVolatile, etc.
+
+ // getObject, putIntVolatile, etc.
+ StringBuilder nameBuilder = new StringBuilder();
+ if (isGetter) {
+ nameBuilder.append("get");
+ } else {
+ nameBuilder.append("put");
+ }
+ nameBuilder.append(fw.primitiveSimpleName());
+ nameBuilder.setCharAt(3, Character.toUpperCase(nameBuilder.charAt(3)));
+ if (isVolatile) {
+ nameBuilder.append("Volatile");
+ }
+
MethodType linkerType;
if (isGetter)
linkerType = MethodType.methodType(ft, Object.class, long.class);
else
linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
- MemberName linker = new MemberName(Unsafe.class, linkerName, linkerType, REF_invokeVirtual);
+ MemberName linker = new MemberName(Unsafe.class, nameBuilder.toString(), linkerType, REF_invokeVirtual);
try {
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
} catch (ReflectiveOperationException ex) {
@@ -635,11 +646,16 @@
if (needsCast && isGetter)
names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
for (Name n : names) assert(n != null);
- String fieldOrStatic = (isStatic ? "Static" : "Field");
- String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging
- if (needsCast) lambdaName += "Cast";
- if (needsInit) lambdaName += "Init";
- return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
+ // add some detail to the lambdaForm debugname,
+ // significant only for debugging
+ if (isStatic) {
+ nameBuilder.append("Static");
+ } else {
+ nameBuilder.append("Field");
+ }
+ if (needsCast) nameBuilder.append("Cast");
+ if (needsInit) nameBuilder.append("Init");
+ return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT);
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Mon Aug 15 08:15:02 2016 -0700
@@ -40,8 +40,8 @@
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Arrays;
+import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Map;
import java.util.stream.Stream;
import static java.lang.invoke.LambdaForm.*;
@@ -68,6 +68,7 @@
private static final String LFN_SIG = "L" + LFN + ";";
private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";";
private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V";
+ private static final String CLASS_PREFIX = LF + "$";
/** Name of its super class*/
static final String INVOKER_SUPER_NAME = OBJ;
@@ -96,15 +97,15 @@
/** Main constructor; other constructors delegate to this one. */
private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
String className, String invokerName, MethodType invokerType) {
- if (invokerName.contains(".")) {
- int p = invokerName.indexOf('.');
+ int p = invokerName.indexOf('.');
+ if (p > -1) {
className = invokerName.substring(0, p);
- invokerName = invokerName.substring(p+1);
+ invokerName = invokerName.substring(p + 1);
}
if (DUMP_CLASS_FILES) {
className = makeDumpableClassName(className);
}
- this.className = LF + "$" + className;
+ this.className = CLASS_PREFIX + className;
this.sourceFile = "LambdaForm$" + className;
this.lambdaForm = lambdaForm;
this.invokerName = invokerName;
@@ -201,38 +202,34 @@
class CpPatch {
final int index;
- final String placeholder;
final Object value;
- CpPatch(int index, String placeholder, Object value) {
+ CpPatch(int index, Object value) {
this.index = index;
- this.placeholder = placeholder;
this.value = value;
}
public String toString() {
- return "CpPatch/index="+index+",placeholder="+placeholder+",value="+value;
+ return "CpPatch/index="+index+",value="+value;
}
}
- Map<Object, CpPatch> cpPatches = new HashMap<>();
+ private final ArrayList<CpPatch> cpPatches = new ArrayList<>();
- int cph = 0; // for counting constant placeholders
+ private int cph = 0; // for counting constant placeholders
String constantPlaceholder(Object arg) {
String cpPlaceholder = "CONSTANT_PLACEHOLDER_" + cph++;
- if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>"; // debugging aid
- if (cpPatches.containsKey(cpPlaceholder)) {
- throw new InternalError("observed CP placeholder twice: " + cpPlaceholder);
- }
+ if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>";
+ // TODO check if arg is already in the constant pool
// insert placeholder in CP and remember the patch
- int index = cw.newConst((Object) cpPlaceholder); // TODO check if already in the constant pool
- cpPatches.put(cpPlaceholder, new CpPatch(index, cpPlaceholder, arg));
+ int index = cw.newConst((Object) cpPlaceholder);
+ cpPatches.add(new CpPatch(index, arg));
return cpPlaceholder;
}
Object[] cpPatches(byte[] classFile) {
int size = getConstantPoolSize(classFile);
Object[] res = new Object[size];
- for (CpPatch p : cpPatches.values()) {
+ for (CpPatch p : cpPatches) {
if (p.index >= size)
throw new InternalError("in cpool["+size+"]: "+p+"\n"+Arrays.toString(Arrays.copyOf(classFile, 20)));
res[p.index] = p.value;
@@ -741,7 +738,7 @@
continue;
case IDENTITY:
assert(name.arguments.length == 1);
- emitPushArguments(name);
+ emitPushArguments(name, 0);
continue;
case ZERO:
assert(name.arguments.length == 0);
@@ -795,7 +792,7 @@
assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE || arrayOpcode == Opcodes.ARRAYLENGTH;
Class<?> elementType = name.function.methodType().parameterType(0).getComponentType();
assert elementType != null;
- emitPushArguments(name);
+ emitPushArguments(name, 0);
if (arrayOpcode != Opcodes.ARRAYLENGTH && elementType.isPrimitive()) {
Wrapper w = Wrapper.forPrimitiveType(elementType);
arrayOpcode = arrayInsnOpcode(arrayTypeCode(w), arrayOpcode);
@@ -824,7 +821,7 @@
}
// push arguments
- emitPushArguments(name);
+ emitPushArguments(name, 0);
// invocation
MethodType type = name.function.methodType();
@@ -923,7 +920,7 @@
assert(!(member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual));
// push arguments
- emitPushArguments(name);
+ emitPushArguments(name, 0);
// invocation
if (member.isMethod()) {
@@ -1444,13 +1441,10 @@
}
}
- private void emitPushArguments(Name args) {
- emitPushArguments(args, 0);
- }
-
private void emitPushArguments(Name args, int start) {
+ MethodType type = args.function.methodType();
for (int i = start; i < args.arguments.length; i++) {
- emitPushArgument(args, i);
+ emitPushArgument(type.parameterType(i), args.arguments[i]);
}
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java Mon Aug 15 08:15:02 2016 -0700
@@ -149,9 +149,9 @@
static final int ARG_TYPE_LIMIT = ARG_TYPES.length;
static final int TYPE_LIMIT = ALL_TYPES.length;
- private final char btChar;
- private final Class<?> btClass;
- private final Wrapper btWrapper;
+ final char btChar;
+ final Class<?> btClass;
+ final Wrapper btWrapper;
private BasicType(char btChar, Class<?> btClass, Wrapper wrapper) {
this.btChar = btChar;
@@ -1366,10 +1366,11 @@
}
public static String basicTypeSignature(MethodType type) {
- char[] sig = new char[type.parameterCount() + 2];
+ int params = type.parameterCount();
+ char[] sig = new char[params + 2];
int sigp = 0;
- for (Class<?> pt : type.parameterList()) {
- sig[sigp++] = basicTypeChar(pt);
+ while (sigp < params) {
+ sig[sigp] = basicTypeChar(type.parameterType(sigp++));
}
sig[sigp++] = '_';
sig[sigp++] = basicTypeChar(type.returnType());
@@ -1407,7 +1408,7 @@
static final class Name {
final BasicType type;
- private short index;
+ @Stable short index;
final NamedFunction function;
final Object constraint; // additional type information, if not null
@Stable final Object[] arguments;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Mon Aug 15 08:15:02 2016 -0700
@@ -78,7 +78,7 @@
private int flags; // modifier bits; see reflect.Modifier
//@Injected JVM_Method* vmtarget;
//@Injected int vmindex;
- private Object resolution; // if null, this guy is resolved
+ Object resolution; // if null, this guy is resolved
/** Return the declaring class of this member.
* In the case of a bare name and type, the declaring class will be null.
@@ -826,7 +826,7 @@
return resolution == null;
}
- private void initResolved(boolean isResolved) {
+ void initResolved(boolean isResolved) {
assert(this.resolution == null); // not initialized yet!
if (!isResolved)
this.resolution = this;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Mon Aug 15 08:15:02 2016 -0700
@@ -40,8 +40,6 @@
import sun.invoke.util.Wrapper;
import java.lang.reflect.Array;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
@@ -60,19 +58,6 @@
* @author jrose
*/
/*non-public*/ abstract class MethodHandleImpl {
- // Do not adjust this except for special platforms:
- private static final int MAX_ARITY;
- static {
- final Object[] values = { 255 };
- AccessController.doPrivileged(new PrivilegedAction<>() {
- @Override
- public Void run() {
- values[0] = Integer.getInteger(MethodHandleImpl.class.getName()+".MAX_ARITY", 255);
- return null;
- }
- });
- MAX_ARITY = (Integer) values[0];
- }
/// Factory methods to create method handles:
@@ -652,7 +637,7 @@
MethodType srcType = targetType // (a..., [b...])=>r
.dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
if (!retainOriginalArgs) { // (a..., b...)=>r
- srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterList());
+ srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterArray());
}
// in arglist: [0: ...keep1 | cpos: collect... | cpos+cacount: keep2... ]
// out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ]
@@ -1097,7 +1082,7 @@
int arity = type.parameterCount();
if (arity > 1) {
MethodHandle mh = throwException(type.dropParameterTypes(1, arity));
- mh = MethodHandles.dropArguments(mh, 1, type.parameterList().subList(1, arity));
+ mh = MethodHandles.dropArguments(mh, 1, Arrays.copyOfRange(type.parameterArray(), 1, arity));
return mh;
}
return makePairwiseConvert(NF_throwException.resolvedHandle(), type, false, true);
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Mon Aug 15 08:15:02 2016 -0700
@@ -53,6 +53,7 @@
static final boolean PROFILE_GWT;
static final int CUSTOMIZE_THRESHOLD;
static final boolean VAR_HANDLE_GUARDS;
+ static final int MAX_ARITY;
static {
Properties props = GetPropertyAction.privilegedGetProperties();
@@ -79,6 +80,10 @@
VAR_HANDLE_GUARDS = Boolean.parseBoolean(
props.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true"));
+ // Do not adjust this except for special platforms:
+ MAX_ARITY = Integer.parseInt(
+ props.getProperty("java.lang.invoke.MethodHandleImpl.MAX_ARITY", "255"));
+
if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Mon Aug 15 08:15:02 2016 -0700
@@ -77,7 +77,7 @@
private MethodHandles() { } // do not instantiate
- private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
+ static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
// See IMPL_LOOKUP below.
@@ -3268,12 +3268,11 @@
*/
public static
MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
- return dropArguments0(target, pos, copyTypes(valueTypes));
+ return dropArguments0(target, pos, copyTypes(valueTypes.toArray()));
}
- private static List<Class<?>> copyTypes(List<Class<?>> types) {
- Object[] a = types.toArray();
- return Arrays.asList(Arrays.copyOf(a, a.length, Class[].class));
+ private static List<Class<?>> copyTypes(Object[] array) {
+ return Arrays.asList(Arrays.copyOf(array, array.length, Class[].class));
}
private static
@@ -3352,13 +3351,13 @@
*/
public static
MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
- return dropArguments(target, pos, Arrays.asList(valueTypes));
+ return dropArguments0(target, pos, copyTypes(valueTypes));
}
// private version which allows caller some freedom with error handling
private static MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos,
boolean nullOnFailure) {
- newTypes = copyTypes(newTypes);
+ newTypes = copyTypes(newTypes.toArray());
List<Class<?>> oldTypes = target.type().parameterList();
int match = oldTypes.size();
if (skip != 0) {
@@ -3900,10 +3899,14 @@
int foldVals = rtype == void.class ? 0 : 1;
int afterInsertPos = foldPos + foldVals;
boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
- if (ok && !(combinerType.parameterList()
- .equals(targetType.parameterList().subList(afterInsertPos,
- afterInsertPos + foldArgs))))
- ok = false;
+ if (ok) {
+ for (int i = 0; i < foldArgs; i++) {
+ if (combinerType.parameterType(i) != targetType.parameterType(i + afterInsertPos)) {
+ ok = false;
+ break;
+ }
+ }
+ }
if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos))
ok = false;
if (!ok)
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Mon Aug 15 08:15:02 2016 -0700
@@ -539,10 +539,10 @@
return res;
} else {
// insert after (if need be), then before
- if (pos < parameterList().size() - 1) {
- res = res.insertParameterTypes(arrayLength, parameterList().subList(pos + 1, parameterList().size()));
+ if (pos < ptypes.length - 1) {
+ res = res.insertParameterTypes(arrayLength, Arrays.copyOfRange(ptypes, pos + 1, ptypes.length));
}
- return res.insertParameterTypes(0, parameterList().subList(0, pos));
+ return res.insertParameterTypes(0, Arrays.copyOf(ptypes, pos));
}
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Mon Aug 15 08:15:02 2016 -0700
@@ -285,7 +285,7 @@
el.add(new RecipeElement(argC++));
}
} else {
- // Not a special characters, this is a constant embedded into
+ // Not a special character, this is a constant embedded into
// the recipe itself.
acc.append(c);
}
@@ -321,30 +321,32 @@
private static final class RecipeElement {
private final Object value;
private final int argPos;
+ private final char tag;
public RecipeElement(Object cnst) {
this.value = Objects.requireNonNull(cnst);
this.argPos = -1;
+ this.tag = TAG_CONST;
}
public RecipeElement(int arg) {
this.value = null;
- assert (arg >= 0);
this.argPos = arg;
+ this.tag = TAG_ARG;
}
public Object getValue() {
- assert (isConst());
+ assert (tag == TAG_CONST);
return value;
}
public int getArgPos() {
- assert (!isConst());
+ assert (tag == TAG_ARG);
return argPos;
}
- public boolean isConst() {
- return argPos == -1;
+ public char getTag() {
+ return tag;
}
@Override
@@ -354,16 +356,15 @@
RecipeElement that = (RecipeElement) o;
- boolean isConst = isConst();
- if (isConst != that.isConst()) return false;
- if (isConst && (!value.equals(that.value))) return false;
- if (!isConst && (argPos != that.argPos)) return false;
+ if (this.tag != that.tag) return false;
+ if (this.tag == TAG_CONST && (!value.equals(that.value))) return false;
+ if (this.tag == TAG_ARG && (argPos != that.argPos)) return false;
return true;
}
@Override
public int hashCode() {
- return argPos;
+ return (int)tag;
}
}
@@ -643,19 +644,20 @@
* @return argument types the strategy is going to use
*/
private static MethodType adaptType(MethodType args) {
- Class<?>[] ptypes = args.parameterArray();
- boolean changed = false;
- for (int i = 0; i < ptypes.length; i++) {
- Class<?> ptype = ptypes[i];
+ Class<?>[] ptypes = null;
+ for (int i = 0; i < args.parameterCount(); i++) {
+ Class<?> ptype = args.parameterType(i);
if (!ptype.isPrimitive() &&
ptype != String.class &&
ptype != Object.class) { // truncate to Object
+ if (ptypes == null) {
+ ptypes = args.parameterArray();
+ }
ptypes[i] = Object.class;
- changed = true;
}
// else other primitives or String or Object (unchanged)
}
- return changed
+ return (ptypes != null)
? MethodType.methodType(args.returnType(), ptypes)
: args;
}
@@ -874,24 +876,29 @@
int off = 0;
for (RecipeElement el : recipe.getElements()) {
- if (el.isConst()) {
- // Guaranteed non-null, no null check required.
- } else {
- // Null-checks are needed only for String arguments, and when a previous stage
- // did not do implicit null-checks. If a String is null, we eagerly replace it
- // with "null" constant. Note, we omit Objects here, because we don't call
- // .length() on them down below.
- int ac = el.getArgPos();
- Class<?> cl = arr[ac];
- if (cl == String.class && !guaranteedNonNull[ac]) {
- Label l0 = new Label();
- mv.visitIntInsn(ALOAD, off);
- mv.visitJumpInsn(IFNONNULL, l0);
- mv.visitLdcInsn("null");
- mv.visitIntInsn(ASTORE, off);
- mv.visitLabel(l0);
- }
- off += getParameterSize(cl);
+ switch (el.getTag()) {
+ case TAG_CONST:
+ // Guaranteed non-null, no null check required.
+ break;
+ case TAG_ARG:
+ // Null-checks are needed only for String arguments, and when a previous stage
+ // did not do implicit null-checks. If a String is null, we eagerly replace it
+ // with "null" constant. Note, we omit Objects here, because we don't call
+ // .length() on them down below.
+ int ac = el.getArgPos();
+ Class<?> cl = arr[ac];
+ if (cl == String.class && !guaranteedNonNull[ac]) {
+ Label l0 = new Label();
+ mv.visitIntInsn(ALOAD, off);
+ mv.visitJumpInsn(IFNONNULL, l0);
+ mv.visitLdcInsn("null");
+ mv.visitIntInsn(ASTORE, off);
+ mv.visitLabel(l0);
+ }
+ off += getParameterSize(cl);
+ break;
+ default:
+ throw new StringConcatException("Unhandled tag: " + el.getTag());
}
}
}
@@ -912,30 +919,35 @@
mv.visitInsn(ICONST_0);
for (RecipeElement el : recipe.getElements()) {
- if (el.isConst()) {
- Object cnst = el.getValue();
- len += cnst.toString().length();
- } else {
- /*
- If an argument is String, then we can call .length() on it. Sized/Exact modes have
- converted arguments for us. If an argument is primitive, we can provide a guess
- for its String representation size.
- */
- Class<?> cl = arr[el.getArgPos()];
- if (cl == String.class) {
- mv.visitIntInsn(ALOAD, off);
- mv.visitMethodInsn(
- INVOKEVIRTUAL,
- "java/lang/String",
- "length",
- "()I",
- false
- );
- mv.visitInsn(IADD);
- } else if (cl.isPrimitive()) {
- len += estimateSize(cl);
- }
- off += getParameterSize(cl);
+ switch (el.getTag()) {
+ case TAG_CONST:
+ Object cnst = el.getValue();
+ len += cnst.toString().length();
+ break;
+ case TAG_ARG:
+ /*
+ If an argument is String, then we can call .length() on it. Sized/Exact modes have
+ converted arguments for us. If an argument is primitive, we can provide a guess
+ for its String representation size.
+ */
+ Class<?> cl = arr[el.getArgPos()];
+ if (cl == String.class) {
+ mv.visitIntInsn(ALOAD, off);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL,
+ "java/lang/String",
+ "length",
+ "()I",
+ false
+ );
+ mv.visitInsn(IADD);
+ } else if (cl.isPrimitive()) {
+ len += estimateSize(cl);
+ }
+ off += getParameterSize(cl);
+ break;
+ default:
+ throw new StringConcatException("Unhandled tag: " + el.getTag());
}
}
@@ -967,15 +979,20 @@
int off = 0;
for (RecipeElement el : recipe.getElements()) {
String desc;
- if (el.isConst()) {
- Object cnst = el.getValue();
- mv.visitLdcInsn(cnst);
- desc = getSBAppendDesc(cnst.getClass());
- } else {
- Class<?> cl = arr[el.getArgPos()];
- mv.visitVarInsn(getLoadOpcode(cl), off);
- off += getParameterSize(cl);
- desc = getSBAppendDesc(cl);
+ switch (el.getTag()) {
+ case TAG_CONST:
+ Object cnst = el.getValue();
+ mv.visitLdcInsn(cnst);
+ desc = getSBAppendDesc(cnst.getClass());
+ break;
+ case TAG_ARG:
+ Class<?> cl = arr[el.getArgPos()];
+ mv.visitVarInsn(getLoadOpcode(cl), off);
+ off += getParameterSize(cl);
+ desc = getSBAppendDesc(cl);
+ break;
+ default:
+ throw new StringConcatException("Unhandled tag: " + el.getTag());
}
mv.visitMethodInsn(
@@ -1245,7 +1262,6 @@
}
}
- List<Class<?>> ptypesList = Arrays.asList(ptypes);
MethodHandle[] lengthers = new MethodHandle[pc];
// Figure out lengths: constants' lengths can be deduced on the spot.
@@ -1253,24 +1269,29 @@
// call the usual String.length(). Primitive values string sizes can be estimated.
int initial = 0;
for (RecipeElement el : recipe.getElements()) {
- if (el.isConst()) {
- Object cnst = el.getValue();
- initial += cnst.toString().length();
- } else {
- final int i = el.getArgPos();
- Class<?> type = ptypesList.get(i);
- if (type.isPrimitive()) {
- MethodHandle est = MethodHandles.constant(int.class, estimateSize(type));
- est = MethodHandles.dropArguments(est, 0, type);
- lengthers[i] = est;
- } else {
- lengthers[i] = STRING_LENGTH;
- }
+ switch (el.getTag()) {
+ case TAG_CONST:
+ Object cnst = el.getValue();
+ initial += cnst.toString().length();
+ break;
+ case TAG_ARG:
+ final int i = el.getArgPos();
+ Class<?> type = ptypes[i];
+ if (type.isPrimitive()) {
+ MethodHandle est = MethodHandles.constant(int.class, estimateSize(type));
+ est = MethodHandles.dropArguments(est, 0, type);
+ lengthers[i] = est;
+ } else {
+ lengthers[i] = STRING_LENGTH;
+ }
+ break;
+ default:
+ throw new StringConcatException("Unhandled tag: " + el.getTag());
}
}
// Create (StringBuilder, <args>) shape for appending:
- MethodHandle builder = MethodHandles.dropArguments(MethodHandles.identity(StringBuilder.class), 1, ptypesList);
+ MethodHandle builder = MethodHandles.dropArguments(MethodHandles.identity(StringBuilder.class), 1, ptypes);
// Compose append calls. This is done in reverse because the application order is
// reverse as well.
@@ -1278,19 +1299,24 @@
for (int i = elements.size() - 1; i >= 0; i--) {
RecipeElement el = elements.get(i);
MethodHandle appender;
- if (el.isConst()) {
- Object constant = el.getValue();
- MethodHandle mh = appender(adaptToStringBuilder(constant.getClass()));
- appender = MethodHandles.insertArguments(mh, 1, constant);
- } else {
- int ac = el.getArgPos();
- appender = appender(ptypesList.get(ac));
+ switch (el.getTag()) {
+ case TAG_CONST:
+ Object constant = el.getValue();
+ MethodHandle mh = appender(adaptToStringBuilder(constant.getClass()));
+ appender = MethodHandles.insertArguments(mh, 1, constant);
+ break;
+ case TAG_ARG:
+ int ac = el.getArgPos();
+ appender = appender(ptypes[ac]);
- // Insert dummy arguments to match the prefix in the signature.
- // The actual appender argument will be the ac-ith argument.
- if (ac != 0) {
- appender = MethodHandles.dropArguments(appender, 1, ptypesList.subList(0, ac));
- }
+ // Insert dummy arguments to match the prefix in the signature.
+ // The actual appender argument will be the ac-ith argument.
+ if (ac != 0) {
+ appender = MethodHandles.dropArguments(appender, 1, Arrays.copyOf(ptypes, ac));
+ }
+ break;
+ default:
+ throw new StringConcatException("Unhandled tag: " + el.getTag());
}
builder = MethodHandles.foldArguments(builder, appender);
}
@@ -1460,7 +1486,6 @@
ptypes[i] = filter.type().returnType();
}
}
- List<Class<?>> ptypesList = Arrays.asList(ptypes);
// Start building the combinator tree. The tree "starts" with (<parameters>)String, and "finishes"
// with the (int, byte[], byte)String in String helper. The combinators are assembled bottom-up,
@@ -1481,12 +1506,17 @@
// *ending* index.
for (RecipeElement el : recipe.getElements()) {
MethodHandle prepender;
- if (el.isConst()) {
- Object cnst = el.getValue();
- prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
- } else {
- int pos = el.getArgPos();
- prepender = selectArgument(prepender(ptypesList.get(pos)), 3, ptypesList, pos);
+ switch (el.getTag()) {
+ case TAG_CONST:
+ Object cnst = el.getValue();
+ prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
+ break;
+ case TAG_ARG:
+ int pos = el.getArgPos();
+ prepender = selectArgument(prepender(ptypes[pos]), 3, ptypes, pos);
+ break;
+ default:
+ throw new StringConcatException("Unhandled tag: " + el.getTag());
}
// Remove "old" index from arguments
@@ -1507,7 +1537,7 @@
}
// Fold in byte[] instantiation at argument 0.
- MethodHandle combiner = MethodHandles.dropArguments(NEW_ARRAY, 2, ptypesList);
+ MethodHandle combiner = MethodHandles.dropArguments(NEW_ARRAY, 2, ptypes);
mh = MethodHandles.foldArguments(mh, combiner);
// Start combining length and coder mixers.
@@ -1526,36 +1556,41 @@
byte initialCoder = INITIAL_CODER;
int initialLen = 0; // initial length, in characters
for (RecipeElement el : recipe.getElements()) {
- if (el.isConst()) {
- Object constant = el.getValue();
- String s = constant.toString();
- initialCoder = (byte) coderMixer(String.class).invoke(initialCoder, s);
- initialLen += s.length();
- } else {
- int ac = el.getArgPos();
+ switch (el.getTag()) {
+ case TAG_CONST:
+ Object constant = el.getValue();
+ String s = constant.toString();
+ initialCoder = (byte) coderMixer(String.class).invoke(initialCoder, s);
+ initialLen += s.length();
+ break;
+ case TAG_ARG:
+ int ac = el.getArgPos();
- Class<?> argClass = ptypesList.get(ac);
- MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypesList, ac);
- lm = MethodHandles.dropArguments(lm, 0, byte.class); // (*)
- lm = MethodHandles.dropArguments(lm, 2, byte.class);
+ Class<?> argClass = ptypes[ac];
+ MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypes, ac);
+ lm = MethodHandles.dropArguments(lm, 0, byte.class); // (*)
+ lm = MethodHandles.dropArguments(lm, 2, byte.class);
+
+ MethodHandle cm = selectArgument(coderMixer(argClass), 1, ptypes, ac);
+ cm = MethodHandles.dropArguments(cm, 0, int.class); // (**)
- MethodHandle cm = selectArgument(coderMixer(argClass), 1, ptypesList, ac);
- cm = MethodHandles.dropArguments(cm, 0, int.class); // (**)
+ // Read this bottom up:
- // Read this bottom up:
+ // 4. Drop old index and coder, producing ("new-index", "new-coder", <args>)
+ mh = MethodHandles.dropArguments(mh, 2, int.class, byte.class);
- // 4. Drop old index and coder, producing ("new-index", "new-coder", <args>)
- mh = MethodHandles.dropArguments(mh, 2, int.class, byte.class);
+ // 3. Compute "new-index", producing ("new-index", "new-coder", "old-index", "old-coder", <args>)
+ // Length mixer ignores both "new-coder" and "old-coder" due to dropArguments above (*)
+ mh = MethodHandles.foldArguments(mh, lm);
- // 3. Compute "new-index", producing ("new-index", "new-coder", "old-index", "old-coder", <args>)
- // Length mixer ignores both "new-coder" and "old-coder" due to dropArguments above (*)
- mh = MethodHandles.foldArguments(mh, lm);
+ // 2. Compute "new-coder", producing ("new-coder", "old-index", "old-coder", <args>)
+ // Coder mixer ignores the "old-index" arg due to dropArguments above (**)
+ mh = MethodHandles.foldArguments(mh, cm);
- // 2. Compute "new-coder", producing ("new-coder", "old-index", "old-coder", <args>)
- // Coder mixer ignores the "old-index" arg due to dropArguments above (**)
- mh = MethodHandles.foldArguments(mh, cm);
-
- // 1. The mh shape here is ("old-index", "old-coder", <args>)
+ // 1. The mh shape here is ("old-index", "old-coder", <args>)
+ break;
+ default:
+ throw new StringConcatException("Unhandled tag: " + el.getTag());
}
}
@@ -1582,14 +1617,14 @@
}
// Adapts: (...prefix..., parameter[pos])R -> (...prefix..., ...parameters...)R
- private static MethodHandle selectArgument(MethodHandle mh, int prefix, List<Class<?>> ptypes, int pos) {
+ private static MethodHandle selectArgument(MethodHandle mh, int prefix, Class<?>[] ptypes, int pos) {
if (pos == 0) {
- return MethodHandles.dropArguments(mh, prefix + 1, ptypes.subList(1, ptypes.size()));
- } else if (pos == ptypes.size() - 1) {
- return MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, ptypes.size() - 1));
+ return MethodHandles.dropArguments(mh, prefix + 1, Arrays.copyOfRange(ptypes, 1, ptypes.length));
+ } else if (pos == ptypes.length - 1) {
+ return MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, ptypes.length - 1));
} else { // 0 < pos < ptypes.size() - 1
- MethodHandle t = MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, pos));
- return MethodHandles.dropArguments(t, prefix + 1 + pos, ptypes.subList(pos + 1, ptypes.size()));
+ MethodHandle t = MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, pos));
+ return MethodHandles.dropArguments(t, prefix + 1 + pos, Arrays.copyOfRange(ptypes, pos + 1, ptypes.length));
}
}
@@ -1648,8 +1683,8 @@
private static final ConcurrentMap<Class<?>, MethodHandle> PREPENDERS;
private static final ConcurrentMap<Class<?>, MethodHandle> LENGTH_MIXERS;
private static final ConcurrentMap<Class<?>, MethodHandle> CODER_MIXERS;
- private static final Class<?> STRING_HELPER;
private static final byte INITIAL_CODER;
+ static final Class<?> STRING_HELPER;
static {
try {
@@ -1751,7 +1786,7 @@
/* ------------------------------- Common utilities ------------------------------------ */
- private static MethodHandle lookupStatic(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
+ static MethodHandle lookupStatic(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
try {
return lookup.findStatic(refc, name, MethodType.methodType(rtype, ptypes));
} catch (NoSuchMethodException | IllegalAccessException e) {
@@ -1759,7 +1794,7 @@
}
}
- private static MethodHandle lookupVirtual(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
+ static MethodHandle lookupVirtual(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
try {
return lookup.findVirtual(refc, name, MethodType.methodType(rtype, ptypes));
} catch (NoSuchMethodException | IllegalAccessException e) {
@@ -1767,7 +1802,7 @@
}
}
- private static MethodHandle lookupConstructor(Lookup lookup, Class<?> refc, Class<?> ptypes) {
+ static MethodHandle lookupConstructor(Lookup lookup, Class<?> refc, Class<?> ptypes) {
try {
return lookup.findConstructor(refc, MethodType.methodType(void.class, ptypes));
} catch (NoSuchMethodException | IllegalAccessException e) {
@@ -1775,7 +1810,7 @@
}
}
- private static int estimateSize(Class<?> cl) {
+ static int estimateSize(Class<?> cl) {
if (cl == Integer.TYPE) {
return 11; // "-2147483648"
} else if (cl == Boolean.TYPE) {
@@ -1797,7 +1832,7 @@
}
}
- private static Class<?> adaptToStringBuilder(Class<?> c) {
+ static Class<?> adaptToStringBuilder(Class<?> c) {
if (c.isPrimitive()) {
if (c == Byte.TYPE || c == Short.TYPE) {
return int.class;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java Mon Aug 15 08:15:02 2016 -0700
@@ -31,7 +31,6 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
/**
@@ -54,7 +53,8 @@
List<Class<?>> l = new ArrayList<>();
if (receiver != null)
l.add(receiver);
- l.addAll(Arrays.asList(intermediate));
+ for (Class<?> c : intermediate)
+ l.add(c);
// (Receiver, <Intermediates>)Value
methodType_table[VarHandle.AccessType.GET.ordinal()] =
--- a/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java Mon Aug 15 08:15:02 2016 -0700
@@ -28,6 +28,7 @@
import java.lang.reflect.Modifier;
import static java.lang.reflect.Modifier.*;
import java.lang.reflect.Module;
+import java.util.Objects;
import jdk.internal.reflect.Reflection;
/**
@@ -330,15 +331,7 @@
return true;
if (class1.getClassLoader() != class2.getClassLoader())
return false;
- String name1 = class1.getName(), name2 = class2.getName();
- int dot = name1.lastIndexOf('.');
- if (dot != name2.lastIndexOf('.'))
- return false;
- for (int i = 0; i < dot; i++) {
- if (name1.charAt(i) != name2.charAt(i))
- return false;
- }
- return true;
+ return Objects.equals(class1.getPackageName(), class2.getPackageName());
}
/** Return the package name for this class.
--- a/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java Mon Aug 15 08:15:02 2016 -0700
@@ -580,6 +580,9 @@
Entry entry;
if (key instanceof PrivateKey) {
+ // Check that all the certs are X.509 certs
+ checkX509Certs(chain);
+
PrivateKeyEntry keyEntry = new PrivateKeyEntry();
keyEntry.date = new Date();
@@ -690,6 +693,9 @@
Certificate[] chain)
throws KeyStoreException
{
+ // Check that all the certs are X.509 certs
+ checkX509Certs(chain);
+
// Private key must be encoded as EncryptedPrivateKeyInfo
// as defined in PKCS#8
try {
@@ -960,6 +966,13 @@
private void setCertEntry(String alias, Certificate cert,
Set<KeyStore.Entry.Attribute> attributes) throws KeyStoreException {
+ // Check that the cert is an X.509 cert
+ if (cert != null && (!(cert instanceof X509Certificate))) {
+ throw new KeyStoreException(
+ "Only X.509 certificates are supported - rejecting class: " +
+ cert.getClass().getName());
+ }
+
Entry entry = entries.get(alias.toLowerCase(Locale.ENGLISH));
if (entry != null && entry instanceof KeyEntry) {
throw new KeyStoreException("Cannot overwrite own certificate");
@@ -1505,6 +1518,21 @@
return set.size() == certChain.length;
}
+ /*
+ * Check that all the certificates are X.509 certificates
+ */
+ private static void checkX509Certs(Certificate[] certs)
+ throws KeyStoreException {
+ if (certs != null) {
+ for (Certificate cert : certs) {
+ if (!(cert instanceof X509Certificate)) {
+ throw new KeyStoreException(
+ "Only X.509 certificates are supported - " +
+ "rejecting class: " + cert.getClass().getName());
+ }
+ }
+ }
+ }
/*
* Create PKCS#12 Attributes, friendlyName, localKeyId and trustedKeyUsage.
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Mon Aug 15 08:15:02 2016 -0700
@@ -59,6 +59,11 @@
"jdk.tls.client.enableStatusRequestExtension", true);
private final boolean serverEnableStapling = Debug.getBooleanProperty(
"jdk.tls.server.enableStatusRequestExtension", false);
+ private final static Collection<CipherSuite> clientCustomizedCipherSuites =
+ getCustomizedCipherSuites("jdk.tls.client.cipherSuites");
+ private final static Collection<CipherSuite> serverCustomizedCipherSuites =
+ getCustomizedCipherSuites("jdk.tls.server.cipherSuites");
+
private volatile StatusResponseManager statusResponseManager;
SSLContextImpl() {
@@ -336,20 +341,52 @@
return isClient ? clientEnableStapling : serverEnableStapling;
}
+
/*
- * Return the list of all available CipherSuites with a priority of
- * minPriority or above.
+ * Return the list of all available CipherSuites that are supported
+ * using currently installed providers.
+ */
+ private static CipherSuiteList getApplicableSupportedCipherSuiteList(
+ ProtocolList protocols) {
+
+ return getApplicableCipherSuiteList(
+ CipherSuite.allowedCipherSuites(),
+ protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+ }
+
+ /*
+ * Return the list of all available CipherSuites that are default enabled
+ * in client or server side.
+ */
+ private static CipherSuiteList getApplicableEnabledCipherSuiteList(
+ ProtocolList protocols, boolean isClient) {
+
+ if (isClient) {
+ if (!clientCustomizedCipherSuites.isEmpty()) {
+ return getApplicableCipherSuiteList(
+ clientCustomizedCipherSuites,
+ protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+ }
+ } else {
+ if (!serverCustomizedCipherSuites.isEmpty()) {
+ return getApplicableCipherSuiteList(
+ serverCustomizedCipherSuites,
+ protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+ }
+ }
+
+ return getApplicableCipherSuiteList(
+ CipherSuite.allowedCipherSuites(),
+ protocols, CipherSuite.DEFAULT_SUITES_PRIORITY);
+ }
+
+ /*
+ * Return the list of available CipherSuites which are applicable to
+ * the specified protocols.
*/
private static CipherSuiteList getApplicableCipherSuiteList(
- ProtocolList protocols, boolean onlyEnabled) {
-
- int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY;
- if (onlyEnabled) {
- minPriority = CipherSuite.DEFAULT_SUITES_PRIORITY;
- }
-
- Collection<CipherSuite> allowedCipherSuites =
- CipherSuite.allowedCipherSuites();
+ Collection<CipherSuite> allowedCipherSuites,
+ ProtocolList protocols, int minPriority) {
TreeSet<CipherSuite> suites = new TreeSet<>();
if (!(protocols.collection().isEmpty()) &&
@@ -386,6 +423,67 @@
return new CipherSuiteList(suites);
}
+ /*
+ * Get the customized cipher suites specified by the given system property.
+ */
+ private static Collection<CipherSuite> getCustomizedCipherSuites(
+ String propertyName) {
+
+ String property = GetPropertyAction.privilegedGetProperty(propertyName);
+ if (debug != null && Debug.isOn("sslctx")) {
+ System.out.println(
+ "System property " + propertyName + " is set to '" +
+ property + "'");
+ }
+ 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);
+ }
+ }
+
+ if (property != null && property.length() != 0) {
+ String[] cipherSuiteNames = property.split(",");
+ Collection<CipherSuite> cipherSuites =
+ new ArrayList<>(cipherSuiteNames.length);
+ for (int i = 0; i < cipherSuiteNames.length; i++) {
+ cipherSuiteNames[i] = cipherSuiteNames[i].trim();
+ if (cipherSuiteNames[i].isEmpty()) {
+ continue;
+ }
+
+ CipherSuite suite;
+ try {
+ suite = CipherSuite.valueOf(cipherSuiteNames[i]);
+ } catch (IllegalArgumentException iae) {
+ if (debug != null && Debug.isOn("sslctx")) {
+ System.out.println(
+ "Unknown or unsupported cipher suite name: " +
+ cipherSuiteNames[i]);
+ }
+
+ continue;
+ }
+
+ if (suite.isAvailable()) {
+ cipherSuites.add(suite);
+ } else {
+ if (debug != null && Debug.isOn("sslctx")) {
+ System.out.println(
+ "The current installed providers do not " +
+ "support cipher suite: " + cipherSuiteNames[i]);
+ }
+ }
+ }
+
+ return cipherSuites;
+ }
+
+ return Collections.emptyList();
+ }
+
+
private static String[] getAvailableProtocols(
ProtocolVersion[] protocolCandidates) {
@@ -481,10 +579,10 @@
}));
}
- supportedCipherSuiteList = getApplicableCipherSuiteList(
- supportedProtocolList, false); // all supported
- serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
- serverDefaultProtocolList, true); // enabled only
+ supportedCipherSuiteList = getApplicableSupportedCipherSuiteList(
+ supportedProtocolList);
+ serverDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+ serverDefaultProtocolList, false);
}
@Override
@@ -541,8 +639,8 @@
}));
}
- clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
- clientDefaultProtocolList, true); // enabled only
+ clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+ clientDefaultProtocolList, true);
}
@Override
@@ -581,8 +679,9 @@
}));
}
- clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
- clientDefaultProtocolList, true); // enabled only
+ clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+ clientDefaultProtocolList, true);
+
}
@Override
@@ -623,8 +722,8 @@
}));
}
- clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
- clientDefaultProtocolList, true); // enabled only
+ clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+ clientDefaultProtocolList, true);
}
@Override
@@ -757,8 +856,9 @@
clientDefaultProtocolList = new ProtocolList(
getAvailableProtocols(candidates));
- clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
- clientDefaultProtocolList, true); // enabled only
+ clientDefaultCipherSuiteList =
+ getApplicableEnabledCipherSuiteList(
+ clientDefaultProtocolList, true);
} else {
clientDefaultProtocolList = null; // unlikely to be used
clientDefaultCipherSuiteList = null; // unlikely to be used
@@ -1032,10 +1132,10 @@
ProtocolVersion.DTLS12
}));
- supportedCipherSuiteList = getApplicableCipherSuiteList(
- supportedProtocolList, false); // all supported
- serverDefaultCipherSuiteList = getApplicableCipherSuiteList(
- serverDefaultProtocolList, true); // enabled only
+ supportedCipherSuiteList = getApplicableSupportedCipherSuiteList(
+ supportedProtocolList);
+ serverDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+ serverDefaultProtocolList, false);
}
@Override
@@ -1090,8 +1190,8 @@
ProtocolVersion.DTLS10
}));
- clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
- clientDefaultProtocolList, true); // enabled only
+ clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+ clientDefaultProtocolList, true);
}
@Override
@@ -1122,8 +1222,8 @@
ProtocolVersion.DTLS12
}));
- clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
- clientDefaultProtocolList, true); // enabled only
+ clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
+ clientDefaultProtocolList, true);
}
@Override
@@ -1187,8 +1287,9 @@
clientDefaultProtocolList = new ProtocolList(
getAvailableProtocols(candidates));
- clientDefaultCipherSuiteList = getApplicableCipherSuiteList(
- clientDefaultProtocolList, true); // enabled only
+ clientDefaultCipherSuiteList =
+ getApplicableEnabledCipherSuiteList(
+ clientDefaultProtocolList, true);
} else {
clientDefaultProtocolList = null; // unlikely to be used
clientDefaultCipherSuiteList = null; // unlikely to be used
--- a/jdk/src/java.base/windows/lib/security/default.policy Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.base/windows/lib/security/default.policy Mon Aug 15 08:15:02 2016 -0700
@@ -11,5 +11,6 @@
"clearProviderProperties.SunMSCAPI";
permission java.security.SecurityPermission
"removeProviderProperty.SunMSCAPI";
+ permission java.security.SecurityPermission "authProvider.SunMSCAPI";
permission java.util.PropertyPermission "*", "read";
};
--- a/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardPermission.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/src/java.smartcardio/share/classes/javax/smartcardio/CardPermission.java Mon Aug 15 08:15:02 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -118,7 +118,7 @@
/**
* @serial
*/
- private volatile String actions;
+ private final String actions;
/**
* Constructs a new CardPermission with the specified actions.
@@ -143,10 +143,14 @@
throw new NullPointerException();
}
mask = getMask(actions);
+ this.actions = getActions(mask);
}
private static int getMask(String actions) {
- if ((actions == null) || (actions.length() == 0)) {
+ if (actions == null) {
+ return 0;
+ }
+ if (actions.length() == 0) {
throw new IllegalArgumentException("actions must not be empty");
}
@@ -177,6 +181,9 @@
}
private static String getActions(int mask) {
+ if (mask == 0) {
+ return null;
+ }
if (mask == A_ALL) {
return S_ALL;
}
@@ -200,9 +207,6 @@
* @return the canonical string representation of the actions.
*/
public String getActions() {
- if (actions == null) {
- actions = getActions(mask);
- }
return actions;
}
@@ -278,10 +282,6 @@
private void writeObject(ObjectOutputStream s) throws IOException {
// Write out the actions. The superclass takes care of the name.
- // Call getActions to make sure actions field is initialized
- if (actions == null) {
- getActions();
- }
s.defaultWriteObject();
}
@@ -291,5 +291,4 @@
s.defaultReadObject();
mask = getMask(actions);
}
-
}
--- a/jdk/test/ProblemList.txt Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/ProblemList.txt Mon Aug 15 08:15:02 2016 -0700
@@ -133,15 +133,13 @@
# jdk_instrument
-java/lang/instrument/RedefineBigClass.sh 8061177 generic-all
-java/lang/instrument/RetransformBigClass.sh 8061177 generic-all
+java/lang/instrument/RedefineBigClass.sh 8065756 generic-all
+java/lang/instrument/RetransformBigClass.sh 8065756 generic-all
java/lang/instrument/BootClassPath/BootClassPathTest.sh 8072130 macosx-all
java/lang/instrument/DaemonThread/TestDaemonThread.java 8161225 generic-all
-java/lang/management/MemoryMXBean/LowMemoryTest.java 8130339 generic-all
-
java/lang/management/MemoryMXBean/Pending.java 8158837 generic-all
java/lang/management/MemoryMXBean/PendingAllGC.sh 8158760 generic-all
@@ -235,8 +233,8 @@
sun/security/pkcs11/KeyAgreement/TestDH.java 8077138,8023434 windows-all
sun/security/pkcs11/KeyAgreement/TestInterop.java 8077138,8023434 windows-all
sun/security/pkcs11/KeyAgreement/TestShort.java 8077138,8023434 windows-all
-sun/security/pkcs11/KeyAgreement/SupportedDHKeys.java 8154910 windows-all
-sun/security/pkcs11/KeyAgreement/UnsupportedDHKeys.java 8154910 windows-all
+sun/security/pkcs11/KeyAgreement/SupportedDHKeys.java 8077138 windows-all
+sun/security/pkcs11/KeyAgreement/UnsupportedDHKeys.java 8077138 windows-all
sun/security/pkcs11/KeyGenerator/DESParity.java 8077138,8023434 windows-all
sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java 8077138,8023434 windows-all
sun/security/pkcs11/KeyPairGenerator/TestDH2048.java 8077138,8023434 windows-all
@@ -287,7 +285,6 @@
sun/security/krb5/auto/HttpNegotiateServer.java 8038079 generic-all
-sun/security/tools/keytool/autotest.sh 8130302 generic-all
sun/security/ssl/SSLSocketImpl/AsyncSSLSocketClose.java 8161232 macosx-all
############################################################################
@@ -331,14 +328,10 @@
com/sun/jdi/RedefineImplementor.sh 8004127 generic-all
-com/sun/jdi/JdbMethodExitTest.sh 8031555 generic-all
+com/sun/jdi/JdbMethodExitTest.sh 6902121 generic-all
com/sun/jdi/RepStep.java 8043571 generic-all
-com/sun/jdi/RedefinePop.sh 8058616 generic-all
-
-com/sun/jdi/CatchPatternTest.sh 8068645 generic-all
-
com/sun/jdi/GetLocalVariables4Test.sh 8067354 windows-all
com/sun/jdi/sde/SourceDebugExtensionTest.java 8158066 windows-all
@@ -374,8 +367,6 @@
sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java 8160376 macosx-all
-sun/tools/jstatd/TestJstatdExternalRegistry.java 8046285 generic-all
-
sun/tools/jps/TestJpsJar.java 8160923 generic-all
sun/tools/jps/TestJpsJarRelative.java 6456333 generic-all
--- a/jdk/test/java/io/CharArrayReader/OverflowInRead.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/java/io/CharArrayReader/OverflowInRead.java Mon Aug 15 08:15:02 2016 -0700
@@ -24,7 +24,7 @@
/* @test
* @bug 8163518
* @summary Integer overflow when reading in large buffer
- * @requires (os.simpleArch == "x64" & os.maxMemory > 8g)
+ * @requires (sun.arch.data.model == "64" & os.maxMemory > 8g)
* @run main/othervm -Xmx8g OverflowInRead
*/
--- a/jdk/test/java/io/StringBufferInputStream/OverflowInRead.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/java/io/StringBufferInputStream/OverflowInRead.java Mon Aug 15 08:15:02 2016 -0700
@@ -24,7 +24,7 @@
/* @test
* @bug 8163518
* @summary Integer overflow when reading in large buffer
- * @requires (os.simpleArch == "x64" & os.maxMemory > 4g)
+ * @requires (sun.arch.data.model == "64" & os.maxMemory > 4g)
* @run main/othervm -Xmx4g OverflowInRead
*/
--- a/jdk/test/java/net/ProxySelector/B8035158.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/java/net/ProxySelector/B8035158.java Mon Aug 15 08:15:02 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -22,7 +22,7 @@
*/
/*
* @test
- * @bug 8035158
+ * @bug 8035158 8145732
* @run main/othervm B8035158
*/
@@ -94,6 +94,8 @@
false));
t.add(new TestCase("google.com|google.ie", "http://google.ie",
false));
+ t.add(new TestCase("google.com|google.com|google.ie",
+ "http://google.ie", false));
t.add(new TestCase("google.com|bing.com|yahoo.com",
"http://127.0.0.1", false));
--- a/jdk/test/javax/smartcardio/TestCardPermission.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/javax/smartcardio/TestCardPermission.java Mon Aug 15 08:15:02 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 6293767
+ * @bug 6293767 6469513
* @summary Test for the CardPermission class
* @author Andreas Sterbenz
* @compile --add-modules=java.smartcardio TestCardPermission.java
@@ -49,15 +49,14 @@
test("Reset,coNnect", "connect,reset");
test("exclusive,*,connect", "*");
test("connect,reset,exclusive,transmitControl,getBasicChannel,openLogicalChannel", "*");
+ test(null, null);
- invalid(null);
invalid("");
invalid("foo");
invalid("connect, reset");
invalid("connect,,reset");
invalid("connect,");
invalid(",connect");
- invalid("");
}
private static void invalid(String s) throws Exception {
@@ -77,7 +76,7 @@
CardPermission p = new CardPermission("*", actions);
System.out.println(p);
String a = p.getActions();
- if (canon.equals(a) == false) {
+ if (canon != null && canon.equals(a) == false) {
throw new Exception("Canonical actions mismatch: " + canon + " != " + a);
}
}
--- a/jdk/test/sun/security/mscapi/AccessKeyStore.java Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/sun/security/mscapi/AccessKeyStore.java Mon Aug 15 08:15:02 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -22,7 +22,12 @@
*/
/**
- * @see AccessKeyStore.sh
+ * @test
+ * @bug 6324295 6931562 8154113
+ * @modules jdk.crypto.mscapi
+ * @run main/othervm/java.security.policy==access.policy AccessKeyStore pass
+ * @run main/othervm/java.security.policy==noaccess.policy AccessKeyStore fail
+ * @summary Confirm that right permissions are granted to access keystores.
*/
import java.security.Provider;
@@ -36,13 +41,16 @@
public static void main(String[] args) throws Exception {
- // Check that a security manager has been installed
+ // Check for security manager and required arg(s)
if (System.getSecurityManager() == null) {
- throw new Exception("A security manager has not been installed");
+ throw new Exception("Missing security manager");
}
+ if (args.length <= 0) {
+ throw new Exception("Missing expected test status");
+ }
+ boolean shouldPass = args[0].equalsIgnoreCase("pass");
Provider p = Security.getProvider("SunMSCAPI");
-
System.out.println("SunMSCAPI provider classname is " +
p.getClass().getName());
@@ -56,18 +64,14 @@
* SecurityPermission("authProvider.SunMSCAPI")
*/
try {
-
keyStore.load(null, null);
-
- if (args.length > 0 && "-deny".equals(args[0])) {
+ if (!shouldPass) {
throw new Exception(
"Expected KeyStore.load to throw a SecurityException");
}
-
} catch (SecurityException se) {
-
- if (args.length > 0 && "-deny".equals(args[0])) {
- System.out.println("Caught the expected exception: " + se);
+ if (!shouldPass) {
+ System.out.println("Expected exception thrown: " + se);
return;
} else {
throw se;
--- a/jdk/test/sun/security/mscapi/AccessKeyStore.sh Fri Aug 12 14:35:56 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2005, 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
-# @bug 6324295 6931562
-# @requires os.family == "windows"
-# @run shell AccessKeyStore.sh
-# @summary Confirm that permission must be granted to access keystores.
-
-OS=`uname -s`
-case "$OS" in
- Windows* | CYGWIN* )
-
- # 'uname -m' does not give us enough information -
- # should rely on $PROCESSOR_IDENTIFIER (as is done in Defs-windows.gmk),
- # but JTREG does not pass this env variable when executing a shell script.
- #
- # execute test program - rely on it to exit if platform unsupported
-
- ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\AccessKeyStore.java
-
- echo "Using access.policy..."
- ${TESTJAVA}/bin/java ${TESTVMOPTS} \
- -Djava.security.manager \
- -Djava.security.policy==${TESTSRC}\\access.policy \
- AccessKeyStore
-
- echo "Using noaccess.policy..."
- ${TESTJAVA}/bin/java ${TESTVMOPTS} \
- -Djava.security.manager \
- -Djava.security.policy==${TESTSRC}\\noaccess.policy \
- AccessKeyStore -deny
-
- exit
- ;;
-
- * )
- echo "This test is not intended for '$OS' - passing test"
- exit 0
- ;;
-esac
-
--- a/jdk/test/sun/security/mscapi/access.policy Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/sun/security/mscapi/access.policy Mon Aug 15 08:15:02 2016 -0700
@@ -1,19 +1,4 @@
grant {
- // These permissions are required for the test to start
- permission java.lang.RuntimePermission
- "accessClassInPackage.sun.*";
-
- permission java.lang.RuntimePermission "loadLibrary.*";
-
- permission java.util.PropertyPermission "os.arch", "read";
-
- permission java.util.PropertyPermission
- "sun.security.mscapi.keyStoreCompatibilityMode", "read";
-
- permission java.io.FilePermission "<<ALL FILES>>", "read";
-
- permission java.security.SecurityPermission "putProviderProperty.SunMSCAPI";
-
// This permission is required for the test to run to completion
permission java.security.SecurityPermission "authProvider.SunMSCAPI";
};
--- a/jdk/test/sun/security/mscapi/noaccess.policy Fri Aug 12 14:35:56 2016 -0700
+++ b/jdk/test/sun/security/mscapi/noaccess.policy Mon Aug 15 08:15:02 2016 -0700
@@ -1,19 +1,4 @@
grant {
- // These permissions are required for the test to start
- permission java.lang.RuntimePermission
- "accessClassInPackage.sun.*";
-
- permission java.lang.RuntimePermission "loadLibrary.*";
-
- permission java.util.PropertyPermission "os.arch", "read";
-
- permission java.util.PropertyPermission
- "sun.security.mscapi.keyStoreCompatibilityMode", "read";
-
- permission java.io.FilePermission "<<ALL FILES>>", "read";
-
- permission java.security.SecurityPermission "putProviderProperty.SunMSCAPI";
-
// This permission is required for the test to run to completion
//permission java.security.SecurityPermission "authProvider.SunMSCAPI";
};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/SSLContextImpl/CustomizedCipherSuites.java Mon Aug 15 08:15:02 2016 -0700
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8162362
+ * @summary Cannot enable previously default enabled cipher suites
+ * @run main/othervm
+ * CustomizedCipherSuites Default true
+ * TLS_RSA_WITH_AES_128_CBC_SHA
+ * SSL_RSA_WITH_DES_CBC_SHA
+ * @run main/othervm
+ * -Djdk.tls.client.cipherSuites="unknown"
+ * CustomizedCipherSuites Default true
+ * TLS_RSA_WITH_AES_128_CBC_SHA
+ * SSL_RSA_WITH_DES_CBC_SHA
+ * @run main/othervm
+ * -Djdk.tls.client.cipherSuites=""
+ * CustomizedCipherSuites Default true
+ * TLS_RSA_WITH_AES_128_CBC_SHA
+ * SSL_RSA_WITH_DES_CBC_SHA
+ * @run main/othervm
+ * -Djdk.tls.client.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA"
+ * CustomizedCipherSuites Default true
+ * SSL_RSA_WITH_DES_CBC_SHA
+ * TLS_RSA_WITH_AES_128_CBC_SHA
+ * @run main/othervm
+ * -Djdk.tls.server.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA"
+ * CustomizedCipherSuites Default false
+ * SSL_RSA_WITH_DES_CBC_SHA
+ * TLS_RSA_WITH_AES_128_CBC_SHA
+ * @run main/othervm
+ * -Djdk.tls.client.cipherSuites="TLS_RSA_WITH_AES_128_CBC_SHA,unknown,SSL_RSA_WITH_DES_CBC_SHA"
+ * CustomizedCipherSuites Default true
+ * SSL_RSA_WITH_DES_CBC_SHA
+ * ""
+ * @run main/othervm
+ * -Djdk.tls.server.cipherSuites="TLS_RSA_WITH_AES_128_CBC_SHA,unknown,SSL_RSA_WITH_DES_CBC_SHA"
+ * CustomizedCipherSuites Default false
+ * TLS_RSA_WITH_AES_128_CBC_SHA
+ * ""
+ * @run main/othervm
+ * -Djdk.tls.server.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA"
+ * CustomizedCipherSuites Default true
+ * TLS_RSA_WITH_AES_128_CBC_SHA
+ * SSL_RSA_WITH_DES_CBC_SHA
+ * @run main/othervm
+ * -Djdk.tls.client.cipherSuites="SSL_RSA_WITH_DES_CBC_SHA"
+ * CustomizedCipherSuites Default false
+ * TLS_RSA_WITH_AES_128_CBC_SHA
+ * SSL_RSA_WITH_DES_CBC_SHA
+ */
+
+import javax.net.ssl.*;
+
+/**
+ * Test the customized default cipher suites.
+ *
+ * This test is based on the behavior that SSL_RSA_WITH_DES_CBC_SHA is
+ * disabled by default, and TLS_RSA_WITH_AES_128_CBC_SHA is enabled by
+ * default in JDK. If the behavior is changed in the future, please
+ * update the test cases above accordingly.
+ */
+public class CustomizedCipherSuites {
+
+ private static String contextProtocol;
+ private static boolean isClientMode;
+
+ private static String enabledCipherSuite;
+ private static String disabledCipherSuite;
+
+ public static void main(String[] args) throws Exception {
+
+ contextProtocol = trimQuotes(args[0]);
+ isClientMode = Boolean.parseBoolean(args[1]);
+ enabledCipherSuite = trimQuotes(args[2]);
+ disabledCipherSuite = trimQuotes(args[3]);
+
+ //
+ // Create instance of SSLContext with the specified protocol.
+ //
+ SSLContext context = SSLContext.getInstance(contextProtocol);
+
+ // Default SSLContext is initialized automatically.
+ if (!contextProtocol.equals("Default")) {
+ // Use default TK, KM and random.
+ context.init((KeyManager[])null, (TrustManager[])null, null);
+ }
+
+ // SSLContext default parameters is client mode in JDK.
+ if (isClientMode) {
+ //
+ // Check default parameters of the specified SSLContext protocol
+ //
+ SSLParameters parameters = context.getDefaultSSLParameters();
+ System.out.println("Checking SSLContext default parameters ...");
+ checkEnabledCiphers(parameters.getCipherSuites());
+ }
+
+ //
+ // Check supported parameters of the specified SSLContext protocol
+ //
+ SSLParameters parameters = context.getSupportedSSLParameters();
+ System.out.println("Checking SSLContext suppport parameters ...");
+ checkSupportedCiphers(parameters.getCipherSuites());
+
+
+ //
+ // Check the default cipher suites of SSLEngine.
+ //
+ SSLEngine engine = context.createSSLEngine();
+ engine.setUseClientMode(isClientMode);
+
+ System.out.println("Checking SSLEngine default cipher suites ...");
+ checkEnabledCiphers(engine.getEnabledCipherSuites());
+
+ //
+ // Check the supported cipher suites of SSLEngine.
+ //
+ System.out.println("Checking SSLEngine supported cipher suites ...");
+ checkSupportedCiphers(engine.getSupportedCipherSuites());
+
+ if (isClientMode) {
+ SSLSocketFactory factory = context.getSocketFactory();
+ // Use an unconnected socket.
+ try (SSLSocket socket = (SSLSocket)factory.createSocket()) {
+ //
+ // Check the default cipher suites of SSLSocket.
+ //
+ System.out.println(
+ "Checking SSLSocket default cipher suites ...");
+ checkEnabledCiphers(socket.getEnabledCipherSuites());
+
+ //
+ // Check the supported cipher suites of SSLSocket.
+ //
+ System.out.println(
+ "Checking SSLSocket supported cipher suites ...");
+ checkSupportedCiphers(socket.getSupportedCipherSuites());
+ }
+ } else {
+ SSLServerSocketFactory factory = context.getServerSocketFactory();
+ // Use an unbound server socket.
+ try (SSLServerSocket socket =
+ (SSLServerSocket)factory.createServerSocket()) {
+ //
+ // Check the default cipher suites of SSLServerSocket.
+ //
+ System.out.println(
+ "Checking SSLServerSocket default cipher suites ...");
+ checkEnabledCiphers(socket.getEnabledCipherSuites());
+
+ //
+ // Check the supported cipher suites of SSLServerSocket.
+ //
+ System.out.println(
+ "Checking SSLServerSocket supported cipher suites ...");
+ checkSupportedCiphers(socket.getSupportedCipherSuites());
+ }
+ }
+
+ System.out.println("\t... Success");
+ }
+
+ private static void checkEnabledCiphers(
+ String[] ciphers) throws Exception {
+
+ if (ciphers.length == 0) {
+ throw new Exception("No default cipher suites");
+ }
+
+ boolean isMatch = false;
+ if (enabledCipherSuite.isEmpty()) {
+ // Don't check if not specify the expected cipher suite.
+ isMatch = true;
+ }
+
+ boolean isBroken = false;
+ for (String cipher : ciphers) {
+ System.out.println("\tdefault cipher suite " + cipher);
+ if (!enabledCipherSuite.isEmpty() &&
+ cipher.equals(enabledCipherSuite)) {
+ isMatch = true;
+ }
+
+ if (!disabledCipherSuite.isEmpty() &&
+ cipher.equals(disabledCipherSuite)) {
+ isBroken = true;
+ }
+ }
+
+ if (!isMatch) {
+ throw new Exception(
+ "Cipher suite " + enabledCipherSuite + " should be enabled");
+ }
+
+ if (isBroken) {
+ throw new Exception(
+ "Cipher suite " + disabledCipherSuite + " should be disabled");
+ }
+ }
+
+ private static void checkSupportedCiphers(
+ String[] ciphers) throws Exception {
+
+ if (ciphers.length == 0) {
+ throw new Exception("No supported cipher suites");
+ }
+
+ boolean hasEnabledCipherSuite = enabledCipherSuite.isEmpty();
+ boolean hasDisabledCipherSuite = disabledCipherSuite.isEmpty();
+ for (String cipher : ciphers) {
+ System.out.println("\tsupported cipher suite " + cipher);
+ if (!enabledCipherSuite.isEmpty() &&
+ cipher.equals(enabledCipherSuite)) {
+ hasEnabledCipherSuite = true;
+ }
+
+ if (!disabledCipherSuite.isEmpty() &&
+ cipher.equals(disabledCipherSuite)) {
+ hasDisabledCipherSuite = true;
+ }
+ }
+
+ if (!hasEnabledCipherSuite) {
+ throw new Exception(
+ "Cipher suite " + enabledCipherSuite + " should be supported");
+ }
+
+ if (!hasDisabledCipherSuite) {
+ throw new Exception(
+ "Cipher suite " + disabledCipherSuite + " should be supported");
+ }
+ }
+
+ private static String trimQuotes(String candidate) {
+ if (candidate != null && candidate.length() != 0) {
+ // Remove double quote marks from beginning/end of the string.
+ if (candidate.length() > 1 && candidate.charAt(0) == '"' &&
+ candidate.charAt(candidate.length() - 1) == '"') {
+ return candidate.substring(1, candidate.length() - 1);
+ }
+ }
+
+ return candidate;
+ }
+}