diff --git a/make/lib/Awt2dLibraries.gmk b/make/lib/Awt2dLibraries.gmk index fc0c2074e2b654664c94edd22b6de57c83532c5c..063fcd62ad533012e40e2a4345e601247704b929 100644 --- a/make/lib/Awt2dLibraries.gmk +++ b/make/lib/Awt2dLibraries.gmk @@ -23,9 +23,6 @@ # questions. # -# Openwin is defined on Solaris. -OPENWIN_LIB := $(OPENWIN_HOME)/lib - WIN_AWT_LIB := $(JDK_OUTPUTDIR)/objs/libawt/awt.lib ########################################################################################## @@ -477,7 +474,6 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBAWT, \ ASFLAGS := $(LIBAWT_ASFLAGS), \ MAPFILE := $(LIBAWT_MAPFILE), \ LDFLAGS := $(LDFLAGS_JDKLIB) $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_solaris := -R/usr/dt/lib$(OPENJDK_TARGET_CPU_ISADIR) -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR), \ LDFLAGS_SUFFIX_linux := -ljvm $(LIBM) $(LIBDL) -ljava, \ LDFLAGS_SUFFIX_solaris := -ljvm $(LIBM) $(LIBDL) -ljava -lc, \ LDFLAGS_SUFFIX_aix :=-ljvm $(LIBM) $(LIBDL) -ljava -lm,\ @@ -636,14 +632,7 @@ ifeq ($(findstring $(OPENJDK_TARGET_OS),windows macosx),) $(X_CFLAGS), \ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libawt_xawt/mapfile-vers, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(X_LIBS) $(LIBAWT_XAWT_LDFLAGS), \ - LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN) \ - $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ - LDFLAGS_solaris := -L$(OPENWIN_HOME)/sfw/lib$(OPENJDK_TARGET_CPU_ISADIR) \ - -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) \ - -R$(OPENWIN_HOME)/sfw/lib$(OPENJDK_TARGET_CPU_ISADIR) \ - -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) \ - -R/usr/dt/lib$(OPENJDK_TARGET_CPU_ISADIR) \ + $(X_LIBS) $(LIBAWT_XAWT_LDFLAGS) \ $(call SET_SHARED_LIBRARY_ORIGIN) \ $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ LDFLAGS_SUFFIX := $(LIBAWT_XAWT_LDFLAGS_SUFFIX), \ @@ -839,9 +828,7 @@ ifeq ($(BUILD_HEADLESS), true) LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ - LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..) \ - -R/usr/dt/lib$(OPENJDK_TARGET_CPU_ISADIR) \ - -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR), \ + LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_ORIGIN)., \ REORDER := $(LIBAWT_HEADLESS_REORDER), \ LDFLAGS_SUFFIX_linux := -ljvm -lawt -lm $(LIBDL) -ljava, \ @@ -1071,7 +1058,7 @@ else # OPENJDK_TARGET_OS not windows MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjawt/mapfile-vers, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_solaris := -L$(OPENWIN_HOME)/sfw/lib$(OPENJDK_TARGET_CPU_ISADIR) -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR), \ + LDFLAGS_solaris := $(X_LIBS), \ LDFLAGS_SUFFIX_linux := $(JAWT_LIBS) $(LDFLAGS_JDKLIB_SUFFIX), \ LDFLAGS_SUFFIX_aix := $(JAWT_LIBS) $(LDFLAGS_JDKLIB_SUFFIX),\ LDFLAGS_SUFFIX_solaris := $(JAWT_LIBS) $(LDFLAGS_JDKLIB_SUFFIX) -lXrender, \ @@ -1169,11 +1156,11 @@ ifndef OPENJDK CFLAGS := $(CFLAGS_JDKLIB) \ -I$(JDK_TOPDIR)/src/share/javavm/export \ -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/javavm/export \ - -I$(OPENWIN_HOME)/include, \ + $(X_CFLAGS), \ MAPFILE := $(SUNWJDGA_MAPFILE), \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_SUFFIX := -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -R$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -ldga -lX11 $(LIBDL) -lc, \ + LDFLAGS_SUFFIX := $(X_LIBS) -ldga -lX11 $(LIBDL) -lc, \ OBJECT_DIR := $(JDK_OUTPUTDIR)/objs/libsunwjdga, \ DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES))) @@ -1224,8 +1211,6 @@ ifndef BUILD_HEADLESS_ONLY else ifeq ($(OPENJDK_TARGET_OS), windows) LIBSPLASHSCREEN_CFLAGS += -DWITH_WIN32 - else ifeq ($(OPENJDK_TARGET_OS), solaris) - LIBSPLASHSCREEN_CFLAGS += -DWITH_X11 -I$(OPENWIN_HOME)/include -I$(OPENWIN_HOME)/include/X11/extensions else LIBSPLASHSCREEN_CFLAGS += -DWITH_X11 $(X_CFLAGS) endif @@ -1245,10 +1230,7 @@ ifndef BUILD_HEADLESS_ONLY -framework JavaNativeFoundation else ifeq ($(OPENJDK_TARGET_OS), windows) LIBSPLASHSCREEN_LDFLAGS_SUFFIX += kernel32.lib user32.lib gdi32.lib delayimp.lib -DELAYLOAD:user32.dll - else ifeq ($(OPENJDK_TARGET_OS), solaris) - # Solaris still uses OPENWIN_LIB .. - LIBSPLASHSCREEN_LDFLAGS_SUFFIX += -L$(OPENWIN_LIB)$(OPENJDK_TARGET_CPU_ISADIR) -lX11 -lXext $(LIBM) -lpthread - else # .. all other Unixes can use X_LIBS + else LIBSPLASHSCREEN_LDFLAGS_SUFFIX += $(X_LIBS) -lX11 -lXext $(LIBM) -lpthread endif diff --git a/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java b/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java index 83547e494556bb7dadc77278a2bef71b53e7a647..8ba62f242f173959a3f6e9327c2c93fe4ef5b321 100644 --- a/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java +++ b/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2018, 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 @@ -674,20 +674,18 @@ class VirtualMachineImpl extends MirrorImpl versionInfo().jdwpMinor >= 6; } public boolean canGetInstanceInfo() { - if (versionInfo().jdwpMajor < 1 || - versionInfo().jdwpMinor < 6) { + if (versionInfo().jdwpMajor > 1 || + versionInfo().jdwpMinor >= 6) { + validateVM(); + return hasNewCapabilities() && + capabilitiesNew().canGetInstanceInfo; + } else { return false; } - validateVM(); - return hasNewCapabilities() && - capabilitiesNew().canGetInstanceInfo; } public boolean canUseSourceNameFilters() { - if (versionInfo().jdwpMajor < 1 || - versionInfo().jdwpMinor < 6) { - return false; - } - return true; + return versionInfo().jdwpMajor > 1 || + versionInfo().jdwpMinor >= 6; } public boolean canForceEarlyReturn() { validateVM(); @@ -703,12 +701,8 @@ class VirtualMachineImpl extends MirrorImpl capabilitiesNew().canGetSourceDebugExtension; } public boolean canGetClassFileVersion() { - if ( versionInfo().jdwpMajor < 1 && - versionInfo().jdwpMinor < 6) { - return false; - } else { - return true; - } + return versionInfo().jdwpMajor > 1 || + versionInfo().jdwpMinor >= 6; } public boolean canGetConstantPool() { validateVM(); diff --git a/src/share/classes/java/awt/SequencedEvent.java b/src/share/classes/java/awt/SequencedEvent.java index 81fc116e56e7a6280ba6940bf70c3f30e7151295..f4fbc81c8f30b4e92d2fb033faef5aa40341a59a 100644 --- a/src/share/classes/java/awt/SequencedEvent.java +++ b/src/share/classes/java/awt/SequencedEvent.java @@ -104,11 +104,7 @@ class SequencedEvent extends AWTEvent implements ActiveEvent { if (EventQueue.isDispatchThread()) { EventDispatchThread edt = (EventDispatchThread) Thread.currentThread(); - edt.pumpEvents(SentEvent.ID, new Conditional() { - public boolean evaluate() { - return !SequencedEvent.this.isFirstOrDisposed(); - } - }); + edt.pumpEvents(ID, () -> !SequencedEvent.this.isFirstOrDisposed()); } else { while(!isFirstOrDisposed()) { synchronized (SequencedEvent.class) { diff --git a/src/share/classes/java/awt/image/FilteredImageSource.java b/src/share/classes/java/awt/image/FilteredImageSource.java index 2f58c096474f89d267802a0d4678416c798733ac..8c1227f9324f228e3e4ba9cac9d2f34dad57f79f 100644 --- a/src/share/classes/java/awt/image/FilteredImageSource.java +++ b/src/share/classes/java/awt/image/FilteredImageSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2018, 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 @@ -171,7 +171,7 @@ public class FilteredImageSource implements ImageProducer { * @param ic the consumer for the filtered image * @see ImageConsumer */ - public void startProduction(ImageConsumer ic) { + public synchronized void startProduction(ImageConsumer ic) { if (proxies == null) { proxies = new Hashtable(); } @@ -198,7 +198,7 @@ public class FilteredImageSource implements ImageProducer { * * @see ImageConsumer */ - public void requestTopDownLeftRightResend(ImageConsumer ic) { + public synchronized void requestTopDownLeftRightResend(ImageConsumer ic) { if (proxies != null) { ImageFilter imgf = (ImageFilter) proxies.get(ic); if (imgf != null) { diff --git a/src/share/classes/sun/security/krb5/internal/rcache/AuthList.java b/src/share/classes/sun/security/krb5/internal/rcache/AuthList.java index 1764271a272a437d26e504267e8556794d4c9756..c97841746ebeffa063ce0b10cb4d046133aa049e 100644 --- a/src/share/classes/sun/security/krb5/internal/rcache/AuthList.java +++ b/src/share/classes/sun/security/krb5/internal/rcache/AuthList.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, 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 @@ -55,6 +55,9 @@ public class AuthList { private final LinkedList entries; private final int lifespan; + // entries.getLast().ctime, updated after each cleanup. + private volatile int oldestTime = Integer.MIN_VALUE; + /** * Constructs a AuthList. */ @@ -67,11 +70,13 @@ public class AuthList { * Puts the authenticator timestamp into the cache in descending order, * and throw an exception if it's already there. */ - public void put(AuthTimeWithHash t, KerberosTime currentTime) + public synchronized void put(AuthTimeWithHash t, KerberosTime currentTime) throws KrbApErrException { if (entries.isEmpty()) { entries.addFirst(t); + oldestTime = t.ctime; + return; } else { AuthTimeWithHash temp = entries.getFirst(); int cmp = temp.compareTo(t); @@ -106,24 +111,26 @@ public class AuthList { // let us cleanup while we are here long timeLimit = currentTime.getSeconds() - lifespan; - ListIterator it = entries.listIterator(0); - AuthTimeWithHash temp = null; - int index = -1; - while (it.hasNext()) { - // search expired timestamps. - temp = it.next(); - if (temp.ctime < timeLimit) { - index = entries.indexOf(temp); - break; - } + + // Only trigger a cleanup when the earliest entry is + // lifespan + 5 sec ago. This ensures a cleanup is done + // at most every 5 seconds so that we don't always + // addLast(removeLast). + if (oldestTime > timeLimit - 5) { + return; } - // It would be nice if LinkedList has a method called truncate(index). - if (index > -1) { - do { - // remove expired timestamps from the list. - entries.removeLast(); - } while(entries.size() > index); + + // and we remove the *enough* old ones (1 lifetime ago) + while (!entries.isEmpty()) { + AuthTimeWithHash removed = entries.removeLast(); + if (removed.ctime >= timeLimit) { + entries.addLast(removed); + oldestTime = removed.ctime; + return; + } } + + oldestTime = Integer.MIN_VALUE; } public boolean isEmpty() { diff --git a/src/share/classes/sun/security/krb5/internal/rcache/MemoryCache.java b/src/share/classes/sun/security/krb5/internal/rcache/MemoryCache.java index 403d97f831921a66afa809f1bc3515782bbba3ce..351f14eca89e32c679b94d5678d819363bf07d5e 100644 --- a/src/share/classes/sun/security/krb5/internal/rcache/MemoryCache.java +++ b/src/share/classes/sun/security/krb5/internal/rcache/MemoryCache.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,9 @@ package sun.security.krb5.internal.rcache; -import java.util.*; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + import sun.security.krb5.internal.KerberosTime; import sun.security.krb5.internal.KrbApErrException; import sun.security.krb5.internal.ReplayCache; @@ -48,31 +50,18 @@ public class MemoryCache extends ReplayCache { private static final int lifespan = KerberosTime.getDefaultSkew(); private static final boolean DEBUG = sun.security.krb5.internal.Krb5.DEBUG; - private final Map content = new HashMap<>(); + private final Map content = new ConcurrentHashMap<>(); @Override public synchronized void checkAndStore(KerberosTime currTime, AuthTimeWithHash time) throws KrbApErrException { String key = time.client + "|" + time.server; - AuthList rc = content.get(key); + content.computeIfAbsent(key, k -> new AuthList(lifespan)) + .put(time, currTime); if (DEBUG) { System.out.println("MemoryCache: add " + time + " to " + key); } - if (rc == null) { - rc = new AuthList(lifespan); - rc.put(time, currTime); - if (!rc.isEmpty()) { - content.put(key, rc); - } - } else { - if (DEBUG) { - System.out.println("MemoryCache: Existing AuthList:\n" + rc); - } - rc.put(time, currTime); - if (rc.isEmpty()) { - content.remove(key); - } - } + // TODO: clean up AuthList entries with only expired AuthTimeWithHash objects. } public String toString() { diff --git a/src/share/classes/sun/security/ssl/SSLContextImpl.java b/src/share/classes/sun/security/ssl/SSLContextImpl.java index 60aa908bfc4949f523b4197abbb5005fee422a35..28aa4d34f9994228b773535483248aa796697459 100644 --- a/src/share/classes/sun/security/ssl/SSLContextImpl.java +++ b/src/share/classes/sun/security/ssl/SSLContextImpl.java @@ -53,6 +53,11 @@ public abstract class SSLContextImpl extends SSLContextSpi { private X509TrustManager trustManager; private SecureRandom secureRandom; + private final static Collection clientCustomizedCipherSuites = + getCustomizedCipherSuites("jdk.tls.client.cipherSuites"); + private final static Collection serverCustomizedCipherSuites = + getCustomizedCipherSuites("jdk.tls.server.cipherSuites"); + SSLContextImpl() { ephemeralKeyManager = new EphemeralKeyManager(); clientCache = new SSLSessionContextImpl(); @@ -279,19 +284,50 @@ public abstract class SSLContextImpl extends SSLContextSpi { } /* - * 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 getApplicableCipherSuiteList( - ProtocolList protocols, boolean onlyEnabled) { + private static CipherSuiteList getApplicableSupportedCipherSuiteList( + ProtocolList protocols) { + + return getApplicableCipherSuiteList( + CipherSuite.allowedCipherSuites(), + protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY); + } - int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY; - if (onlyEnabled) { - minPriority = CipherSuite.DEFAULT_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); + } } - Collection allowedCipherSuites = - CipherSuite.allowedCipherSuites(); + 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( + Collection allowedCipherSuites, + ProtocolList protocols, int minPriority) { TreeSet suites = new TreeSet<>(); if (!(protocols.collection().isEmpty()) && @@ -328,6 +364,67 @@ public abstract class SSLContextImpl extends SSLContextSpi { return new CipherSuiteList(suites); } + /* + * Get the customized cipher suites specified by the given system property. + */ + private static Collection getCustomizedCipherSuites( + String propertyName) { + + String property = AccessController.doPrivileged( + new GetPropertyAction(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 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) { @@ -422,10 +519,10 @@ public abstract class SSLContextImpl extends SSLContextSpi { })); } - supportedCipherSuiteList = getApplicableCipherSuiteList( - supportedProtocolList, false); // all supported - serverDefaultCipherSuiteList = getApplicableCipherSuiteList( - serverDefaultProtocolList, true); // enabled only + supportedCipherSuiteList = getApplicableSupportedCipherSuiteList( + supportedProtocolList); + serverDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList( + serverDefaultProtocolList, false); } @Override @@ -482,8 +579,8 @@ public abstract class SSLContextImpl extends SSLContextSpi { })); } - clientDefaultCipherSuiteList = getApplicableCipherSuiteList( - clientDefaultProtocolList, true); // enabled only + clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList( + clientDefaultProtocolList, true); } @Override @@ -522,8 +619,9 @@ public abstract class SSLContextImpl extends SSLContextSpi { })); } - clientDefaultCipherSuiteList = getApplicableCipherSuiteList( - clientDefaultProtocolList, true); // enabled only + clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList( + clientDefaultProtocolList, true); + } @Override @@ -564,8 +662,8 @@ public abstract class SSLContextImpl extends SSLContextSpi { })); } - clientDefaultCipherSuiteList = getApplicableCipherSuiteList( - clientDefaultProtocolList, true); // enabled only + clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList( + clientDefaultProtocolList, true); } @Override @@ -696,8 +794,9 @@ public abstract class SSLContextImpl extends SSLContextSpi { 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 diff --git a/src/share/classes/sun/security/ssl/SSLEngineImpl.java b/src/share/classes/sun/security/ssl/SSLEngineImpl.java index e021d8ee2c27968ad02c5f2376cdb33e10722d9b..fef6868384c1e5ac336d00392c5f3f95791b5cb7 100644 --- a/src/share/classes/sun/security/ssl/SSLEngineImpl.java +++ b/src/share/classes/sun/security/ssl/SSLEngineImpl.java @@ -1946,13 +1946,21 @@ final public class SSLEngineImpl extends SSLEngine { case cs_START: /* - * If we need to change the engine mode and the enabled - * protocols haven't specifically been set by the user, - * change them to the corresponding default ones. + * If we need to change the socket mode and the enabled + * protocols and cipher suites haven't specifically been + * set by the user, change them to the corresponding + * default ones. */ - if (roleIsServer != (!flag) && - sslContext.isDefaultProtocolList(enabledProtocols)) { - enabledProtocols = sslContext.getDefaultProtocolList(!flag); + if (roleIsServer != (!flag)) { + if (sslContext.isDefaultProtocolList(enabledProtocols)) { + enabledProtocols = + sslContext.getDefaultProtocolList(!flag); + } + + if (sslContext.isDefaultCipherSuiteList(enabledCipherSuites)) { + enabledCipherSuites = + sslContext.getDefaultCipherSuiteList(!flag); + } } roleIsServer = !flag; diff --git a/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/src/share/classes/sun/security/ssl/SSLSocketImpl.java index d7322dd5ddb89b9d2ec089422ba50ccb766c4e1d..23df2c5b62de5aa38856457096372328bd617727 100644 --- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java @@ -2417,13 +2417,22 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { case cs_START: /* * If we need to change the socket mode and the enabled - * protocols haven't specifically been set by the user, - * change them to the corresponding default ones. + * protocols and cipher suites haven't specifically been + * set by the user, change them to the corresponding + * default ones. */ - if (roleIsServer != (!flag) && - sslContext.isDefaultProtocolList(enabledProtocols)) { - enabledProtocols = sslContext.getDefaultProtocolList(!flag); + if (roleIsServer != (!flag)) { + if (sslContext.isDefaultProtocolList(enabledProtocols)) { + enabledProtocols = + sslContext.getDefaultProtocolList(!flag); + } + + if (sslContext.isDefaultCipherSuiteList(enabledCipherSuites)) { + enabledCipherSuites = + sslContext.getDefaultCipherSuiteList(!flag); + } } + roleIsServer = !flag; break; diff --git a/src/windows/classes/sun/awt/windows/WToolkit.java b/src/windows/classes/sun/awt/windows/WToolkit.java index 4792306da2d717845f064acef1c566c379cb8698..e639ff7ea99264f455601c10c5d59e9c0ed51d63 100644 --- a/src/windows/classes/sun/awt/windows/WToolkit.java +++ b/src/windows/classes/sun/awt/windows/WToolkit.java @@ -1123,6 +1123,7 @@ public final class WToolkit extends SunToolkit implements Runnable { } if ((e instanceof MouseEvent) && comp.isEnabled() && + comp.isFocusable() && (((comp instanceof TextComponent) && ((TextComponent)comp).isEditable()) || ((comp instanceof JTextComponent) && diff --git a/src/windows/native/sun/security/mscapi/security.cpp b/src/windows/native/sun/security/mscapi/security.cpp index 5796c3085821a6e5a71a88e928fb797791316936..508eabeb66b24fa47d295cc70d47989b3bc2dbb4 100644 --- a/src/windows/native/sun/security/mscapi/security.cpp +++ b/src/windows/native/sun/security/mscapi/security.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #define OID_EKU_ANY "2.5.29.37.0" @@ -47,14 +48,27 @@ #define KEYSTORE_EXCEPTION "java/security/KeyStoreException" #define PROVIDER_EXCEPTION "java/security/ProviderException" #define SIGNATURE_EXCEPTION "java/security/SignatureException" +#define OUT_OF_MEMORY_ERROR "java/lang/OutOfMemoryError" extern "C" { +/* + * Throws an arbitrary Java exception with the given message. + */ +void ThrowExceptionWithMessage(JNIEnv *env, const char *exceptionName, + const char *szMessage) +{ + jclass exceptionClazz = env->FindClass(exceptionName); + if (exceptionClazz != NULL) { + env->ThrowNew(exceptionClazz, szMessage); + } +} + /* * Throws an arbitrary Java exception. * The exception message is a Windows system error message. */ -void ThrowException(JNIEnv *env, char *exceptionName, DWORD dwError) +void ThrowException(JNIEnv *env, const char *exceptionName, DWORD dwError) { char szMessage[1024]; szMessage[0] = '\0'; @@ -65,12 +79,22 @@ void ThrowException(JNIEnv *env, char *exceptionName, DWORD dwError) strcpy(szMessage, "Unknown error"); } - jclass exceptionClazz = env->FindClass(exceptionName); - if (exceptionClazz != NULL) { - env->ThrowNew(exceptionClazz, szMessage); - } + ThrowExceptionWithMessage(env, exceptionName, szMessage); } +/* + * Overloaded 'operator new[]' variant, which will raise Java's + * OutOfMemoryError in the case of a failure. + */ +void* operator new[](std::size_t size, JNIEnv *env) +{ + void* buf = ::operator new[](size, std::nothrow); + if (buf == NULL) { + ThrowExceptionWithMessage(env, OUT_OF_MEMORY_ERROR, + "Native memory allocation failed"); + } + return buf; +} /* * Maps the name of a hash algorithm to an algorithm identifier. @@ -205,7 +229,10 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_PRNG_generateSeed } else if (length > 0) { - pbData = new BYTE[length]; + pbData = new (env) BYTE[length]; + if (pbData == NULL) { + __leave; + } if (::CryptGenRandom( hCryptProv, @@ -435,7 +462,11 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_loadKeysOrCertificateCh NULL, 0)) > 1) { // Found friendly name - pszNameString = new char[cchNameString]; + pszNameString = new (env) char[cchNameString]; + if (pszNameString == NULL) { + __leave; + } + CertGetNameString(pc, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString, cchNameString); @@ -572,7 +603,10 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash } // Copy hash from Java to native buffer - pHashBuffer = new jbyte[jHashSize]; + pHashBuffer = new (env) jbyte[jHashSize]; + if (pHashBuffer == NULL) { + __leave; + } env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer); // Set hash value in the hash object @@ -610,7 +644,10 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSASignature_signHash __leave; } - pSignedHashBuffer = new jbyte[dwBufLen]; + pSignedHashBuffer = new (env) jbyte[dwBufLen]; + if (pSignedHashBuffer == NULL) { + __leave; + } if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE) { ThrowException(env, SIGNATURE_EXCEPTION, GetLastError()); @@ -698,9 +735,16 @@ JNIEXPORT jboolean JNICALL Java_sun_security_mscapi_RSASignature_verifySignedHas } // Copy hash and signedHash from Java to native buffer - pHashBuffer = new jbyte[jHashSize]; + pHashBuffer = new (env) jbyte[jHashSize]; + if (pHashBuffer == NULL) { + __leave; + } env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer); - pSignedHashBuffer = new jbyte[jSignedHashSize]; + + pSignedHashBuffer = new (env) jbyte[jSignedHashSize]; + if (pSignedHashBuffer == NULL) { + __leave; + } env->GetByteArrayRegion(jSignedHash, 0, jSignedHashSize, pSignedHashBuffer); @@ -913,7 +957,10 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate } // Copy encoding from Java to native buffer - pbCertEncoding = new jbyte[jCertEncodingSize]; + pbCertEncoding = new (env) jbyte[jCertEncodingSize]; + if (pbCertEncoding == NULL) { + __leave; + } env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding); // Create a certificate context from the encoded cert @@ -926,7 +973,10 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate // Set the certificate's friendly name int size = env->GetStringLength(jCertAliasName); - pszCertAliasName = new WCHAR[size + 1]; + pszCertAliasName = new (env) WCHAR[size + 1]; + if (pszCertAliasName == NULL) { + __leave; + } jCertAliasChars = env->GetStringChars(jCertAliasName, NULL); memcpy(pszCertAliasName, jCertAliasChars, size * sizeof(WCHAR)); @@ -964,7 +1014,10 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate __leave; } - pszContainerName = new char[dwDataLen]; + pszContainerName = new (env) char[dwDataLen]; + if (pszContainerName == NULL) { + __leave; + } if (! ::CryptGetProvParam( (HCRYPTPROV) hCryptProv, @@ -978,7 +1031,10 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate } // Convert to a wide char string - pwszContainerName = new WCHAR[dwDataLen]; + pwszContainerName = new (env) WCHAR[dwDataLen]; + if (pwszContainerName == NULL) { + __leave; + } if (mbstowcs(pwszContainerName, pszContainerName, dwDataLen) == 0) { ThrowException(env, KEYSTORE_EXCEPTION, GetLastError()); @@ -1001,7 +1057,10 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate __leave; } - pszProviderName = new char[dwDataLen]; + pszProviderName = new (env) char[dwDataLen]; + if (pszProviderName == NULL) { + __leave; + } if (! ::CryptGetProvParam( (HCRYPTPROV) hCryptProv, @@ -1015,7 +1074,10 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_storeCertificate } // Convert to a wide char string - pwszProviderName = new WCHAR[dwDataLen]; + pwszProviderName = new (env) WCHAR[dwDataLen]; + if (pwszProviderName == NULL) { + __leave; + } if (mbstowcs(pwszProviderName, pszProviderName, dwDataLen) == 0) { ThrowException(env, KEYSTORE_EXCEPTION, GetLastError()); @@ -1155,7 +1217,10 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_removeCertificate } // Copy encoding from Java to native buffer - pbCertEncoding = new jbyte[jCertEncodingSize]; + pbCertEncoding = new (env) jbyte[jCertEncodingSize]; + if (pbCertEncoding == NULL) { + __leave; + } env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding); // Create a certificate context from the encoded cert @@ -1178,7 +1243,10 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_KeyStore_removeCertificate if ((cchNameString = ::CertGetNameString(pTBDCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) > 1) { - pszNameString = new char[cchNameString]; + pszNameString = new (env) char[cchNameString]; + if (pszNameString == NULL) { + __leave; + } ::CertGetNameString(pTBDCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString, @@ -1328,7 +1396,10 @@ JNIEXPORT jlong JNICALL Java_sun_security_mscapi_RSACipher_findCertificateUsingA continue; // not found } - pszNameString = new char[cchNameString]; + pszNameString = new (env) char[cchNameString]; + if (pszNameString == NULL) { + __leave; + } if (::CertGetNameString(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString, @@ -1504,7 +1575,10 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSACipher_encryptDecrypt __try { // Copy data from Java buffer to native buffer - pData = new jbyte[dwBufLen]; + pData = new (env) jbyte[dwBufLen]; + if (pData == NULL) { + __leave; + } env->GetByteArrayRegion(jData, 0, dwBufLen, pData); if (doEncrypt == JNI_TRUE) { @@ -1578,7 +1652,10 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getPublicKeyB __leave; } - pbKeyBlob = new BYTE[dwBlobLen]; + pbKeyBlob = new (env) BYTE[dwBlobLen]; + if (pbKeyBlob == NULL) { + __leave; + } // Generate key blob if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0, @@ -1632,8 +1709,12 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getExponent RSAPUBKEY* pRsaPubKey = (RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC)); + int len = sizeof(pRsaPubKey->pubexp); - exponentBytes = new jbyte[len]; + exponentBytes = new (env) jbyte[len]; + if (exponentBytes == NULL) { + __leave; + } // convert from little-endian while copying from blob for (int i = 0, j = len - 1; i < len; i++, j--) { @@ -1684,9 +1765,12 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_RSAPublicKey_getModulus RSAPUBKEY* pRsaPubKey = (RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC)); - int len = pRsaPubKey->bitlen / 8; - modulusBytes = new jbyte[len]; + int len = pRsaPubKey->bitlen / 8; + modulusBytes = new (env) jbyte[len]; + if (modulusBytes == NULL) { + __leave; + } BYTE * pbModulus = (BYTE *) (keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY)); @@ -1807,12 +1891,16 @@ jbyteArray generateKeyBlob( (jKeyBitLength / 8); } - jbyte* jBlobBytes = new jbyte[jBlobLength]; + jbyte* jBlobBytes = NULL; jbyte* jBlobElement; jbyteArray jBlob = NULL; jsize jElementLength; __try { + jBlobBytes = new (env) jbyte[jBlobLength]; + if (jBlobBytes == NULL) { + __leave; + } BLOBHEADER *pBlobHeader = (BLOBHEADER *) jBlobBytes; if (bGeneratePrivateKeyBlob) { diff --git a/src/windows/native/sun/windows/awt_Component.cpp b/src/windows/native/sun/windows/awt_Component.cpp index 58993b4ef0320ed2dd53be3051ed4590ac97c15a..2b4430ecb90ebaa286b0ad9629cde595ba8c4a82 100644 --- a/src/windows/native/sun/windows/awt_Component.cpp +++ b/src/windows/native/sun/windows/awt_Component.cpp @@ -1815,6 +1815,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) "new = 0x%08X", GetHWnd(), GetClassName(), (UINT)lParam); mr = WmInputLangChange(static_cast(wParam), reinterpret_cast(lParam)); + g_bUserHasChangedInputLang = TRUE; CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); // should return non-zero if we process this message retValue = 1; diff --git a/src/windows/native/sun/windows/awt_ScrollPane.cpp b/src/windows/native/sun/windows/awt_ScrollPane.cpp index 7e351e134b7c898d302a3b1e2e23351fd55dc7ea..1e4091bd50578f76dd60eb5c6b58921d4abf1004 100644 --- a/src/windows/native/sun/windows/awt_ScrollPane.cpp +++ b/src/windows/native/sun/windows/awt_ScrollPane.cpp @@ -196,15 +196,7 @@ void AwtScrollPane::SetScrollInfo(int orient, int max, int page, // and the page size changes posAfter = GetScrollPos(orient); if (posBefore != posAfter) { - if(max==0 && posAfter==0) { - // Caller used nMin==nMax idiom to hide scrollbar. - // On the new themes (Windows XP, Vista) this would reset - // scroll position to zero ("just inside the range") (6404832). - // - PostScrollEvent(orient, SB_THUMBPOSITION, posBefore); - }else{ - PostScrollEvent(orient, SB_THUMBPOSITION, posAfter); - } + PostScrollEvent(orient, SB_THUMBPOSITION, posAfter); } } @@ -263,8 +255,11 @@ void AwtScrollPane::RecalcSizes(int parentWidth, int parentHeight, (policy == java_awt_ScrollPane_SCROLLBARS_ALWAYS)); env->DeleteLocalRef(hAdj); } else { - SetScrollInfo(SB_HORZ, 0, 0, + /* Set scroll info to imitate the behaviour and since we don't + need to display it, explicitly don't show the bar */ + SetScrollInfo(SB_HORZ, childWidth - 1, parentWidth, (policy == java_awt_ScrollPane_SCROLLBARS_ALWAYS)); + ::ShowScrollBar(GetHWnd(), SB_HORZ, false); } if (needsVert) { @@ -275,8 +270,11 @@ void AwtScrollPane::RecalcSizes(int parentWidth, int parentHeight, (policy == java_awt_ScrollPane_SCROLLBARS_ALWAYS)); env->DeleteLocalRef(vAdj); } else { - SetScrollInfo(SB_VERT, 0, 0, + /* Set scroll info to imitate the behaviour and since we don't + need to display it, explicitly don't show the bar */ + SetScrollInfo(SB_VERT, childHeight - 1, parentHeight, (policy == java_awt_ScrollPane_SCROLLBARS_ALWAYS)); + ::ShowScrollBar(GetHWnd(), SB_VERT, false); } env->DeleteLocalRef(target); diff --git a/src/windows/native/sun/windows/awt_Toolkit.cpp b/src/windows/native/sun/windows/awt_Toolkit.cpp index 2027cab6f3523ee1e6ca0094dc5410c9a6b73cb8..f43b1d501f66fea1aff549a27b4199a7f0220dbb 100644 --- a/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -490,8 +490,7 @@ void AwtToolkit::InitTouchKeyboardExeFilePath() { HWND AwtToolkit::GetTouchKeyboardWindow() { const TCHAR wndClassName[] = _T("IPTip_Main_Window"); HWND hwnd = ::FindWindow(wndClassName, NULL); - if ((hwnd != NULL) && ::IsWindow(hwnd) && ::IsWindowEnabled(hwnd) && - ::IsWindowVisible(hwnd)) { + if ((hwnd != NULL) && ::IsWindow(hwnd) && ::IsWindowEnabled(hwnd)) { return hwnd; } return NULL; diff --git a/test/TEST.groups b/test/TEST.groups index 8452ce52c52cd1633d574a741c7b3b5724ecde71..8afd9dd26c0ba68f086949b4051558d277bdbb5d 100644 --- a/test/TEST.groups +++ b/test/TEST.groups @@ -393,6 +393,7 @@ needs_jre = \ javax/management/mxbean/LeakTest.java \ javax/management/mxbean/MXBeanTest.java \ javax/management/mxbean/PropertyNamesTest.java \ + javax/xml/bind/marshal/8036981/Test.java \ javax/xml/bind/marshal/8134111/UnmarshalTest.java \ javax/xml/ws/8043129 \ jdk/lambda/vm/InterfaceAccessFlagsTest.java \ diff --git a/test/java/awt/ScrollPane/ScrollPaneValidateTest.java b/test/java/awt/ScrollPane/ScrollPaneValidateTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e1b2b23639c068f60d06dddd186bdf4ca99a4910 --- /dev/null +++ b/test/java/awt/ScrollPane/ScrollPaneValidateTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2018, 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 8195738 + * @summary scroll position in ScrollPane is reset after calling validate() + * @run main ScrollPaneValidateTest + */ + +import java.awt.ScrollPane; +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.Button; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.AWTException; + +public class ScrollPaneValidateTest extends Frame { + ScrollPane pane; + + public ScrollPaneValidateTest() { + setBounds(300, 300, 300, 300); + pane = new ScrollPane(ScrollPane.SCROLLBARS_NEVER); + add(pane, BorderLayout.NORTH); + pane.add(new InnerPanel()); + } + + public static void main(String[] args) throws AWTException { + Robot robot = new Robot(); + final ScrollPaneValidateTest obj = new ScrollPaneValidateTest(); + obj.setVisible(true); + + // set to some scroll position + obj.pane.setScrollPosition(600, 200); + + // get the newly set position + Point scrollPosition = obj.pane.getScrollPosition(); + + // call validate multiple times + obj.pane.validate(); + robot.delay(1000); + obj.pane.validate(); + robot.delay(1000); + + // compare position after calling the validate function + if(!scrollPosition.equals(obj.pane.getScrollPosition())) { + obj.dispose(); + throw new RuntimeException("Scrolling position is changed in ScrollPane"); + } + + obj.dispose(); + return; + } + + class InnerPanel extends Panel { + public InnerPanel() { + this.setLayout(new GridLayout(2, 4)); + for (int i = 1; i <= 8; i++) { + this.add(new Button("Button" + i)); + } + } + + public Dimension getPreferredSize() { + return new Dimension(980, 200); + } + } +} diff --git a/test/java/awt/event/SequencedEvent/SequencedEventTest.java b/test/java/awt/event/SequencedEvent/SequencedEventTest.java new file mode 100644 index 0000000000000000000000000000000000000000..cddc8e0d50197699200ccf0256bb3fd142cd2fac --- /dev/null +++ b/test/java/awt/event/SequencedEvent/SequencedEventTest.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2018, 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 8152974 + * @summary AWT hang occurrs when sequenced events arrive out of sequence + * @run main SequencedEventTest + */ +import sun.awt.AppContext; +import sun.awt.SunToolkit; + +import java.awt.Robot; +import java.awt.Point; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.AWTEvent; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.lang.reflect.Constructor; +import java.util.concurrent.CountDownLatch; + +import javax.swing.JFrame; +import javax.swing.JButton; +import javax.swing.SwingUtilities; +import javax.swing.JTextArea; + +public class SequencedEventTest extends JFrame implements ActionListener { + private JButton spamMeButton; + private static Robot robot; + private static SequencedEventTest window; + private static AppContext context; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> { + window = new SequencedEventTest(); + window.setVisible(true); + }); + + robot = new Robot(); + robot.waitForIdle(); + + Point pt = window.spamMeButton.getLocationOnScreen(); + Dimension d = window.spamMeButton.getSize(); + + robot.mouseMove(pt.x + d.width / 2, pt.y + d.height / 2); + robot.waitForIdle(); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + /* + *Cannot have robot.waitForIdle() here since it will block the test forever, + * in the case of failure and the test will timeout. + */ + + try { + /* + * Wait for 2 seconds, and then see if all the sequenced events are dispatched. + */ + Thread.sleep(2000); + AWTEvent ev = Toolkit.getDefaultToolkit().getSystemEventQueue(). + peekEvent(java.awt.event.FocusEvent.FOCUS_LAST + 1); + + if (ev != null) + throw new RuntimeException("Test case failed!"); + } catch (InterruptedException e) { + throw new RuntimeException("Test case failed." + e.getMessage()); + } + + /* + * In the case of failure, the cleanup job cannot be executed, since it + * will block the test. + */ + System.out.println("Test case succeeded."); + context.dispose(); + SwingUtilities.invokeAndWait(() -> window.dispose()); + } + + public SequencedEventTest() { + super("Test Window"); + + setLayout(new FlowLayout()); + JTextArea textBlock = new JTextArea("Lorem ipsum dolor sit amet..."); + add(textBlock); + + spamMeButton = new JButton("Press me!"); + spamMeButton.addActionListener(this); + add(spamMeButton); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + pack(); + } + + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource() == spamMeButton) { + AWTEvent eventOne = getSequencedEvent(); + AWTEvent eventFour = getSequencedEvent(); + ThreadGroup tg = new ThreadGroup("TestThreadGroup" ); + CountDownLatch latch = new CountDownLatch(1); + Thread t = new Thread(tg, () -> { + context = SunToolkit.createNewAppContext(); + AWTEvent eventTwo = getSequencedEvent(); + AWTEvent eventThree = getSequencedEvent(); + + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(eventThree); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new ActionEvent(this, 0, null)); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new ActionEvent(this, 1, null)); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(eventTwo); + + latch.countDown(); + }); + + t.start(); + try { + latch.await(); + }catch (InterruptedException ex) { + throw new RuntimeException("Test case failed."); + } + + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(eventFour); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new ActionEvent(this, 2, null)); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new ActionEvent(this, 3, null)); + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(eventOne); + + try { + t.join(); + } catch (InterruptedException ex) { + throw new RuntimeException("Test case failed."); + } + } + } + + private AWTEvent getSequencedEvent() + { + AWTEvent wrapMe = new AWTEvent(this, AWTEvent.RESERVED_ID_MAX) {}; + + try { + /* + * SequencedEvent is a package private class, which cannot be instantiated + * by importing. So use reflection to create an instance. + */ + Class seqClass = (Class) Class.forName("java.awt.SequencedEvent"); + Constructor seqConst = seqClass.getConstructor(AWTEvent.class); + seqConst.setAccessible(true);; + return seqConst.newInstance(wrapMe); + } catch (Throwable err) { + throw new RuntimeException("Unable to instantiate SequencedEvent",err); + } + } +} diff --git a/test/java/awt/image/FilteredImageSourceTest.java b/test/java/awt/image/FilteredImageSourceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..aa1731bfb78d0f52f0cd68973af9e195dd567c34 --- /dev/null +++ b/test/java/awt/image/FilteredImageSourceTest.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2017, 2018, 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 8188083 + * @summary The test checks whether applying image filters using + * FilteredImageSource results in a NullPointerException. + * @run main FilteredImageSourceTest + */ +import java.awt.Graphics; +import java.awt.Image; +import java.awt.image.ColorModel; +import java.awt.image.FilteredImageSource; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageFilter; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.util.Hashtable; + +/* + * An empty image consumer that will be added to the list of consumers + * interested in image data for the filtered image. + */ +class EmptyImageConsumer implements ImageConsumer { + @Override + public void setDimensions(int width, int height) { + } + + @Override + public void setProperties(Hashtable props) { + } + + @Override + public void setColorModel(ColorModel colorModel) { + } + + @Override + public void setHints(int hintFlags) { + } + + @Override + public void setPixels(int x, int y, int width, int height, + ColorModel colorModel, byte[] pixels, + int offset, int scanSize) { + } + + @Override + public void setPixels(int x, int y, int width, int height, + ColorModel colorModel, int[] pixels, + int offset, int scanSize) { + } + + @Override + public void imageComplete(int i) { + } +} + +/* + * An empty image producer whose sole purpose is to provide stub methods + * that will be invoked while preparing filtered image. + */ +class EmptyImageProducer implements ImageProducer { + @Override + public void addConsumer(ImageConsumer imageConsumer) { + } + + @Override + public boolean isConsumer(ImageConsumer imageConsumer) { + return false; + } + + @Override + public void removeConsumer(ImageConsumer imageConsumer) { + } + + @Override + public void startProduction(ImageConsumer imageConsumer) { + } + + @Override + public void requestTopDownLeftRightResend(ImageConsumer imageConsumer) { + } +} + +/* + * Typically, an Image object will contain an ImageProducer that prepares + * image data. FilteredImageSource will be set as image producer for images + * that require image filter applied to image data. + */ +class EmptyFilteredImage extends Image { + ImageFilter filter = null; + ImageProducer producer = null; + + public EmptyFilteredImage(ImageProducer imgSource) { + filter = new ImageFilter(); + producer = new FilteredImageSource(imgSource, filter); + } + + @Override + public int getWidth(ImageObserver observer) { + return 100; + } + + @Override + public int getHeight(ImageObserver observer) { + return 100; + } + + @Override + public ImageProducer getSource() { + return producer; + } + + @Override + public Graphics getGraphics() { + throw new UnsupportedOperationException(); + } + + @Override + public Object getProperty(String name, ImageObserver observer) { + return null; + } +} + +public final class FilteredImageSourceTest { + // Minimum test duration in ms + private static final int TEST_MIN_DURATION = 5000; + + /* + * A throwable object that will hold any exception generated while + * executing methods on FilteredImageSource. The test passes if the + * methods execute without any exception + */ + private static volatile Throwable fail = null; + + public static void main(final String[] args) + throws InterruptedException { + final ImageConsumer ic = new EmptyImageConsumer(); + final ImageProducer ip = new EmptyImageProducer(); + final Image image = new EmptyFilteredImage(ip); + + /* + * Simulate the framework's operations on FilteredImageSource by + * invoking the concerned methods in multiple threads and observe + * whether exceptions are generated. + */ + Thread t1 = new Thread(() -> { + try { + while (true) { + image.getSource().addConsumer(ic); + } + } catch (Throwable t) { + fail = t; + } + }); + t1.setDaemon(true); + + Thread t2 = new Thread(() -> { + try { + while (true) { + image.getSource().removeConsumer(ic); + } + } catch (Throwable t) { + fail = t; + } + }); + t2.setDaemon(true); + + Thread t3 = new Thread(() -> { + try { + while (true) { + image.getSource().startProduction(ic); + } + } catch (Throwable t) { + fail = t; + } + }); + t3.setDaemon(true); + + // Start the threads + t1.start(); + t2.start(); + t3.start(); + + // Wait on one of the threads for a specific duration. + t1.join(TEST_MIN_DURATION); + if (fail != null) { + throw new RuntimeException("Test failed with exception: ", fail); + } + } +} diff --git a/test/java/security/Signature/SignatureLength.java b/test/java/security/Signature/SignatureLength.java index 13c4a6dd938395b915185c4ff244d447c2d12a77..ee6b72b7dbcd0f6de0f534e288007a19f51366de 100644 --- a/test/java/security/Signature/SignatureLength.java +++ b/test/java/security/Signature/SignatureLength.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,48 +21,82 @@ * questions. */ -import java.security.*; - /* * @test - * @bug 8161571 + * @bug 8161571 8178370 * @summary Reject signatures presented for verification that contain extra * bytes. + * @modules jdk.crypto.ec * @run main SignatureLength */ + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; +import java.security.Signature; +import java.security.SignatureException; + public class SignatureLength { public static void main(String[] args) throws Exception { - main0("EC", 256, "SHA256withECDSA", "SunEC"); - main0("RSA", 2048, "SHA256withRSA", "SunRsaSign"); - main0("DSA", 2048, "SHA256withDSA", "SUN"); + for (Provider p0 : Security.getProviders()) { + for (Provider p1 : Security.getProviders()) { + for (Provider p2 : Security.getProviders()) { + // SunMSCAPI signer can only be initialized with + // a key generated with SunMSCAPI + if (!p0.getName().equals("SunMSCAPI") + && p1.getName().equals("SunMSCAPI")) continue; + + // SunMSCAPI generated key can only be signed + // with SunMSCAPI signer + if (p0.getName().equals("SunMSCAPI") + && !p1.getName().equals("SunMSCAPI")) continue; + + // SunMSCAPI and SunPKCS11 verifiers may return false + // instead of throwing SignatureException + boolean mayNotThrow = p2.getName().equals("SunMSCAPI") + || p2.getName().startsWith("SunPKCS11"); - if (System.getProperty("os.name").equals("SunOS")) { - main0("EC", 256, "SHA256withECDSA", null); - main0("RSA", 2048, "SHA256withRSA", null); + main0("EC", 256, "SHA256withECDSA", p0, p1, p2, mayNotThrow); + main0("RSA", 2048, "SHA256withRSA", p0, p1, p2, mayNotThrow); + main0("DSA", 2048, "SHA256withDSA", p0, p1, p2, mayNotThrow); + } + } } } private static void main0(String keyAlgorithm, int keysize, - String signatureAlgorithm, String provider) throws Exception { + String signatureAlgorithm, Provider generatorProvider, + Provider signerProvider, Provider verifierProvider, + boolean mayNotThrow) throws Exception { + + KeyPairGenerator generator; + Signature signer; + Signature verifier; + + try { + generator = KeyPairGenerator.getInstance(keyAlgorithm, + generatorProvider); + signer = Signature.getInstance(signatureAlgorithm, + signerProvider); + verifier = Signature.getInstance(signatureAlgorithm, + verifierProvider); + } catch (NoSuchAlgorithmException nsae) { + // ignore this set of providers + return; + } + byte[] plaintext = "aaa".getBytes("UTF-8"); // Generate - KeyPairGenerator generator = - provider == null ? - (KeyPairGenerator) KeyPairGenerator.getInstance(keyAlgorithm) : - (KeyPairGenerator) KeyPairGenerator.getInstance( - keyAlgorithm, provider); generator.initialize(keysize); System.out.println("Generating " + keyAlgorithm + " keypair using " + generator.getProvider().getName() + " JCE provider"); KeyPair keypair = generator.generateKeyPair(); // Sign - Signature signer = - provider == null ? - Signature.getInstance(signatureAlgorithm) : - Signature.getInstance(signatureAlgorithm, provider); signer.initSign(keypair.getPrivate()); signer.update(plaintext); System.out.println("Signing using " + signer.getProvider().getName() + @@ -80,19 +114,26 @@ public class SignatureLength { badSignature[signature.length + 4] = 0x01; // Verify - Signature verifier = - provider == null ? - Signature.getInstance(signatureAlgorithm) : - Signature.getInstance(signatureAlgorithm, provider); verifier.initVerify(keypair.getPublic()); verifier.update(plaintext); System.out.println("Verifying using " + verifier.getProvider().getName() + " JCE provider"); try { - System.out.println("Valid? " + verifier.verify(badSignature)); - throw new Exception( - "ERROR: expected a SignatureException but none was thrown"); + boolean valid = verifier.verify(badSignature); + System.out.println("Valid? " + valid); + if (mayNotThrow) { + if (valid) { + throw new Exception( + "ERROR: expected a SignatureException but none was thrown" + + " and invalid signature was verified"); + } else { + System.out.println("OK: verification failed as expected"); + } + } else { + throw new Exception( + "ERROR: expected a SignatureException but none was thrown"); + } } catch (SignatureException e) { System.out.println("OK: caught expected exception: " + e); } diff --git a/test/sun/security/ssl/HandshakeHash/DigestBase.java b/test/sun/security/ssl/HandshakeHash/DigestBase.java new file mode 100644 index 0000000000000000000000000000000000000000..a92de6fff6edaacc2e990ea8e7f5178ded1e45e0 --- /dev/null +++ b/test/sun/security/ssl/HandshakeHash/DigestBase.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.*; + +class DigestBase extends MessageDigestSpi { + + private MessageDigest digest = null; + + public DigestBase(String alg, String provider) throws Exception { + digest = MessageDigest.getInstance(alg, provider); + } + + @Override + protected void engineUpdate(byte input) { + digest.update(input); + } + + @Override + protected void engineUpdate(byte[] input, int offset, int len) { + digest.update(input, offset, len); + } + + @Override + protected byte[] engineDigest() { + return digest.digest(); + } + + @Override + protected void engineReset() { + digest.reset(); + } + + public static final class MD5 extends DigestBase { + public MD5() throws Exception { + super("MD5", "SUN"); + } + } + + public static final class SHA extends DigestBase { + public SHA() throws Exception { + super("SHA", "SUN"); + } + } + + public static final class SHA256 extends DigestBase { + public SHA256() throws Exception { + super("SHA-256", "SUN"); + } + } +} diff --git a/test/sun/security/ssl/HandshakeHash/HandshakeHashCloneExhaustion.java b/test/sun/security/ssl/HandshakeHash/HandshakeHashCloneExhaustion.java new file mode 100644 index 0000000000000000000000000000000000000000..73e7c2a51c60bff41750b1cc73574d68bc166f91 --- /dev/null +++ b/test/sun/security/ssl/HandshakeHash/HandshakeHashCloneExhaustion.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016, 2018, 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. + */ + +// +// Please run in othervm mode. SunJSSE does not support dynamic system +// properties, no way to re-use system properties in samevm/agentvm mode. +// + +/* + * @test + * @bug 8148421 8193683 + * @summary Transport Layer Security (TLS) Session Hash and Extended + * Master Secret Extension + * @summary Increase the number of clones in the CloneableDigest + * @library /javax/net/ssl/templates + * @compile DigestBase.java + * @run main/othervm HandshakeHashCloneExhaustion + * TLSv1.2 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * @run main/othervm HandshakeHashCloneExhaustion + * TLSv1.1 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + */ + +import java.io.InputStream; +import java.io.OutputStream; +import java.security.MessageDigest; +import java.security.Security; +import javax.net.ssl.SSLSocket; + +public class HandshakeHashCloneExhaustion extends SSLSocketTemplate { + + private static String[] protocol; + private static String[] ciphersuite; + private static String[] mds = { "SHA", "MD5", "SHA-256" }; + + /* + * ================== + * Run the test case. + */ + public static void main(String[] args) throws Exception { + // Add in a non-cloneable MD5/SHA1/SHA-256 implementation + Security.insertProviderAt(new MyProvider(), 1); + // make sure our provider is functioning + for (String s : mds) { + MessageDigest md = MessageDigest.getInstance(s); + String p = md.getProvider().getName(); + if (!p.equals("MyProvider")) { + throw new RuntimeException("Unexpected provider: " + p); + } + } + + if (args.length != 2) { + throw new Exception( + "Usage: HandshakeHashCloneExhaustion protocol ciphersuite"); + } + + System.out.println("Testing: " + args[0] + " " + args[1]); + protocol = new String [] { args[0] }; + ciphersuite = new String[] { args[1] }; + + (new HandshakeHashCloneExhaustion()).run(); + } + + @Override + protected void runServerApplication(SSLSocket socket) throws Exception { + socket.setNeedClientAuth(true); + socket.setEnabledProtocols(protocol); + socket.setEnabledCipherSuites(ciphersuite); + + // here comes the test logic + InputStream sslIS = socket.getInputStream(); + OutputStream sslOS = socket.getOutputStream(); + + sslIS.read(); + sslOS.write(85); + sslOS.flush(); + } + + @Override + protected void runClientApplication(SSLSocket socket) throws Exception { + InputStream sslIS = socket.getInputStream(); + OutputStream sslOS = socket.getOutputStream(); + + sslOS.write(280); + sslOS.flush(); + sslIS.read(); + } +} diff --git a/test/sun/security/ssl/HandshakeHash/MyProvider.java b/test/sun/security/ssl/HandshakeHash/MyProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..325a0b8fd2c0f12d7b98de648ed90f3667a2027d --- /dev/null +++ b/test/sun/security/ssl/HandshakeHash/MyProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.*; + +public final class MyProvider extends Provider { + + public MyProvider() { + super("MyProvider", 1.0d, + "Test Provider: SHA1/MD5/SHA256 exhaustion testing"); + put("MessageDigest.SHA", "DigestBase$SHA"); + put("MessageDigest.MD5", "DigestBase$MD5"); + put("MessageDigest.SHA-256", "DigestBase$SHA256"); + } +} diff --git a/test/sun/security/ssl/SSLContextImpl/CustomizedCipherSuites.java b/test/sun/security/ssl/SSLContextImpl/CustomizedCipherSuites.java new file mode 100644 index 0000000000000000000000000000000000000000..e19b8f29b83e29b53c1d1577db3938ac7f6947d3 --- /dev/null +++ b/test/sun/security/ssl/SSLContextImpl/CustomizedCipherSuites.java @@ -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; + } +}