summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2010-05-20 15:27:31 -0700
committerBrian Carlstrom <bdc@google.com>2010-05-26 17:06:35 -0700
commit0c131a2ca38465b7d1df4eaee63ac73ce4d5986d (patch)
tree8129cbd03af624f78dc7bbbe7916c7ac7e54f403
parent162a12c1442641a95fe95859fa4e561b22db049f (diff)
downloadlibcore-0c131a2ca38465b7d1df4eaee63ac73ce4d5986d.zip
libcore-0c131a2ca38465b7d1df4eaee63ac73ce4d5986d.tar.gz
libcore-0c131a2ca38465b7d1df4eaee63ac73ce4d5986d.tar.bz2
RI 6 support for javax.net.ssl
Summary: - RI 6 support for javax.net.ssl - SSLEngine fixes based on new SSLEngineTest - fix Cipher.checkMode bug recently introduced in dalvik-dev Details: Fix Cipher.checkMode that was preventing most javax.net.ssl tests from working luni/src/main/java/javax/crypto/Cipher.java RI 6 has introduced the concept of a "Default" SSLContext. This is accessed via SSLContext.getDefault() and also SSLContext.getInstance("Default"). Harmony had its own DefaultSSLContext but it was not created via an SSLContextSpi. It also was a single shared instance whereas the new RI6 Default SSLContext shares internal SSLSessionContext instances between different Default SSLContexts. Refactored the old code into an SSLContextImpl subclass that allows it to be created via SSLContext.getInstance. SSLContextImpl ensures that we only ever create one set of SSLSessionContext instances for the Default context. luni/src/main/java/javax/net/ssl/DefaultSSLContext.java luni/src/main/java/org/apache/harmony/xnet/provider/jsse/DefaultSSLContextImpl.java luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java Added SSLContext.getDefault and SSLContext.setDefault luni/src/main/java/javax/net/ssl/SSLContext.java Replace dependencies of old DefaultSSLContext with use of SSLContext.getDefault luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java luni/src/main/java/javax/net/ssl/SSLSocketFactory.java Register "SSLContext.Default" as DefaultSSLContextImpl class for SSLContext.getInstance() luni/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java Added constant for new "Default" standard name and added it to SSL_CONTEXT_PROTOCOLS. New tests based on SSL_CONTEXT_PROTOCOLS made it clear that neither Android or RI support SSLv2 so removed it from SSL_CONTEXT_PROTOCOLS and SSL_SOCKET_PROTOCOLS. Added constant for TLS as well which was previously scattered all over tests. Remove SSLv2Hello from SSL_SOCKET_PROTOCOLS for Android since with OpenSSL disablign SSLv2 means you can not use SSLv2Hello either. support/src/test/java/javax/net/ssl/StandardNames.java Added tests for SSLContext.getDefault and SSLContext.setDefault. Changed existing tests to work on all protocols including new "Default". luni/src/test/java/javax/net/ssl/SSLContextTest.java RI 6 has introduced the notion of SSLParameters which encapsulate SSL the handshake parameters of desired cipher suites, protocols, and client authentication requirements. The main new class SSLParameters is basically just a bag of fields with accessors and a couple simple constructors. The only things of note are that it clones all String arrays on input and output and the setters for the two boolean fields ensure that only one is true at a time. luni/src/main/java/javax/net/ssl/SSLParameters.java Added SSLContext.getDefaultSSLParameters and SSLContext.getSupportedSSLParameters which simply delegate to the SSLContextSpi. luni/src/main/java/javax/net/ssl/SSLContext.java Added abstract SSLContextSpi.engineGetDefaultSSLParameters and SSLContext.engineGetSupportedSSLParameters. luni/src/main/java/javax/net/ssl/SSLContextSpi.java Added engineGetDefaultSSLParameters and engineGetSupportedSSLParameters implementation. The RI documents in SSLContextSpi that these are implemented by default by creating a socket via the SSLContext's SocketFactory and asking for the enabled/supported cipher suites and protocols respectively, so that is what is done. The doc mentions throwing UnsupportedOperationException if there is a problem, so we do that as well. luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java Added {SSLEngine,SSLSocket}.{getSSLParameters,setSSLParameters} which are analogous. luni/src/main/java/javax/net/ssl/SSLEngine.java luni/src/main/java/javax/net/ssl/SSLSocket.java Added SSLParametersTest luni/src/test/java/javax/net/ssl/SSLParametersTest.java luni/src/test/java/javax/net/ssl/AllTests.java Added SSLContext.get{Default,Supported}SSLParameters tests luni/src/test/java/javax/net/ssl/SSLContextTest.java Added SSLSocket.{getSSLParameters,setSSLParameters} tests and added some extra asserts to test_SSLSocketPair_create based on experience with test_SSLEnginePair_create. luni/src/test/java/javax/net/ssl/SSLSocketTest.java Dummy implementation of new SSLContextSpi for test classes. support/src/test/java/org/apache/harmony/security/tests/support/MySSLContextSpi.java support/src/test/java/org/apache/harmony/xnet/tests/support/MySSLContextSpi.java Other minor RI 6 API changes: RI 6 removed Serializable from HandshakeCompletedEvent and SSLSessionBindingEvent luni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java luni/src/main/java/javax/net/ssl/SSLSessionBindingEvent.java RI 6 added generic types to the KeyStoreBuilderParameters List constructor and accessor as well as to SSLSessionContext.getIds. Fixed tests to compile with generic types. luni/src/main/java/javax/net/ssl/KeyStoreBuilderParameters.java luni/src/main/java/javax/net/ssl/SSLSessionContext.java luni/src/test/java/tests/api/javax/net/ssl/KeyStoreBuilderParametersTest.java SSLEngine improvements. Since I was changing SSLEngine, I wrote an SSLEngineTest based on my SSLSocketTest to do some simply sanity checking. It expose a number of issues. I've fixed the small ones, marked the rest as known failures. Renamed some TLS_ cipher suites to SSL_ to match JSSE standard names. These were all old suites no longer supported by RI or OpenSSL which is why they were missed in an earlier cleanup of this type in this class. Also fixed SSLEngine supported cipher suites list not to include SSL_NULL_WITH_NULL_NULL which is not a valid suite to negotiate. luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CipherSuite.java SSLEngine instances can have null host values, which caused a NullPointerException in the ClientSessionContext implementation. luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java SSLEngine tests were failing because SSLParameters was throwing NullPointerException instead of IllegalArgument exception on null element values. Fixed null pointer message style while I was here. luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java Fixed SSLEngine instances to default to server mode like RI luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java Fixed KEY_TYPES based on SSLEngine implementation. Removed dead code NativeCrypto.getEnabledProtocols which was recently made obsolete. Cleaned up null exception messages to follow our convention. luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java Added SSLEngineTest which parallels SSLSocketTest in its coverage. Similarly added TestSSLEnginePair which loosely parallels TestSSLSocketPair. luni/src/test/java/javax/net/ssl/SSLEngineTest.java luni/src/test/java/javax/net/ssl/AllTests.java support/src/test/java/javax/net/ssl/TestSSLEnginePair.java SSLEngineTest betters exposed the differences between SSLSocket and SSLEngine supported cipher suites. StandardNames now has an CIPHER_SUITES_SSLENGINE definition which denotes what is missing and what is extra and why in the SSLEngine implementation. support/src/test/java/javax/net/ssl/StandardNames.java Created StandardNames.assert{Valid,Supported}{CipherSuites,Protocols} to factor out some code test code that is also used by new tests. support/src/test/java/javax/net/ssl/StandardNames.java luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java luni/src/test/java/javax/net/ssl/SSLSocketTest.java Remove SSLSocketTest known failure and add new SSLEngineTest known failures expectations/knownfailures.txt SSL_OP_NO_TICKET change was recently merged from master which required some fixes. For the moment, sslServerSocketSupportsSessionTickets always returns false. support/src/test/java/javax/net/ssl/TestSSLContext.java Fixed flakey test_SSLSocket_HandshakeCompletedListener which had a race because the client thread look in the server session context for an session by id potentially before the server thread had a chance to store its session. Made noticable because of SSL_OP_NO_TICKET recently merged from master (before this code path was host only, not device) luni/src/test/java/javax/net/ssl/SSLSocketTest.java Fix checkjni issue where we need to check for pending exception in OpenSSL callback. Possibly introduced by recent merge of SSL_OP_NO_TICKET from master. luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp Expectation updates Remove SSLSocketTest known failure and add new SSLEngineTest known failures expectations/knownfailures.txt Tag test_SSLSocket_getSupportedCipherSuites_connect as large expectations/taggedtests.txt Misc changes: opening brace on wrong line luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java Long line cleanup while debugging luni/src/main/java/org/apache/harmony/xnet/provider/jsse/HandshakeProtocol.java luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketFactoryImpl.java luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketFactoryImpl.java support/src/test/java/javax/net/ssl/TestKeyStore.java Removed bogus import luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java Comment clarify while debugging luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java Ctor -> Constructor in comment luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLEngineImpl.java Fixed naming of SocketTest_Test_create to TestSocketPair_Create to match renamed classes luni/src/test/java/javax/net/ssl/SSLSocketTest.java Change-Id: I99505e97d6047eeabe4a0b93202075a0b2d486ec
-rw-r--r--expectations/knownfailures.txt28
-rw-r--r--expectations/taggedtests.txt3
-rw-r--r--luni/src/main/java/javax/crypto/Cipher.java8
-rw-r--r--luni/src/main/java/javax/net/ssl/DefaultSSLContext.java124
-rw-r--r--luni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java9
-rw-r--r--luni/src/main/java/javax/net/ssl/KeyStoreBuilderParameters.java6
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLContext.java78
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLContextSpi.java23
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLEngine.java48
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLParameters.java141
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java10
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLSessionBindingEvent.java12
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLSessionContext.java3
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLSocket.java41
-rw-r--r--luni/src/main/java/javax/net/ssl/SSLSocketFactory.java12
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CipherSuite.java14
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java22
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/DefaultSSLContextImpl.java138
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/HandshakeProtocol.java4
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java1
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java20
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketFactoryImpl.java14
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketFactoryImpl.java26
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java19
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java102
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLEngineImpl.java18
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java37
-rw-r--r--luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java3
-rw-r--r--luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp5
-rw-r--r--luni/src/test/java/javax/net/ssl/AllTests.java4
-rw-r--r--luni/src/test/java/javax/net/ssl/SSLContextTest.java278
-rw-r--r--luni/src/test/java/javax/net/ssl/SSLEngineTest.java379
-rw-r--r--luni/src/test/java/javax/net/ssl/SSLParametersTest.java107
-rw-r--r--luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java1
-rw-r--r--luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java45
-rw-r--r--luni/src/test/java/javax/net/ssl/SSLSocketTest.java161
-rw-r--r--luni/src/test/java/tests/api/javax/net/ssl/KeyStoreBuilderParametersTest.java11
-rw-r--r--support/src/test/java/javax/net/ssl/StandardNames.java131
-rw-r--r--support/src/test/java/javax/net/ssl/TestKeyStore.java4
-rw-r--r--support/src/test/java/javax/net/ssl/TestSSLContext.java22
-rw-r--r--support/src/test/java/javax/net/ssl/TestSSLEnginePair.java168
-rw-r--r--support/src/test/java/org/apache/harmony/security/tests/support/MySSLContextSpi.java14
-rw-r--r--support/src/test/java/org/apache/harmony/xnet/tests/support/MySSLContextSpi.java16
43 files changed, 1828 insertions, 482 deletions
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 31f0863..4394d94 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -871,8 +871,32 @@ result EXEC_FAILED
test tests.api.javax.net.ssl.HostnameVerifierTest#testSubjectAlt
result EXEC_FAILED
-# Need to support SSL_RSA_EXPORT_WITH_RC4_40_MD5
-test javax.net.ssl.SSLSocketTest#test_SSLSocket_getSupportedCipherSuites_connect
+# NO SERVER CERTIFICATE FOUND - selectSuite should not pick a suite that needs a certificate if it is missing
+test javax.net.ssl.SSLEngineTest#test_SSLEngine_beginHandshake_noKeyStore
+result EXEC_FAILED
+
+# NO SERVER CERTIFICATE FOUND - selectSuite should not pick a suite that needs a certificate if it is missing
+test javax.net.ssl.SSLEngineTest#test_SSLEngine_getSupportedCipherSuites_connect
+result EXEC_FAILED
+
+# init - invalid private key
+test javax.net.ssl.SSLEngineTest#test_SSLEngine_clientAuth
+result EXEC_FAILED
+
+# AlertException instead of SSLException
+test javax.net.ssl.SSLEngineTest#test_SSLEngine_setEnableSessionCreation_client
+result EXEC_FAILED
+
+# SSLException instead of failure to handshake
+test javax.net.ssl.SSLEngineTest#test_SSLEngine_setEnableSessionCreation_server
+result EXEC_FAILED
+
+# SSLHandshakeException instead of failure to handshake
+test javax.net.ssl.SSLEngineTest#test_SSLEngine_setUseClientMode
+result EXEC_FAILED
+
+# No *_WITH_NULL_* ciphers work because of 'Invalid transformation: null'
+test javax.net.ssl.SSLEngineTest#test_SSLEngine_getSupportedCipherSuites_connect
result EXEC_FAILED
# method test fails once in a while. Cannot be sure that exception is thrown in every test execution.
diff --git a/expectations/taggedtests.txt b/expectations/taggedtests.txt
index c4ee467..0a5dbfb 100644
--- a/expectations/taggedtests.txt
+++ b/expectations/taggedtests.txt
@@ -6,3 +6,6 @@ tags large
test org.apache.harmony.tests.java.util.regex.MatcherTest.testAllCodePoints
tags large
+# Takes a long time because it tries connecting every supported cipher suite
+test javax.net.ssl.SSLSocketTest#test_SSLSocket_getSupportedCipherSuites_connect
+tags large
diff --git a/luni/src/main/java/javax/crypto/Cipher.java b/luni/src/main/java/javax/crypto/Cipher.java
index c34ba40..3a2dedd 100644
--- a/luni/src/main/java/javax/crypto/Cipher.java
+++ b/luni/src/main/java/javax/crypto/Cipher.java
@@ -505,7 +505,7 @@ public class Cipher {
* if the specified opmode is invalid.
*/
public final void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
- checkMode(mode);
+ checkMode(opmode);
// FIXME InvalidKeyException
// if keysize exceeds the maximum allowable keysize
// (jurisdiction policy files)
@@ -598,7 +598,7 @@ public class Cipher {
public final void init(int opmode, Key key, AlgorithmParameterSpec params,
SecureRandom random) throws InvalidKeyException,
InvalidAlgorithmParameterException {
- checkMode(mode);
+ checkMode(opmode);
// FIXME InvalidKeyException
// if keysize exceeds the maximum allowable keysize
// (jurisdiction policy files)
@@ -689,7 +689,7 @@ public class Cipher {
public final void init(int opmode, Key key, AlgorithmParameters params,
SecureRandom random) throws InvalidKeyException,
InvalidAlgorithmParameterException {
- checkMode(mode);
+ checkMode(opmode);
// FIXME InvalidKeyException
// if keysize exceeds the maximum allowable keysize
// (jurisdiction policy files)
@@ -777,7 +777,7 @@ public class Cipher {
*/
public final void init(int opmode, Certificate certificate,
SecureRandom random) throws InvalidKeyException {
- checkMode(mode);
+ checkMode(opmode);
if (certificate instanceof X509Certificate) {
Set<String> ce = ((X509Certificate) certificate).getCriticalExtensionOIDs();
boolean critical = false;
diff --git a/luni/src/main/java/javax/net/ssl/DefaultSSLContext.java b/luni/src/main/java/javax/net/ssl/DefaultSSLContext.java
deleted file mode 100644
index bcb51ff..0000000
--- a/luni/src/main/java/javax/net/ssl/DefaultSSLContext.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package javax.net.ssl;
-
-import java.io.FileInputStream;
-import java.security.AccessController;
-import java.security.KeyStore;
-import java.security.PrivilegedAction;
-import java.security.Provider;
-import java.security.Security;
-
-import org.apache.harmony.security.fortress.Engine;
-import org.apache.harmony.security.fortress.Services;
-
-/**
- * Support class for this package.
- */
-final class DefaultSSLContext {
- private static SSLContext defaultSSLContext;
-
- static synchronized SSLContext getContext() {
- if (defaultSSLContext == null) {
- defaultSSLContext = AccessController
- .doPrivileged(new PrivilegedAction<SSLContext>() {
- public SSLContext run() {
- return findDefault();
- }
- });
- }
- return defaultSSLContext;
- }
-
- private static SSLContext findDefault() {
- // FIXME EXPORT CONTROL
- for (Provider provider : Services.getProvidersList()) {
- final Provider.Service service = Engine.door.getService(provider, "SSLContext");
- if (service != null) {
- try {
- SSLContext con = new SSLContext((SSLContextSpi) service.newInstance(null),
- service.getProvider(), service.getAlgorithm());
-
- /*
- * TODO
- * javax.net.ssl.keyStoreProvider,
- * javax.net.ssl.trustStoreProvider system property
- */
-
- // find KeyStore, KeyManagers
- KeyManager[] keyManagers = null;
- KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
- String keystore = System.getProperty("javax.net.ssl.keyStore");
- String keystorepwd = System.getProperty("javax.net.ssl.keyStorePassword");
- char[] pwd = null;
- if (keystorepwd != null) {
- pwd = keystorepwd.toCharArray();
- }
- if (keystore != null) {
- FileInputStream fis = new FileInputStream(keystore);
- try {
- ks.load(fis, pwd);
- } finally {
- fis.close();
- }
- KeyManagerFactory kmf;
- String kmfAlg = Security.getProperty("ssl.KeyManagerFactory.algorithm");
- if (kmfAlg == null) {
- kmfAlg = "SunX509";
- }
- kmf = KeyManagerFactory.getInstance(kmfAlg);
- kmf.init(ks, pwd);
- keyManagers = kmf.getKeyManagers();
- }
-
- // find TrustStore, TrustManagers
- TrustManager[] trustManagers = null;
- keystore = System.getProperty("javax.net.ssl.trustStore");
- keystorepwd = System.getProperty("javax.net.ssl.trustStorePassword");
- pwd = null;
- if (keystorepwd != null) {
- pwd = keystorepwd.toCharArray();
- }
- // TODO Defaults: jssecacerts; cacerts
- if (keystore != null) {
- FileInputStream fis = new FileInputStream(keystore);
- try {
- ks.load(fis, pwd);
- } finally {
- fis.close();
- }
- TrustManagerFactory tmf;
- String tmfAlg = Security.getProperty("ssl.TrustManagerFactory.algorithm");
- if (tmfAlg == null) {
- tmfAlg = "PKIX";
- }
- tmf = TrustManagerFactory.getInstance(tmfAlg);
- tmf.init(ks);
- trustManagers = tmf.getTrustManagers();
- }
-
- con.init(keyManagers, trustManagers, null);
- return con;
- } catch (Exception e) {
- // ignore and try another
- }
- }
- }
- return null;
- }
-}
diff --git a/luni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java b/luni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java
index 4618280..4ff53f5 100644
--- a/luni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java
+++ b/luni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java
@@ -17,7 +17,6 @@
package javax.net.ssl;
-import java.io.Serializable;
import java.security.Principal;
import java.security.cert.Certificate;
import javax.security.cert.X509Certificate;
@@ -27,13 +26,7 @@ import java.util.EventObject;
* The event object encapsulating the information about a completed SSL
* handshake on a SSL connection.
*/
-public class HandshakeCompletedEvent extends EventObject implements Serializable {
-
- /**
- * The 5.0 spec. doesn't declare this serialVersionUID field In order to be
- * compatible it is explicitly declared here
- */
- private static final long serialVersionUID = 7914963744257769778L;
+public class HandshakeCompletedEvent extends EventObject {
private transient SSLSession session;
diff --git a/luni/src/main/java/javax/net/ssl/KeyStoreBuilderParameters.java b/luni/src/main/java/javax/net/ssl/KeyStoreBuilderParameters.java
index 899da70..d92aa52 100644
--- a/luni/src/main/java/javax/net/ssl/KeyStoreBuilderParameters.java
+++ b/luni/src/main/java/javax/net/ssl/KeyStoreBuilderParameters.java
@@ -54,8 +54,7 @@ public class KeyStoreBuilderParameters implements ManagerFactoryParameters {
* @throws IllegalArgumentException
* if the specified list is empty.
*/
- @SuppressWarnings("unchecked")
- public KeyStoreBuilderParameters(List parameters) {
+ public KeyStoreBuilderParameters(List<KeyStore.Builder> parameters) {
super();
if (parameters == null) {
throw new NullPointerException("Builders list is null");
@@ -72,8 +71,7 @@ public class KeyStoreBuilderParameters implements ManagerFactoryParameters {
*
* @return the unmodifiable list of {@code KeyStore.Builder}s.
*/
- @SuppressWarnings("unchecked")
- public List getParameters() {
+ public List<KeyStore.Builder> getParameters() {
return ksbuilders;
}
}
diff --git a/luni/src/main/java/javax/net/ssl/SSLContext.java b/luni/src/main/java/javax/net/ssl/SSLContext.java
index 8a0a157..7aae41f 100644
--- a/luni/src/main/java/javax/net/ssl/SSLContext.java
+++ b/luni/src/main/java/javax/net/ssl/SSLContext.java
@@ -36,7 +36,49 @@ public class SSLContext {
private static final String SERVICE = "SSLContext";
// Used to access common engine functionality
- private static Engine engine = new Engine(SERVICE);
+ private static final Engine ENGINE = new Engine(SERVICE);
+
+ /**
+ * Default SSLContext that can be replaced with SSLContext.setDefault()
+ */
+ private static SSLContext DEFAULT;
+
+ /**
+ * Returns the default SSLContext.
+ *
+ * The default SSL context can be set with {@link #setDefault}. If
+ * not, one will be created with {@code
+ * SSLContext.getInstance("Default")}, which will already be
+ * initialized.
+ *
+ * @throws NoSuchAlgorithmException if there is a problem creating
+ * the default instance.
+ * @since 1.6
+ */
+ public static SSLContext getDefault() throws NoSuchAlgorithmException {
+ synchronized (ENGINE) {
+ if (DEFAULT == null) {
+ DEFAULT = SSLContext.getInstance("Default");
+ }
+ return DEFAULT;
+ }
+ }
+
+ /**
+ * Sets the default SSLContext instance as returned by {@link
+ * #getDefault()} to a non-null initialized value.
+ *
+ * @throws NullPointerException on a null argument
+ * @since 1.6
+ */
+ public static void setDefault(SSLContext sslContext) {
+ if (sslContext == null) {
+ throw new NullPointerException("sslContext == null");
+ }
+ synchronized (ENGINE) {
+ DEFAULT = sslContext;
+ }
+ }
/**
* Creates a new {@code SSLContext} instance for the specified protocol.
@@ -54,9 +96,9 @@ public class SSLContext {
if (protocol == null) {
throw new NullPointerException("protocol is null");
}
- synchronized (engine) {
- engine.getInstance(protocol, null);
- return new SSLContext((SSLContextSpi) engine.spi, engine.provider, protocol);
+ synchronized (ENGINE) {
+ ENGINE.getInstance(protocol, null);
+ return new SSLContext((SSLContextSpi) ENGINE.spi, ENGINE.provider, protocol);
}
}
@@ -117,9 +159,9 @@ public class SSLContext {
if (protocol == null) {
throw new NullPointerException("protocol is null");
}
- synchronized (engine) {
- engine.getInstance(protocol, provider, null);
- return new SSLContext((SSLContextSpi) engine.spi, provider, protocol);
+ synchronized (ENGINE) {
+ ENGINE.getInstance(protocol, provider, null);
+ return new SSLContext((SSLContextSpi) ENGINE.spi, provider, protocol);
}
}
@@ -250,4 +292,26 @@ public class SSLContext {
public final SSLSessionContext getClientSessionContext() {
return spiImpl.engineGetClientSessionContext();
}
+
+ /**
+ * Returns the default SSL handshake parameters for SSLSockets
+ * created by this SSLContext.
+ *
+ * @throws UnsupportedOperationException
+ * @since 1.6
+ */
+ public final SSLParameters getDefaultSSLParameters() {
+ return spiImpl.engineGetDefaultSSLParameters();
+ }
+
+ /**
+ * Returns SSL handshake parameters for SSLSockets that includes
+ * all supported cipher suites and protocols.
+ *
+ * @throws UnsupportedOperationException
+ * @since 1.6
+ */
+ public final SSLParameters getSupportedSSLParameters() {
+ return spiImpl.engineGetSupportedSSLParameters();
+ }
}
diff --git a/luni/src/main/java/javax/net/ssl/SSLContextSpi.java b/luni/src/main/java/javax/net/ssl/SSLContextSpi.java
index 44d2c59..20c763e 100644
--- a/luni/src/main/java/javax/net/ssl/SSLContextSpi.java
+++ b/luni/src/main/java/javax/net/ssl/SSLContextSpi.java
@@ -106,4 +106,27 @@ public abstract class SSLContextSpi {
*/
protected abstract SSLSessionContext engineGetClientSessionContext();
+
+ /**
+ * Returns a new SSLParameters instance that includes the default
+ * SSL handshake parameters values including cipher suites,
+ * protocols, and client authentication.
+ *
+ * The default implementation returns an SSLParameters with values
+ * based an SSLSocket created from this instances SocketFactory.
+ *
+ * @since 1.6
+ */
+ protected abstract SSLParameters engineGetDefaultSSLParameters();
+
+ /**
+ * Returns a new SSLParameters instance that includes all
+ * supported cipher suites and protocols.
+ *
+ * The default implementation returns an SSLParameters with values
+ * based an SSLSocket created from this instances SocketFactory.
+ *
+ * @since 1.6
+ */
+ protected abstract SSLParameters engineGetSupportedSSLParameters();
}
diff --git a/luni/src/main/java/javax/net/ssl/SSLEngine.java b/luni/src/main/java/javax/net/ssl/SSLEngine.java
index 21a956c..f737e98 100644
--- a/luni/src/main/java/javax/net/ssl/SSLEngine.java
+++ b/luni/src/main/java/javax/net/ssl/SSLEngine.java
@@ -324,8 +324,10 @@ public abstract class SSLEngine {
* if the engine does not have all the needed settings (e.g.
* client/server mode not set).
*/
- public abstract SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts, int offset, int length)
- throws SSLException;
+ public abstract SSLEngineResult unwrap(ByteBuffer src,
+ ByteBuffer[] dsts,
+ int offset,
+ int length) throws SSLException;
/**
* Encodes the outgoing application data buffers into the network data
@@ -461,4 +463,46 @@ public abstract class SSLEngine {
public SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException {
return wrap(new ByteBuffer[] { src }, 0, 1, dst);
}
+
+ /**
+ * Returns a new SSLParameters based on this SSLSocket's current
+ * cipher suites, protocols, and client authentication settings.
+ *
+ * @since 1.6
+ */
+ public SSLParameters getSSLParameters() {
+ SSLParameters p = new SSLParameters();
+ p.setCipherSuites(getEnabledCipherSuites());
+ p.setProtocols(getEnabledProtocols());
+ p.setNeedClientAuth(getNeedClientAuth());
+ p.setWantClientAuth(getWantClientAuth());
+ return p;
+ }
+
+ /**
+ * Sets various SSL handshake parameters based on the SSLParameter
+ * argument. Specifically, sets the SSLEngine's enabled cipher
+ * suites if the parameter's cipher suites are non-null. Similarly
+ * sets the enabled protocols. If the parameters specify the want
+ * or need for client authentication, those requirements are set
+ * on the SSLEngine, otherwise both are set to false.
+ * @since 1.6
+ */
+ public void setSSLParameters(SSLParameters p) {
+ String[] cipherSuites = p.getCipherSuites();
+ if (cipherSuites != null) {
+ setEnabledCipherSuites(cipherSuites);
+ }
+ String[] protocols = p.getProtocols();
+ if (protocols != null) {
+ setEnabledProtocols(protocols);
+ }
+ if (p.getNeedClientAuth()) {
+ setNeedClientAuth(true);
+ } else if (p.getWantClientAuth()) {
+ setWantClientAuth(true);
+ } else {
+ setWantClientAuth(false);
+ }
+ }
}
diff --git a/luni/src/main/java/javax/net/ssl/SSLParameters.java b/luni/src/main/java/javax/net/ssl/SSLParameters.java
new file mode 100644
index 0000000..6694ef2
--- /dev/null
+++ b/luni/src/main/java/javax/net/ssl/SSLParameters.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.net.ssl;
+
+/**
+ * SSL handshake parameters that include protocols, cipher suites, and
+ * client authentication requirements.
+ * @since 1.6
+ */
+public class SSLParameters {
+
+ private String[] cipherSuites;
+ private String[] protocols;
+ private boolean needClientAuth;
+ private boolean wantClientAuth;
+
+ /**
+ * The default SSLParameters constructor. Cipher suites and
+ * protocols are initialized to null and client authentication
+ * options are initialized to false.
+ */
+ public SSLParameters() {}
+
+ /**
+ * A SSLParameters constructor that allows the values for the
+ * initial cipher suites array to be provided. Other values
+ * default as specified in {@link #SSLParameters()}.
+ *
+ * @param cipherSuites An array of cipherSuites that is cloned for
+ * use within the SSLParameters, or null.
+ */
+ public SSLParameters(String[] cipherSuites) {
+ setCipherSuites(cipherSuites);
+ }
+
+ /**
+ * A SSLParameters constructor that allows the values for initial
+ * cipher suites and protocols arrays to be provided. Other values
+ * default as specified in {@link #SSLParameters()}.
+ *
+ * @param cipherSuites An array of cipher names that is cloned for
+ * use within the SSLParameters, or null.
+ * @param protocols An array of protocol names that is cloned for
+ * use within the SSLParameters, or null.
+ */
+ public SSLParameters(String[] cipherSuites,
+ String[] protocols) {
+ setCipherSuites(cipherSuites);
+ setProtocols(protocols);
+ }
+
+ /**
+ * Returns a copy of the cipher suites, or null if none have been
+ * specified.
+ */
+ public String[] getCipherSuites() {
+ if (cipherSuites == null) {
+ return null;
+ }
+ return cipherSuites.clone();
+ }
+
+ /**
+ * Sets the cipher suites to a copy of the input, or null
+ */
+ public void setCipherSuites(String[] cipherSuites) {
+ this.cipherSuites = ((cipherSuites == null)
+ ? null
+ : cipherSuites.clone());
+ }
+
+ /**
+ * Returns a copy of the protocols, or null if none have been
+ * specified.
+ */
+ public String[] getProtocols() {
+ if (protocols == null) {
+ return null;
+ }
+ return protocols.clone();
+ }
+
+ /**
+ * Sets the protocols to a copy of the input, or null
+ */
+ public void setProtocols(String[] protocols) {
+ this.protocols = ((protocols == null)
+ ? null
+ : protocols.clone());
+ }
+
+ /**
+ * Returns true if a server requires authentication from a client
+ * during handshaking. If this returns true, {@link
+ * #getWantClientAuth} will return false.
+ */
+ public boolean getNeedClientAuth () {
+ return needClientAuth;
+ }
+
+ /**
+ * Sets whether or not to a server needs client authentication.
+ * After calling this, #getWantClientAuth() will return false.
+ */
+ public void setNeedClientAuth (boolean needClientAuth) {
+ this.needClientAuth = needClientAuth;
+ this.wantClientAuth = false;
+ }
+
+ /**
+ * Returns true if a server optionally wants to authenticate a
+ * client during handshaking. If this returns true, {@link
+ * #getNeedClientAuth} will return false.
+ */
+ public boolean getWantClientAuth () {
+ return wantClientAuth;
+ }
+
+ /**
+ * Sets whether or not to a server wants client authentication.
+ * After calling this, #getNeedClientAuth() will return false.
+ */
+ public void setWantClientAuth (boolean wantClientAuth) {
+ this.wantClientAuth = wantClientAuth;
+ this.needClientAuth = false;
+ }
+}
diff --git a/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java b/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
index ccb2c5d..e8a7071 100644
--- a/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
+++ b/luni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
@@ -18,9 +18,9 @@
package javax.net.ssl;
import java.security.AccessController;
+import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.security.Security;
-
import javax.net.ServerSocketFactory;
/**
@@ -65,8 +65,12 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory {
});
}
if (defaultServerSocketFactory == null) {
- // Try to find in providers
- SSLContext context = DefaultSSLContext.getContext();
+ SSLContext context;
+ try {
+ context = SSLContext.getDefault();
+ } catch (NoSuchAlgorithmException e) {
+ context = null;
+ }
if (context != null) {
defaultServerSocketFactory = context.getServerSocketFactory();
}
diff --git a/luni/src/main/java/javax/net/ssl/SSLSessionBindingEvent.java b/luni/src/main/java/javax/net/ssl/SSLSessionBindingEvent.java
index 19ae835..705192d 100644
--- a/luni/src/main/java/javax/net/ssl/SSLSessionBindingEvent.java
+++ b/luni/src/main/java/javax/net/ssl/SSLSessionBindingEvent.java
@@ -17,7 +17,6 @@
package javax.net.ssl;
-import java.io.Serializable;
import java.util.EventObject;
/**
@@ -25,17 +24,8 @@ import java.util.EventObject;
* object is bound ({@link SSLSession#putValue(String, Object)}) or unbound
* ({@link SSLSession#removeValue(String)}) to an {@code SSLSession}.
*/
-public class SSLSessionBindingEvent extends EventObject implements Serializable {
+public class SSLSessionBindingEvent extends EventObject {
- /**
- * The 5.0 spec. doesn't declare this serialVersionUID field In order to be compatible it is
- * explicitly declared here
- */
- private static final long serialVersionUID = 3989172637106345L;
-
- /**
- * @serial include
- */
private final String name;
/**
diff --git a/luni/src/main/java/javax/net/ssl/SSLSessionContext.java b/luni/src/main/java/javax/net/ssl/SSLSessionContext.java
index 154376e..f393072 100644
--- a/luni/src/main/java/javax/net/ssl/SSLSessionContext.java
+++ b/luni/src/main/java/javax/net/ssl/SSLSessionContext.java
@@ -28,8 +28,7 @@ public interface SSLSessionContext {
*
* @return an iterable of all session identifiers in this session context.
*/
- @SuppressWarnings("unchecked")
- public Enumeration getIds();
+ public Enumeration<byte[]> getIds();
/**
* Returns the session for the specified session identifier.
diff --git a/luni/src/main/java/javax/net/ssl/SSLSocket.java b/luni/src/main/java/javax/net/ssl/SSLSocket.java
index 4a70843..4539c3b 100644
--- a/luni/src/main/java/javax/net/ssl/SSLSocket.java
+++ b/luni/src/main/java/javax/net/ssl/SSLSocket.java
@@ -296,4 +296,45 @@ public abstract class SSLSocket extends Socket {
*/
public abstract boolean getEnableSessionCreation();
+ /**
+ * Returns a new SSLParameters based on this SSLSocket's current
+ * cipher suites, protocols, and client authentication settings.
+ *
+ * @since 1.6
+ */
+ public SSLParameters getSSLParameters() {
+ SSLParameters p = new SSLParameters();
+ p.setCipherSuites(getEnabledCipherSuites());
+ p.setProtocols(getEnabledProtocols());
+ p.setNeedClientAuth(getNeedClientAuth());
+ p.setWantClientAuth(getWantClientAuth());
+ return p;
+ }
+
+ /**
+ * Sets various SSL handshake parameters based on the SSLParameter
+ * argument. Specifically, sets the SSLSocket's enabled cipher
+ * suites if the parameter's cipher suites are non-null. Similarly
+ * sets the enabled protocols. If the parameters specify the want
+ * or need for client authentication, those requirements are set
+ * on the SSLSocket, otherwise both are set to false.
+ * @since 1.6
+ */
+ public void setSSLParameters(SSLParameters p) {
+ String[] cipherSuites = p.getCipherSuites();
+ if (cipherSuites != null) {
+ setEnabledCipherSuites(cipherSuites);
+ }
+ String[] protocols = p.getProtocols();
+ if (protocols != null) {
+ setEnabledProtocols(protocols);
+ }
+ if (p.getNeedClientAuth()) {
+ setNeedClientAuth(true);
+ } else if (p.getWantClientAuth()) {
+ setWantClientAuth(true);
+ } else {
+ setWantClientAuth(false);
+ }
+ }
}
diff --git a/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java b/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java
index b75c218..b31d4e2 100644
--- a/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java
+++ b/luni/src/main/java/javax/net/ssl/SSLSocketFactory.java
@@ -20,13 +20,11 @@ package javax.net.ssl;
import java.io.IOException;
import java.net.Socket;
import java.security.AccessController;
+import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.security.Security;
-// BEGIN android-added
import java.util.logging.Level;
import java.util.logging.Logger;
-// END android-added
-
import javax.net.SocketFactory;
/**
@@ -77,8 +75,12 @@ public abstract class SSLSocketFactory extends SocketFactory {
}
if (defaultSocketFactory == null) {
- // Try to find in providers
- SSLContext context = DefaultSSLContext.getContext();
+ SSLContext context;
+ try {
+ context = SSLContext.getDefault();
+ } catch (NoSuchAlgorithmException e) {
+ context = null;
+ }
if (context != null) {
defaultSocketFactory = context.getSocketFactory();
}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CipherSuite.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CipherSuite.java
index a6c2e4c..f6eef42 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CipherSuite.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/CipherSuite.java
@@ -171,11 +171,11 @@ public class CipherSuite {
CODE_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA);
static final CipherSuite TLS_DH_DSS_WITH_DES_CBC_SHA = new CipherSuite(
- "TLS_DH_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
+ "SSL_DH_DSS_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
"DES_CBC", "SHA", CODE_TLS_DH_DSS_WITH_DES_CBC_SHA);
static final CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
+ "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_DSS,
"3DES_EDE_CBC", "SHA", CODE_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA);
static final CipherSuite TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
@@ -184,11 +184,11 @@ public class CipherSuite {
CODE_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA);
static final CipherSuite TLS_DH_RSA_WITH_DES_CBC_SHA = new CipherSuite(
- "TLS_DH_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
+ "SSL_DH_RSA_WITH_DES_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
"DES_CBC", "SHA", CODE_TLS_DH_RSA_WITH_DES_CBC_SHA);
static final CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = new CipherSuite(
- "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
+ "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", false, KEY_EXCHANGE_DH_RSA,
"3DES_EDE_CBC", "SHA", CODE_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA);
static final CipherSuite TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = new CipherSuite(
@@ -296,6 +296,9 @@ public class CipherSuite {
int count = 0;
SUITES_BY_NAME = new Hashtable<String, CipherSuite>();
for (int i = 0; i < SUITES_BY_CODE.length; i++) {
+ if (SUITES_BY_CODE[i] == TLS_NULL_WITH_NULL_NULL) {
+ continue;
+ }
SUITES_BY_NAME.put(SUITES_BY_CODE[i].getName(), SUITES_BY_CODE[i]);
if (SUITES_BY_CODE[i].supported) {
count++;
@@ -305,6 +308,9 @@ public class CipherSuite {
SUPPORTED_CIPHER_SUITE_NAMES = new String[count];
count = 0;
for (int i = 0; i < SUITES_BY_CODE.length; i++) {
+ if (SUITES_BY_CODE[i] == TLS_NULL_WITH_NULL_NULL) {
+ continue;
+ }
if (SUITES_BY_CODE[i].supported) {
SUPPORTED_CIPHER_SUITES[count] = SUITES_BY_CODE[i];
SUPPORTED_CIPHER_SUITE_NAMES[count] = SUPPORTED_CIPHER_SUITES[count].getName();
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java
index 0b297a3..97ededd 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientSessionContext.java
@@ -44,7 +44,12 @@ public class ClientSessionContext extends AbstractSessionContext {
}
protected void sessionRemoved(SSLSession session) {
- HostAndPort hostAndPortKey = new HostAndPort(session);
+ String host = session.getPeerHost();
+ int port = session.getPeerPort();
+ if (host == null) {
+ return;
+ }
+ HostAndPort hostAndPortKey = new HostAndPort(host, port);
synchronized (sessionsByHostAndPort) {
sessionsByHostAndPort.remove(hostAndPortKey);
}
@@ -58,6 +63,9 @@ public class ClientSessionContext extends AbstractSessionContext {
* @return cached session or null if none found
*/
public SSLSession getSession(String host, int port) {
+ if (host == null) {
+ return null;
+ }
SSLSession session;
HostAndPort hostAndPortKey = new HostAndPort(host, port);
synchronized (sessionsByHostAndPort) {
@@ -89,7 +97,13 @@ public class ClientSessionContext extends AbstractSessionContext {
void putSession(SSLSession session) {
super.putSession(session);
- HostAndPort hostAndPortKey = new HostAndPort(session);
+ String host = session.getPeerHost();
+ int port = session.getPeerPort();
+ if (host == null) {
+ return;
+ }
+
+ HostAndPort hostAndPortKey = new HostAndPort(host, port);
synchronized (sessionsByHostAndPort) {
sessionsByHostAndPort.put(hostAndPortKey, session);
}
@@ -107,10 +121,6 @@ public class ClientSessionContext extends AbstractSessionContext {
final String host;
final int port;
- HostAndPort(SSLSession session) {
- this(session.getPeerHost(), session.getPeerPort());
- }
-
HostAndPort(String host, int port) {
this.host = host;
this.port = port;
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/DefaultSSLContextImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/DefaultSSLContextImpl.java
new file mode 100644
index 0000000..609a448
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/DefaultSSLContextImpl.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.security.Security;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+
+/**
+ * Support class for this package.
+ */
+public final class DefaultSSLContextImpl extends SSLContextImpl {
+
+ /**
+ * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
+ * DefaultSSLContextImpl.class monitor
+ */
+ private static KeyManager[] KEY_MANAGERS;
+
+ /**
+ * Accessed by SSLContextImpl(DefaultSSLContextImpl) holding the
+ * DefaultSSLContextImpl.class monitor
+ */
+ private static TrustManager[] TRUST_MANAGERS;
+
+ /**
+ * DefaultSSLContextImpl delegates the work to the super class
+ * since there is no way to put a synchronized around both the
+ * call to super and the rest of this constructor to guarantee
+ * that we don't have races in creating the state shared between
+ * all default SSLContexts.
+ */
+ public DefaultSSLContextImpl() throws GeneralSecurityException, IOException {
+ super(null);
+ }
+
+ // TODO javax.net.ssl.keyStoreProvider system property
+ KeyManager[] getKeyManagers () throws GeneralSecurityException, IOException {
+ if (KEY_MANAGERS != null) {
+ return KEY_MANAGERS;
+ }
+ // find KeyStore, KeyManagers
+ String keystore = System.getProperty("javax.net.ssl.keyStore");
+ if (keystore == null) {
+ return null;
+ }
+ String keystorepwd = System.getProperty("javax.net.ssl.keyStorePassword");
+ char[] pwd = (keystorepwd == null) ? null : keystorepwd.toCharArray();
+
+ KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ InputStream is = null;
+ try {
+ is = new BufferedInputStream(new FileInputStream(keystore));
+ ks.load(is, pwd);
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+
+ String kmfAlg = Security.getProperty("ssl.KeyManagerFactory.algorithm");
+ if (kmfAlg == null) {
+ kmfAlg = "SunX509";
+ }
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlg);
+ kmf.init(ks, pwd);
+ KEY_MANAGERS = kmf.getKeyManagers();
+ return KEY_MANAGERS;
+ }
+
+ // TODO javax.net.ssl.trustStoreProvider system property
+ TrustManager[] getTrustManagers() throws GeneralSecurityException, IOException {
+ if (TRUST_MANAGERS != null) {
+ return TRUST_MANAGERS;
+ }
+
+ // find TrustStore, TrustManagers
+ String keystore = System.getProperty("javax.net.ssl.trustStore");
+ if (keystore == null) {
+ return null;
+ }
+ String keystorepwd = System.getProperty("javax.net.ssl.trustStorePassword");
+ char[] pwd = (keystorepwd == null) ? null : keystorepwd.toCharArray();
+
+ // TODO Defaults: jssecacerts; cacerts
+ KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ InputStream is = null;
+ try {
+ is = new BufferedInputStream(new FileInputStream(keystore));
+ ks.load(is, pwd);
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ String tmfAlg = Security.getProperty("ssl.TrustManagerFactory.algorithm");
+ if (tmfAlg == null) {
+ tmfAlg = "PKIX";
+ }
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlg);
+ tmf.init(ks);
+ TRUST_MANAGERS = tmf.getTrustManagers();
+ return TRUST_MANAGERS;
+ }
+
+ @Override
+ public void engineInit(KeyManager[] kms, TrustManager[] tms,
+ SecureRandom sr) throws KeyManagementException {
+ throw new KeyManagementException("Do not init() the default SSLContext ");
+ }
+}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/HandshakeProtocol.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/HandshakeProtocol.java
index 94b18ce..283deb6 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/HandshakeProtocol.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/HandshakeProtocol.java
@@ -388,7 +388,9 @@ public abstract class HandshakeProtocol {
md5 = MessageDigest.getInstance("MD5");
sha = MessageDigest.getInstance("SHA-1");
} catch (Exception e) {
- fatalAlert(AlertProtocol.INTERNAL_ERROR, "Could not initialize the Digest Algorithms.", e);
+ fatalAlert(AlertProtocol.INTERNAL_ERROR,
+ "Could not initialize the Digest Algorithms.",
+ e);
return;
}
try {
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
index 6d50756..cb7d6c9 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
@@ -115,6 +115,7 @@ public final class JSSEProvider extends Provider {
put("KeyManagerFactory.X509", KeyManagerFactoryImpl.class.getName());
put("TrustManagerFactory.X509", TrustManagerFactoryImpl.class.getName());
// BEGIN android-added
+ put("SSLContext.Default", DefaultSSLContextImpl.class.getName());
put("SSLContext.SSL", SSLContextImpl.class.getName());
put("Alg.Alias.SSLContext.SSLv3", "SSL");
put("MessageDigest.SHA-1", "org.apache.harmony.xnet.provider.jsse.OpenSSLMessageDigestJDK$SHA1");
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
index 75ca8ea..7e6723e 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
@@ -256,7 +256,7 @@ public class NativeCrypto {
public static native int SSL_new(int ssl_ctx) throws IOException;
- public static final String[] KEY_TYPES = new String[] { "RSA", "DSA", "DH" };
+ public static final String[] KEY_TYPES = new String[] { "RSA", "DSA", "DH_RSA" , "DH_DSA" };
public static native void SSL_use_certificate(int ssl, byte[] pemEncodedCertificate);
@@ -280,25 +280,13 @@ public class NativeCrypto {
return new String[] { SUPPORTED_PROTOCOL_SSLV3, SUPPORTED_PROTOCOL_TLSV1 };
}
- public static String[] getEnabledProtocols(int ssl) {
- long options = SSL_get_options(ssl);
- ArrayList<String> array = new ArrayList<String>();
- if ((options & NativeCrypto.SSL_OP_NO_SSLv3) == 0) {
- array.add(SUPPORTED_PROTOCOL_SSLV3);
- }
- if ((options & NativeCrypto.SSL_OP_NO_TLSv1) == 0) {
- array.add(SUPPORTED_PROTOCOL_TLSV1);
- }
- return array.toArray(new String[array.size()]);
- }
-
public static void setEnabledProtocols(int ssl, String[] protocols) {
if (protocols == null) {
throw new IllegalArgumentException("protocols == null");
}
// openssl uses negative logic letting you disable protocols.
- // so first, assume we need to set all (disable all ) and clear none (enable none).
+ // so first, assume we need to set all (disable all) and clear none (enable none).
// in the loop, selectively move bits from set to clear (from disable to enable)
long optionsToSet = (SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
long optionsToClear = 0;
@@ -325,7 +313,7 @@ public class NativeCrypto {
public static String[] checkEnabledProtocols(String[] protocols) {
if (protocols == null) {
- throw new IllegalArgumentException("protocols parameter is null");
+ throw new IllegalArgumentException("protocols == null");
}
for (int i = 0; i < protocols.length; i++) {
String protocol = protocols[i];
@@ -333,7 +321,7 @@ public class NativeCrypto {
throw new IllegalArgumentException("protocols[" + i + "] == null");
}
if ((!protocol.equals(SUPPORTED_PROTOCOL_SSLV3))
- && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1))) {
+ && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1))) {
throw new IllegalArgumentException("protocol " + protocol +
" is not supported");
}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketFactoryImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketFactoryImpl.java
index f342457..f2126ad 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketFactoryImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLServerSocketFactoryImpl.java
@@ -61,11 +61,17 @@ public class OpenSSLServerSocketFactoryImpl extends javax.net.ssl.SSLServerSocke
public ServerSocket createServerSocket(int port, int backlog)
throws IOException {
- return new OpenSSLServerSocketImpl(port, backlog, (SSLParameters) sslParameters.clone());
+ return new OpenSSLServerSocketImpl(port,
+ backlog,
+ (SSLParameters) sslParameters.clone());
}
- public ServerSocket createServerSocket(int port, int backlog,
- InetAddress iAddress) throws IOException {
- return new OpenSSLServerSocketImpl(port, backlog, iAddress, (SSLParameters) sslParameters.clone());
+ public ServerSocket createServerSocket(int port,
+ int backlog,
+ InetAddress iAddress) throws IOException {
+ return new OpenSSLServerSocketImpl(port,
+ backlog,
+ iAddress,
+ (SSLParameters) sslParameters.clone());
}
}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketFactoryImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketFactoryImpl.java
index 7b6d7c8..ed8861c 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketFactoryImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketFactoryImpl.java
@@ -66,19 +66,35 @@ public class OpenSSLSocketFactoryImpl extends javax.net.ssl.SSLSocketFactory {
public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
throws IOException, UnknownHostException {
- return new OpenSSLSocketImpl(host, port, localHost, localPort, (SSLParameters) sslParameters.clone());
+ return new OpenSSLSocketImpl(host,
+ port,
+ localHost,
+ localPort,
+ (SSLParameters) sslParameters.clone());
}
public Socket createSocket(InetAddress host, int port) throws IOException {
return new OpenSSLSocketImpl(host, port, (SSLParameters) sslParameters.clone());
}
- public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
+ public Socket createSocket(InetAddress address,
+ int port,
+ InetAddress localAddress,
+ int localPort)
throws IOException {
- return new OpenSSLSocketImpl(address, port, localAddress, localPort, (SSLParameters) sslParameters.clone());
+ return new OpenSSLSocketImpl(address,
+ port,
+ localAddress,
+ localPort,
+ (SSLParameters) sslParameters.clone());
}
- public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
- return new OpenSSLSocketImplWrapper(s, host, port, autoClose, (SSLParameters) sslParameters.clone());
+ public Socket createSocket(Socket s, String host, int port, boolean autoClose)
+ throws IOException {
+ return new OpenSSLSocketImplWrapper(s,
+ host,
+ port,
+ autoClose,
+ (SSLParameters) sslParameters.clone());
}
}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
index 61c1bdc..b23f50e 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
@@ -22,7 +22,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
-import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.security.PrivateKey;
@@ -122,8 +121,7 @@ public class OpenSSLSocketImpl
* @throws IOException if network fails
* @throws java.net.UnknownHostException host not defined
*/
- protected OpenSSLSocketImpl(String host, int port,
- SSLParameters sslParameters)
+ protected OpenSSLSocketImpl(String host, int port, SSLParameters sslParameters)
throws IOException {
super(host, port);
init(sslParameters);
@@ -135,8 +133,7 @@ public class OpenSSLSocketImpl
* @throws IOException if network fails
* @throws java.net.UnknownHostException host not defined
*/
- protected OpenSSLSocketImpl(InetAddress address, int port,
- SSLParameters sslParameters)
+ protected OpenSSLSocketImpl(InetAddress address, int port, SSLParameters sslParameters)
throws IOException {
super(address, port);
init(sslParameters);
@@ -149,8 +146,9 @@ public class OpenSSLSocketImpl
* @throws IOException if network fails
* @throws java.net.UnknownHostException host not defined
*/
- protected OpenSSLSocketImpl(String host, int port, InetAddress clientAddress,
- int clientPort, SSLParameters sslParameters)
+ protected OpenSSLSocketImpl(String host, int port,
+ InetAddress clientAddress, int clientPort,
+ SSLParameters sslParameters)
throws IOException {
super(host, port, clientAddress, clientPort);
init(sslParameters);
@@ -163,7 +161,8 @@ public class OpenSSLSocketImpl
* @throws java.net.UnknownHostException host not defined
*/
protected OpenSSLSocketImpl(InetAddress address, int port,
- InetAddress clientAddress, int clientPort, SSLParameters sslParameters)
+ InetAddress clientAddress, int clientPort,
+ SSLParameters sslParameters)
throws IOException {
super(address, port, clientAddress, clientPort);
init(sslParameters);
@@ -422,7 +421,7 @@ public class OpenSSLSocketImpl
wrappedHost, wrappedPort,
sessionContext);
}
- // putSession will be done later in handshakeCompleted() callback
+ // if not, putSession later in handshakeCompleted() callback
if (handshakeCompleted) {
sessionContext.putSession(sslSession);
}
@@ -437,7 +436,7 @@ public class OpenSSLSocketImpl
}
// END android-added
- // notifyHandshakeCompletedListeners will be done later in handshakeCompleted() callback
+ // if not, notifyHandshakeCompletedListeners later in handshakeCompleted() callback
if (handshakeCompleted) {
notifyHandshakeCompletedListeners();
}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java
index 81dc1a5..c67b151 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java
@@ -17,22 +17,19 @@
package org.apache.harmony.xnet.provider.jsse;
-import org.apache.harmony.xnet.provider.jsse.SSLEngineImpl;
-import org.apache.harmony.xnet.provider.jsse.SSLParameters;
-// BEGIN android-removed
-// import org.apache.harmony.xnet.provider.jsse.SSLServerSocketFactoryImpl;
-// END android-removed
-
+import java.io.IOException;
import java.security.KeyManagementException;
import java.security.SecureRandom;
-
+import java.security.GeneralSecurityException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContextSpi;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
+import org.apache.harmony.xnet.provider.jsse.SSLEngineImpl;
// BEGIN android-note
// Modified heavily during SSLSessionContext refactoring. Added support for
@@ -44,16 +41,46 @@ import javax.net.ssl.TrustManager;
*/
public class SSLContextImpl extends SSLContextSpi {
+ /**
+ * The default SSLContextImpl for use with SSLContext.getInstance("Default").
+ * Protected by the DefaultSSLContextImpl.class monitor.
+ */
+ private static DefaultSSLContextImpl DEFAULT_SSL_CONTEXT_IMPL;
+
/** Client session cache. */
- private final ClientSessionContext clientSessionContext = new ClientSessionContext();
+ private final ClientSessionContext clientSessionContext;
/** Server session cache. */
- private final ServerSessionContext serverSessionContext = new ServerSessionContext();
+ private final ServerSessionContext serverSessionContext;
protected SSLParameters sslParameters;
public SSLContextImpl() {
- super();
+ clientSessionContext = new ClientSessionContext();
+ serverSessionContext = new ServerSessionContext();
+ }
+ /**
+ * Constuctor for the DefaultSSLContextImpl.
+ * @param dummy is null, used to distinguish this case from the
+ * public SSLContextImpl() constructor.
+ */
+ protected SSLContextImpl(DefaultSSLContextImpl dummy)
+ throws GeneralSecurityException, IOException {
+ synchronized (DefaultSSLContextImpl.class) {
+ if (DEFAULT_SSL_CONTEXT_IMPL == null) {
+ clientSessionContext = new ClientSessionContext();
+ serverSessionContext = new ServerSessionContext();
+ DEFAULT_SSL_CONTEXT_IMPL = (DefaultSSLContextImpl)this;
+ } else {
+ clientSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetClientSessionContext();
+ serverSessionContext = DEFAULT_SSL_CONTEXT_IMPL.engineGetServerSessionContext();
+ }
+ sslParameters = new SSLParameters(DEFAULT_SSL_CONTEXT_IMPL.getKeyManagers(),
+ DEFAULT_SSL_CONTEXT_IMPL.getTrustManagers(),
+ null,
+ clientSessionContext,
+ serverSessionContext);
+ }
}
/**
@@ -88,7 +115,7 @@ public class SSLContextImpl extends SSLContextSpi {
public SSLSocketFactory engineGetSocketFactory() {
if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initiallized.");
+ throw new IllegalStateException("SSLContext is not initialized.");
}
return new OpenSSLSocketFactoryImpl(sslParameters);
}
@@ -96,7 +123,7 @@ public class SSLContextImpl extends SSLContextSpi {
@Override
public SSLServerSocketFactory engineGetServerSocketFactory() {
if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initiallized.");
+ throw new IllegalStateException("SSLContext is not initialized.");
}
return new OpenSSLServerSocketFactoryImpl(sslParameters);
}
@@ -104,18 +131,21 @@ public class SSLContextImpl extends SSLContextSpi {
@Override
public SSLEngine engineCreateSSLEngine(String host, int port) {
if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initiallized.");
+ throw new IllegalStateException("SSLContext is not initialized.");
}
- return new SSLEngineImpl(host, port,
- (SSLParameters) sslParameters.clone());
+ SSLParameters p = (SSLParameters) sslParameters.clone();
+ p.setUseClientMode(false);
+ return new SSLEngineImpl(host, port, p);
}
@Override
public SSLEngine engineCreateSSLEngine() {
if (sslParameters == null) {
- throw new IllegalStateException("SSLContext is not initiallized.");
+ throw new IllegalStateException("SSLContext is not initialized.");
}
- return new SSLEngineImpl((SSLParameters) sslParameters.clone());
+ SSLParameters p = (SSLParameters) sslParameters.clone();
+ p.setUseClientMode(false);
+ return new SSLEngineImpl(p);
}
@Override
@@ -127,4 +157,42 @@ public class SSLContextImpl extends SSLContextSpi {
public ClientSessionContext engineGetClientSessionContext() {
return clientSessionContext;
}
+
+ @Override
+ public javax.net.ssl.SSLParameters engineGetDefaultSSLParameters() {
+ return createSSLParameters(false);
+ }
+
+ @Override
+ public javax.net.ssl.SSLParameters engineGetSupportedSSLParameters() {
+ return createSSLParameters(true);
+ }
+
+ private SSLParameters createSSLParameters (boolean supported) {
+ try {
+ SSLSocket s = (SSLSocket) engineGetSocketFactory().createSocket();
+ javax.net.ssl.SSLParameters p = new javax.net.ssl.SSLParameters();
+ String[] cipherSuites;
+ String[] protocols;
+ if (supported) {
+ cipherSuites = s.getSupportedCipherSuites();
+ protocols = s.getSupportedProtocols();
+ } else {
+ cipherSuites = s.getEnabledCipherSuites();
+ protocols = s.getEnabledProtocols();
+ }
+ p.setCipherSuites(cipherSuites);
+ p.setProtocols(protocols);
+ p.setNeedClientAuth(s.getNeedClientAuth());
+ p.setWantClientAuth(s.getWantClientAuth());
+ return p;
+ } catch (IOException e) {
+ /*
+ * SSLContext.getDefaultSSLParameters specifies to throw
+ * UnsupportedOperationException if there is a problem getting the
+ * parameters
+ */
+ throw new UnsupportedOperationException("Could not access supported SSL parameters");
+ }
+ }
}
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLEngineImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLEngineImpl.java
index 4b2dd8d..f66b82f 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLEngineImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLEngineImpl.java
@@ -17,19 +17,19 @@
package org.apache.harmony.xnet.provider.jsse;
-import org.apache.harmony.xnet.provider.jsse.AlertException;
-import org.apache.harmony.xnet.provider.jsse.SSLSessionImpl;
-import org.apache.harmony.xnet.provider.jsse.SSLEngineDataStream;
import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException;
import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSession;
+import org.apache.harmony.xnet.provider.jsse.AlertException;
+import org.apache.harmony.xnet.provider.jsse.SSLEngineDataStream;
+import org.apache.harmony.xnet.provider.jsse.SSLSessionImpl;
/**
* Implementation of SSLEngine.
@@ -83,21 +83,11 @@ public class SSLEngineImpl extends SSLEngine {
// logger
private Logger.Stream logger = Logger.getStream("engine");
- /**
- * Ctor
- * @param sslParameters: SSLParameters
- */
protected SSLEngineImpl(SSLParameters sslParameters) {
super();
this.sslParameters = sslParameters;
}
- /**
- * Ctor
- * @param host: String
- * @param port: int
- * @param sslParameters: SSLParameters
- */
protected SSLEngineImpl(String host, int port, SSLParameters sslParameters) {
super(host, port);
this.sslParameters = sslParameters;
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java
index dd94ea9..02a1fe5 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLParameters.java
@@ -25,19 +25,13 @@ import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLException;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
-import org.apache.harmony.security.provider.cert.X509CertImpl;
-
/**
* The instances of this class incapsulate all the info
* about enabled cipher suites and protocols,
@@ -46,9 +40,7 @@ import org.apache.harmony.security.provider.cert.X509CertImpl;
* and controls whether new SSL sessions may be established by this
* socket or not.
*/
-// BEGIN android-changed
public class SSLParameters implements Cloneable {
-// END android-changed
// default source of authentication keys
private static X509KeyManager defaultKeyManager;
@@ -221,8 +213,11 @@ public class SSLParameters implements Cloneable {
protected static SSLParameters getDefault() throws KeyManagementException {
if (defaultParameters == null) {
// BEGIN android-changed
- defaultParameters = new SSLParameters(null, null, null,
- new ClientSessionContext(), new ServerSessionContext());
+ defaultParameters = new SSLParameters(null,
+ null,
+ null,
+ new ClientSessionContext(),
+ new ServerSessionContext());
// END android-changed
}
return (SSLParameters) defaultParameters.clone();
@@ -310,14 +305,17 @@ public class SSLParameters implements Cloneable {
*/
protected void setEnabledCipherSuites(String[] suites) {
if (suites == null) {
- throw new IllegalArgumentException("Provided parameter is null");
+ throw new IllegalArgumentException("suites == null");
}
CipherSuite[] cipherSuites = new CipherSuite[suites.length];
for (int i=0; i<suites.length; i++) {
- cipherSuites[i] = CipherSuite.getByName(suites[i]);
+ String suite = suites[i];
+ if (suite == null) {
+ throw new IllegalArgumentException("suites[" + i + "] == null");
+ }
+ cipherSuites[i] = CipherSuite.getByName(suite);
if (cipherSuites[i] == null || !cipherSuites[i].supported) {
- throw new IllegalArgumentException(suites[i] +
- " is not supported.");
+ throw new IllegalArgumentException(suite + " is not supported.");
}
}
enabledCipherSuites = cipherSuites;
@@ -337,12 +335,15 @@ public class SSLParameters implements Cloneable {
*/
protected void setEnabledProtocols(String[] protocols) {
if (protocols == null) {
- throw new IllegalArgumentException("Provided parameter is null");
+ throw new IllegalArgumentException("protocols == null");
}
for (int i=0; i<protocols.length; i++) {
- if (!ProtocolVersion.isSupported(protocols[i])) {
- throw new IllegalArgumentException("Protocol " + protocols[i] +
- " is not supported.");
+ String protocol = protocols[i];
+ if (protocol == null) {
+ throw new IllegalArgumentException("protocols[" + i + "] == null");
+ }
+ if (!ProtocolVersion.isSupported(protocol)) {
+ throw new IllegalArgumentException("Protocol " + protocol + " is not supported.");
}
}
enabledProtocols = protocols;
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java
index 0352ef6..cb21be4 100644
--- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java
+++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerSessionContext.java
@@ -46,8 +46,7 @@ public class ServerSessionContext extends AbstractSessionContext {
protected void sessionRemoved(SSLSession session) {}
@Override
- public SSLSession getSession(byte[] sessionId)
- {
+ public SSLSession getSession(byte[] sessionId) {
SSLSession session = super.getSession(sessionId);
if (session != null) {
return session;
diff --git a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
index 21489a2..b91c8e6 100644
--- a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
+++ b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
@@ -1421,6 +1421,11 @@ static void info_callback(const SSL *ssl, int where, int ret __attribute__ ((unu
JNI_TRACE("ssl=%p info_callback env error", ssl);
return;
}
+ if (env->ExceptionCheck()) {
+ JNI_TRACE("ssl=%p info_callback already pending exception", ssl);
+ return;
+ }
+
jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
diff --git a/luni/src/test/java/javax/net/ssl/AllTests.java b/luni/src/test/java/javax/net/ssl/AllTests.java
index 740b788..7638404 100644
--- a/luni/src/test/java/javax/net/ssl/AllTests.java
+++ b/luni/src/test/java/javax/net/ssl/AllTests.java
@@ -22,9 +22,11 @@ import junit.framework.TestSuite;
public class AllTests {
public static final Test suite() {
TestSuite suite = new TestSuite();
- suite.addTestSuite(SSLSocketFactoryTest.class);
+ suite.addTestSuite(SSLParametersTest.class);
suite.addTestSuite(SSLContextTest.class);
+ suite.addTestSuite(SSLSocketFactoryTest.class);
suite.addTestSuite(SSLSocketTest.class);
+ suite.addTestSuite(SSLEngineTest.class);
suite.addTestSuite(SSLSessionTest.class);
suite.addTestSuite(SSLSessionContextTest.class);
return suite;
diff --git a/luni/src/test/java/javax/net/ssl/SSLContextTest.java b/luni/src/test/java/javax/net/ssl/SSLContextTest.java
index df4d556..f68b21f 100644
--- a/luni/src/test/java/javax/net/ssl/SSLContextTest.java
+++ b/luni/src/test/java/javax/net/ssl/SSLContextTest.java
@@ -16,6 +16,7 @@
package javax.net.ssl;
+import java.security.KeyManagementException;
import java.security.Provider;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
@@ -23,19 +24,45 @@ import junit.framework.TestCase;
public class SSLContextTest extends TestCase {
+ public void test_SSLContext_getDefault() throws Exception {
+ SSLContext sslContext = SSLContext.getDefault();
+ assertNotNull(sslContext);
+ try {
+ sslContext.init(null, null, null);
+ } catch (KeyManagementException expected) {
+ }
+ }
+
+ public void test_SSLContext_setDefault() throws Exception {
+ try {
+ SSLContext.setDefault(null);
+ } catch (NullPointerException expected) {
+ }
+
+ SSLContext defaultContext = SSLContext.getDefault();
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ SSLContext oldContext = SSLContext.getDefault();
+ assertNotNull(oldContext);
+ SSLContext newContext = SSLContext.getInstance(protocol);
+ assertNotNull(newContext);
+ assertNotSame(oldContext, newContext);
+ SSLContext.setDefault(newContext);
+ assertSame(newContext, SSLContext.getDefault());
+ }
+ SSLContext.setDefault(defaultContext);
+ }
+
public void test_SSLContext_getInstance() throws Exception {
try {
SSLContext.getInstance(null);
fail();
} catch (NullPointerException expected) {
}
- assertNotNull(SSLContext.getInstance("SSL"));
- assertNotNull(SSLContext.getInstance("SSLv3"));
- assertNotNull(SSLContext.getInstance("TLS"));
- assertNotNull(SSLContext.getInstance("TLSv1"));
-
- assertNotSame(SSLContext.getInstance("TLS"),
- SSLContext.getInstance("TLS"));
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ assertNotNull(SSLContext.getInstance(protocol));
+ assertNotSame(SSLContext.getInstance(protocol),
+ SSLContext.getInstance(protocol));
+ }
try {
SSLContext.getInstance(null, (String) null);
@@ -47,10 +74,12 @@ public class SSLContextTest extends TestCase {
fail();
} catch (IllegalArgumentException expected) {
}
- try {
- SSLContext.getInstance("TLS", (String) null);
- fail();
- } catch (IllegalArgumentException expected) {
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ try {
+ SSLContext.getInstance(protocol, (String) null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
}
try {
SSLContext.getInstance(null, TestSSLContext.PROVIDER_NAME);
@@ -60,98 +89,197 @@ public class SSLContextTest extends TestCase {
}
public void test_SSLContext_getProtocol() throws Exception {
- assertProtocolExistsForName("SSL");
- assertProtocolExistsForName("TLS");
- }
-
- private void assertProtocolExistsForName(String protocolName) throws Exception {
- String protocol = SSLContext.getInstance(protocolName).getProtocol();
- assertNotNull(protocol);
- assertEquals(protocolName, protocol);
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ String protocolName = SSLContext.getInstance(protocol).getProtocol();
+ assertNotNull(protocolName);
+ assertTrue(protocol.startsWith(protocolName));
+ }
}
public void test_SSLContext_getProvider() throws Exception {
- Provider provider = SSLContext.getInstance("TLS").getProvider();
+ Provider provider = SSLContext.getDefault().getProvider();
assertNotNull(provider);
assertEquals(TestSSLContext.PROVIDER_NAME, provider.getName());
}
public void test_SSLContext_init() throws Exception {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, null, null);
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ try {
+ sslContext.init(null, null, null);
+ } catch (KeyManagementException expected) {
+ }
+ } else {
+ sslContext.init(null, null, null);
+ }
+ }
}
public void test_SSLContext_getSocketFactory() throws Exception {
- try {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.getSocketFactory();
- fail();
- } catch (IllegalStateException expected) {
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ SSLContext.getInstance(protocol).getSocketFactory();
+ } else {
+ try {
+ SSLContext.getInstance(protocol).getSocketFactory();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ sslContext.init(null, null, null);
+ }
+ SocketFactory sf = sslContext.getSocketFactory();
+ assertNotNull(sf);
+ assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
}
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, null, null);
- SocketFactory sf = sslContext.getSocketFactory();
- assertNotNull(sf);
- assertTrue(SSLSocketFactory.class.isAssignableFrom(sf.getClass()));
}
public void test_SSLContext_getServerSocketFactory() throws Exception {
- try {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.getServerSocketFactory();
- fail();
- } catch (IllegalStateException expected) {
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ SSLContext.getInstance(protocol).getServerSocketFactory();
+ } else {
+ try {
+ SSLContext.getInstance(protocol).getServerSocketFactory();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ sslContext.init(null, null, null);
+ }
+ ServerSocketFactory ssf = sslContext.getServerSocketFactory();
+ assertNotNull(ssf);
+ assertTrue(SSLServerSocketFactory.class.isAssignableFrom(ssf.getClass()));
}
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, null, null);
- ServerSocketFactory ssf = sslContext.getServerSocketFactory();
- assertNotNull(ssf);
- assertTrue(SSLServerSocketFactory.class.isAssignableFrom(ssf.getClass()));
}
public void test_SSLContext_createSSLEngine() throws Exception {
- try {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.createSSLEngine();
- fail();
- } catch (IllegalStateException expected) {
- }
- try {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.createSSLEngine(null, -1);
- fail();
- } catch (IllegalStateException expected) {
- }
- {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, null, null);
- SSLEngine se = sslContext.createSSLEngine();
- assertNotNull(se);
- }
- {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, null, null);
- SSLEngine se = sslContext.createSSLEngine(null, -1);
- assertNotNull(se);
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+
+ if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ SSLContext.getInstance(protocol).createSSLEngine();
+ } else {
+ try {
+ SSLContext.getInstance(protocol).createSSLEngine();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ SSLContext.getInstance(protocol).createSSLEngine(null, -1);
+ } else {
+ try {
+ SSLContext.getInstance(protocol).createSSLEngine(null, -1);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ {
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ sslContext.init(null, null, null);
+ }
+ SSLEngine se = sslContext.createSSLEngine();
+ assertNotNull(se);
+ }
+
+ {
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ sslContext.init(null, null, null);
+ }
+ SSLEngine se = sslContext.createSSLEngine(null, -1);
+ assertNotNull(se);
+ }
}
}
public void test_SSLContext_getServerSessionContext() throws Exception {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- SSLSessionContext sessionContext = sslContext.getServerSessionContext();
- assertNotNull(sessionContext);
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ SSLSessionContext sessionContext = sslContext.getServerSessionContext();
+ assertNotNull(sessionContext);
- assertNotSame(SSLContext.getInstance("TLS").getServerSessionContext(),
- sessionContext);
+ if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ assertSame(SSLContext.getInstance(protocol).getServerSessionContext(),
+ sessionContext);
+ } else {
+ assertNotSame(SSLContext.getInstance(protocol).getServerSessionContext(),
+ sessionContext);
+ }
+ }
}
public void test_SSLContext_getClientSessionContext() throws Exception {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- SSLSessionContext sessionContext = sslContext.getClientSessionContext();
- assertNotNull(sessionContext);
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ SSLSessionContext sessionContext = sslContext.getClientSessionContext();
+ assertNotNull(sessionContext);
+
+ if (protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ assertSame(SSLContext.getInstance(protocol).getClientSessionContext(),
+ sessionContext);
+ } else {
+ assertNotSame(SSLContext.getInstance(protocol).getClientSessionContext(),
+ sessionContext);
+ }
+ }
+ }
+
+ public void test_SSLContext_getDefaultSSLParameters() throws Exception {
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ sslContext.init(null, null, null);
+ }
+
+ SSLParameters p = sslContext.getDefaultSSLParameters();
+ assertNotNull(p);
+
+ String[] cipherSuites = p.getCipherSuites();
+ assertNotNull(cipherSuites);
+ StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
+
+ String[] protocols = p.getProtocols();
+ assertNotNull(protocols);
+ StandardNames.assertValidCipherSuites(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
+
+ assertFalse(p.getWantClientAuth());
+ assertFalse(p.getNeedClientAuth());
+ }
+ }
+
+ public void test_SSLContext_getSupportedSSLParameters() throws Exception {
+ for (String protocol : StandardNames.SSL_CONTEXT_PROTOCOLS) {
+ SSLContext sslContext = SSLContext.getInstance(protocol);
+ if (!protocol.equals(StandardNames.SSL_CONTEXT_PROTOCOLS_DEFAULT)) {
+ sslContext.init(null, null, null);
+ }
+
+ SSLParameters p = sslContext.getSupportedSSLParameters();
+ assertNotNull(p);
- assertNotSame(SSLContext.getInstance("TLS").getClientSessionContext(),
- sessionContext);
+ String[] cipherSuites = p.getCipherSuites();
+ assertNotNull(cipherSuites);
+ StandardNames.assertSupportedCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
+
+ String[] protocols = p.getProtocols();
+ assertNotNull(protocols);
+ StandardNames.assertSupportedProtocols(StandardNames.SSL_SOCKET_PROTOCOLS,
+ protocols);
+
+ assertFalse(p.getWantClientAuth());
+ assertFalse(p.getNeedClientAuth());
+ }
}
public void test_SSLContextTest_TestSSLContext_create() {
diff --git a/luni/src/test/java/javax/net/ssl/SSLEngineTest.java b/luni/src/test/java/javax/net/ssl/SSLEngineTest.java
new file mode 100644
index 0000000..75f04a0
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLEngineTest.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.net.ssl;
+
+import dalvik.annotation.KnownFailure;
+import java.util.Arrays;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import junit.framework.TestCase;
+
+public class SSLEngineTest extends TestCase {
+
+ public void assertConnected(TestSSLEnginePair e) {
+ assertConnected(e.client, e.server);
+ }
+
+ public void assertNotConnected(TestSSLEnginePair e) {
+ assertNotConnected(e.client, e.server);
+ }
+
+ public void assertConnected(SSLEngine a, SSLEngine b) {
+ assertTrue(connected(a, b));
+ }
+
+ public void assertNotConnected(SSLEngine a, SSLEngine b) {
+ assertFalse(connected(a, b));
+ }
+
+ public boolean connected(SSLEngine a, SSLEngine b) {
+ return (a.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
+ && b.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING
+ && a.getSession() != null
+ && b.getSession() != null
+ && !a.isInboundDone()
+ && !b.isInboundDone()
+ && !a.isOutboundDone()
+ && !b.isOutboundDone());
+ }
+
+ public void test_SSLEngine_getSupportedCipherSuites_names() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.sslContext.createSSLEngine();
+ String[] cipherSuites = e.getSupportedCipherSuites();
+ StandardNames.assertSupportedCipherSuites(StandardNames.CIPHER_SUITES_SSLENGINE,
+ cipherSuites);
+ assertNotSame(cipherSuites, e.getSupportedCipherSuites());
+ }
+
+ @KnownFailure("No *_WITH_NULL_* ciphers work because of 'Invalid transformation: null'")
+ public void test_SSLEngine_getSupportedCipherSuites_connect() throws Exception {
+ String[] cipherSuites
+ = SSLContext.getDefault().createSSLEngine().getSupportedCipherSuites();
+ for (String cipherSuite : cipherSuites) {
+ /*
+ * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
+ * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#KRBRequire
+ */
+ if (cipherSuite.startsWith("TLS_KRB5_")) {
+ continue;
+ }
+ System.out.println("Trying to connect cipher suite " + cipherSuite);
+ final String[] cipherSuiteArray = new String[] { cipherSuite };
+ assertConnected(TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
+ @Override
+ void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+ client.setEnabledCipherSuites(cipherSuiteArray);
+ server.setEnabledCipherSuites(cipherSuiteArray);
+ }
+ }));
+ }
+ }
+
+ public void test_SSLEngine_getEnabledCipherSuites() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.sslContext.createSSLEngine();
+ String[] cipherSuites = e.getEnabledCipherSuites();
+ StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES_SSLENGINE,
+ cipherSuites);
+ assertNotSame(cipherSuites, e.getEnabledCipherSuites());
+ }
+
+ public void test_SSLEngine_setEnabledCipherSuites() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.sslContext.createSSLEngine();
+
+ try {
+ e.setEnabledCipherSuites(null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ e.setEnabledCipherSuites(new String[1]);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ e.setEnabledCipherSuites(new String[] { "Bogus" } );
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ e.setEnabledCipherSuites(new String[0]);
+ e.setEnabledCipherSuites(e.getEnabledCipherSuites());
+ e.setEnabledCipherSuites(e.getSupportedCipherSuites());
+ }
+
+ public void test_SSLEngine_getSupportedProtocols() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.sslContext.createSSLEngine();
+ String[] protocols = e.getSupportedProtocols();
+ StandardNames.assertSupportedProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
+ assertNotSame(protocols, e.getSupportedProtocols());
+ }
+
+ public void test_SSLEngine_getEnabledProtocols() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.sslContext.createSSLEngine();
+ String[] protocols = e.getEnabledProtocols();
+ StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
+ assertNotSame(protocols, e.getEnabledProtocols());
+ }
+
+ public void test_SSLEngine_setEnabledProtocols() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.sslContext.createSSLEngine();
+
+ try {
+ e.setEnabledProtocols(null);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ e.setEnabledProtocols(new String[1]);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ try {
+ e.setEnabledProtocols(new String[] { "Bogus" } );
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ e.setEnabledProtocols(new String[0]);
+ e.setEnabledProtocols(e.getEnabledProtocols());
+ e.setEnabledProtocols(e.getSupportedProtocols());
+ }
+
+ public void test_SSLEngine_getSession() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.sslContext.createSSLEngine();
+ SSLSession session = e.getSession();
+ assertNotNull(session);
+ assertFalse(session.isValid());
+ }
+
+ public void test_SSLEngine_beginHandshake() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+
+ try {
+ c.sslContext.createSSLEngine().beginHandshake();
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+
+ assertConnected(TestSSLEnginePair.create(null));
+ }
+
+ @KnownFailure("NO SERVER CERTIFICATE FOUND")
+ public void test_SSLEngine_beginHandshake_noKeyStore() throws Exception {
+ TestSSLContext c = TestSSLContext.create(null, null);
+ try {
+ // TODO Fix KnownFailure AlertException "NO SERVER CERTIFICATE FOUND"
+ // ServerHandshakeImpl.selectSuite should not select a suite without a required cert
+ TestSSLEnginePair.connect(c, c, null);
+ fail();
+ } catch (SSLHandshakeException expected) {
+ }
+ }
+
+ public void test_SSLEngine_beginHandshake_noClientCertificate() throws Exception {
+ TestSSLContext serverContext = TestSSLContext.create();
+ TestSSLContext clientContext = TestSSLContext.createClient(serverContext);
+ SSLEngine[] engines = TestSSLEnginePair.connect(clientContext, serverContext, null);
+ assertConnected(engines[0], engines[1]);
+ }
+
+ public void test_SSLEngine_getUseClientMode() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ assertFalse(c.sslContext.createSSLEngine().getUseClientMode());
+ assertFalse(c.sslContext.createSSLEngine(null, -1).getUseClientMode());
+ }
+
+ @KnownFailure("SSLHandshakeException instead assertNotConnected")
+ public void test_SSLEngine_setUseClientMode() throws Exception {
+ // client is client, server is server
+ assertConnected(test_SSLEngine_setUseClientMode(true, false));
+
+ // client is server, server is client
+ assertConnected(test_SSLEngine_setUseClientMode(false, true));
+
+ // both are client
+ assertNotConnected(test_SSLEngine_setUseClientMode(true, true));
+
+ // both are server
+ assertNotConnected(test_SSLEngine_setUseClientMode(false, false));
+ }
+
+ private TestSSLEnginePair test_SSLEngine_setUseClientMode(final boolean clientClientMode,
+ final boolean serverClientMode)
+ throws Exception {
+ return TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
+ @Override
+ void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+ client.setUseClientMode(clientClientMode);
+ server.setUseClientMode(serverClientMode);
+ }
+ });
+ }
+
+ @KnownFailure("init - invalid private key")
+ public void test_SSLEngine_clientAuth() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.sslContext.createSSLEngine();
+
+ assertFalse(e.getWantClientAuth());
+ assertFalse(e.getNeedClientAuth());
+
+ // confirm turning one on by itself
+ e.setWantClientAuth(true);
+ assertTrue(e.getWantClientAuth());
+ assertFalse(e.getNeedClientAuth());
+
+ // confirm turning setting on toggles the other
+ e.setNeedClientAuth(true);
+ assertFalse(e.getWantClientAuth());
+ assertTrue(e.getNeedClientAuth());
+
+ // confirm toggling back
+ e.setWantClientAuth(true);
+ assertTrue(e.getWantClientAuth());
+ assertFalse(e.getNeedClientAuth());
+
+ // TODO Fix KnownFailure "init - invalid private key"
+ TestSSLEnginePair p = TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
+ @Override
+ void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+ server.setWantClientAuth(true);
+ }
+ });
+ assertConnected(p);
+ assertNotNull(p.client.getSession().getLocalCertificates());
+ assertEquals(1, p.client.getSession().getLocalCertificates().length);
+ }
+
+ public void test_SSLEngine_getEnableSessionCreation() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.sslContext.createSSLEngine();
+ assertTrue(e.getEnableSessionCreation());
+ }
+
+ @KnownFailure("SSLException instead assertNotConnected")
+ public void test_SSLEngine_setEnableSessionCreation_server() throws Exception {
+ TestSSLEnginePair p = TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
+ @Override
+ void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+ server.setEnableSessionCreation(false);
+ }
+ });
+ assertNotConnected(p);
+ }
+
+ @KnownFailure("AlertException instead of SSLException")
+ public void test_SSLEngine_setEnableSessionCreation_client() throws Exception {
+ try {
+ TestSSLEnginePair.create(new TestSSLEnginePair.Hooks() {
+ @Override
+ void beforeBeginHandshake(SSLEngine client, SSLEngine server) {
+ client.setEnableSessionCreation(false);
+ }
+ });
+ fail();
+ } catch (SSLException expected) {
+ }
+ }
+
+ public void test_SSLEngine_getSSLParameters() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.sslContext.createSSLEngine();
+
+ SSLParameters p = e.getSSLParameters();
+ assertNotNull(p);
+
+ String[] cipherSuites = p.getCipherSuites();
+ StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES_SSLENGINE,
+ cipherSuites);
+ assertNotSame(cipherSuites, e.getEnabledCipherSuites());
+ assertEquals(Arrays.asList(cipherSuites), Arrays.asList(e.getEnabledCipherSuites()));
+
+ String[] protocols = p.getProtocols();
+ StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
+ assertNotSame(protocols, e.getEnabledProtocols());
+ assertEquals(Arrays.asList(protocols), Arrays.asList(e.getEnabledProtocols()));
+
+ assertEquals(p.getWantClientAuth(), e.getWantClientAuth());
+ assertEquals(p.getNeedClientAuth(), e.getNeedClientAuth());
+ }
+
+ public void test_SSLEngine_setSSLParameters() throws Exception {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine e = c.sslContext.createSSLEngine();
+ String[] defaultCipherSuites = e.getEnabledCipherSuites();
+ String[] defaultProtocols = e.getEnabledProtocols();
+ String[] supportedCipherSuites = e.getSupportedCipherSuites();
+ String[] supportedProtocols = e.getSupportedProtocols();
+
+ {
+ SSLParameters p = new SSLParameters();
+ e.setSSLParameters(p);
+ assertEquals(Arrays.asList(defaultCipherSuites),
+ Arrays.asList(e.getEnabledCipherSuites()));
+ assertEquals(Arrays.asList(defaultProtocols),
+ Arrays.asList(e.getEnabledProtocols()));
+ }
+
+ {
+ SSLParameters p = new SSLParameters(supportedCipherSuites,
+ supportedProtocols);
+ e.setSSLParameters(p);
+ assertEquals(Arrays.asList(supportedCipherSuites),
+ Arrays.asList(e.getEnabledCipherSuites()));
+ assertEquals(Arrays.asList(supportedProtocols),
+ Arrays.asList(e.getEnabledProtocols()));
+ }
+ {
+ SSLParameters p = new SSLParameters();
+
+ p.setNeedClientAuth(true);
+ assertFalse(e.getNeedClientAuth());
+ assertFalse(e.getWantClientAuth());
+ e.setSSLParameters(p);
+ assertTrue(e.getNeedClientAuth());
+ assertFalse(e.getWantClientAuth());
+
+ p.setWantClientAuth(true);
+ assertTrue(e.getNeedClientAuth());
+ assertFalse(e.getWantClientAuth());
+ e.setSSLParameters(p);
+ assertFalse(e.getNeedClientAuth());
+ assertTrue(e.getWantClientAuth());
+
+ p.setWantClientAuth(false);
+ assertFalse(e.getNeedClientAuth());
+ assertTrue(e.getWantClientAuth());
+ e.setSSLParameters(p);
+ assertFalse(e.getNeedClientAuth());
+ assertFalse(e.getWantClientAuth());
+ }
+ }
+
+ public void test_TestSSLEnginePair_create() throws Exception {
+ TestSSLEnginePair test = TestSSLEnginePair.create(null);
+ assertNotNull(test.c);
+ assertNotNull(test.server);
+ assertNotNull(test.client);
+ assertConnected(test);
+ }
+}
diff --git a/luni/src/test/java/javax/net/ssl/SSLParametersTest.java b/luni/src/test/java/javax/net/ssl/SSLParametersTest.java
new file mode 100644
index 0000000..7259ba5
--- /dev/null
+++ b/luni/src/test/java/javax/net/ssl/SSLParametersTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.net.ssl;
+
+import java.util.Arrays;
+import junit.framework.TestCase;
+
+public class SSLParametersTest extends TestCase {
+
+ public void test_SSLParameters_emptyConstructor() {
+ SSLParameters p = new SSLParameters();
+ assertNull(p.getCipherSuites());
+ assertNull(p.getProtocols());
+ assertFalse(p.getWantClientAuth());
+ assertFalse(p.getNeedClientAuth());
+ }
+
+ public void test_SSLParameters_cipherSuitesConstructor() {
+ String[] cipherSuites = new String[] { "foo", null, "bar" };
+ SSLParameters p = new SSLParameters(cipherSuites);
+ assertNotNull(p.getCipherSuites());
+ assertNotSame(cipherSuites, p.getCipherSuites());
+ assertEquals(Arrays.asList(cipherSuites), Arrays.asList(p.getCipherSuites()));
+ assertNull(p.getProtocols());
+ assertFalse(p.getWantClientAuth());
+ assertFalse(p.getNeedClientAuth());
+ }
+
+ public void test_SSLParameters_cpherSuitesProtocolsConstructor() {
+ String[] cipherSuites = new String[] { "foo", null, "bar" };
+ String[] protocols = new String[] { "baz", null, "qux" };
+ SSLParameters p = new SSLParameters(cipherSuites, protocols);
+ assertNotNull(p.getCipherSuites());
+ assertNotNull(p.getProtocols());
+ assertNotSame(cipherSuites, p.getCipherSuites());
+ assertNotSame(protocols, p.getProtocols());
+ assertEquals(Arrays.asList(cipherSuites), Arrays.asList(p.getCipherSuites()));
+ assertEquals(Arrays.asList(protocols), Arrays.asList(p.getProtocols()));
+ assertFalse(p.getWantClientAuth());
+ assertFalse(p.getNeedClientAuth());
+ }
+
+ public void test_SSLParameters_CipherSuites() {
+ SSLParameters p = new SSLParameters();
+ assertNull(p.getCipherSuites());
+
+ // confirm clone on input
+ String[] cipherSuites = new String[] { "fnord" };
+ String[] copy = cipherSuites.clone();
+ p.setCipherSuites(copy);
+ copy[0] = null;
+ assertEquals(Arrays.asList(cipherSuites), Arrays.asList(p.getCipherSuites()));
+
+ // confirm clone on output
+ assertNotSame(p.getCipherSuites(), p.getCipherSuites());
+ }
+
+ public void test_SSLParameters_Protocols() {
+ SSLParameters p = new SSLParameters();
+ assertNull(p.getProtocols());
+
+ // confirm clone on input
+ String[] protocols = new String[] { "fnord" };
+ String[] copy = protocols.clone();
+ p.setProtocols(copy);
+ copy[0] = null;
+ assertEquals(Arrays.asList(protocols), Arrays.asList(p.getProtocols()));
+
+ // confirm clone on output
+ assertNotSame(p.getProtocols(), p.getProtocols());
+ }
+
+ public void test_SSLParameters_ClientAuth() {
+ SSLParameters p = new SSLParameters();
+ assertFalse(p.getWantClientAuth());
+ assertFalse(p.getNeedClientAuth());
+
+ // confirm turning one on by itself
+ p.setWantClientAuth(true);
+ assertTrue(p.getWantClientAuth());
+ assertFalse(p.getNeedClientAuth());
+
+ // confirm turning setting on toggles the other
+ p.setNeedClientAuth(true);
+ assertFalse(p.getWantClientAuth());
+ assertTrue(p.getNeedClientAuth());
+
+ // confirm toggling back
+ p.setWantClientAuth(true);
+ assertTrue(p.getWantClientAuth());
+ assertFalse(p.getNeedClientAuth());
+ }
+}
diff --git a/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java b/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java
index ffa9bc0..7e2cbd0 100644
--- a/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java
+++ b/luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java
@@ -21,7 +21,6 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
-import java.util.List;
import junit.framework.TestCase;
public class SSLSessionContextTest extends TestCase {
diff --git a/luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java b/luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java
index 6c7c99b..a91d07a 100644
--- a/luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java
+++ b/luni/src/test/java/javax/net/ssl/SSLSocketFactoryTest.java
@@ -16,14 +16,11 @@
package javax.net.ssl;
-import java.net.Socket;
-import java.net.SocketException;
-import java.net.ServerSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
-import java.util.Collections;
-import java.util.Set;
-import java.util.HashSet;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import junit.framework.TestCase;
@@ -38,43 +35,15 @@ public class SSLSocketFactoryTest extends TestCase {
public void test_SSLSocketFactory_getDefaultCipherSuites() {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
String[] cipherSuites = sf.getDefaultCipherSuites();
- assertNotNull(cipherSuites);
- assertTrue(cipherSuites.length != 0);
-
- // Make sure modifying the result is not observable
- String savedCipherSuite = cipherSuites[0];
- assertNotNull(savedCipherSuite);
- cipherSuites[0] = null;
- assertNotNull(sf.getSupportedCipherSuites()[0]);
- cipherSuites[0] = savedCipherSuite;
-
- // Make sure all cipherSuites names are expected
- for (String cipherSuite : cipherSuites) {
- assertTrue(StandardNames.CIPHER_SUITES.contains(cipherSuite));
- }
+ StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
+ assertNotSame(cipherSuites, sf.getDefaultCipherSuites());
}
public void test_SSLSocketFactory_getSupportedCipherSuites() {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
String[] cipherSuites = sf.getSupportedCipherSuites();
- assertNotNull(cipherSuites);
- assertTrue(cipherSuites.length != 0);
-
- // Make sure modifying the result is not observable
- String savedCipherSuite = cipherSuites[0];
- assertNotNull(savedCipherSuite);
- cipherSuites[0] = null;
- assertNotNull(sf.getSupportedCipherSuites()[0]);
- cipherSuites[0] = savedCipherSuite;
-
- // Make sure all cipherSuites names are expected
- Set remainingCipherSuites = new HashSet<String>(StandardNames.CIPHER_SUITES);
- for (String cipherSuite : cipherSuites) {
- assertTrue(remainingCipherSuites.remove(cipherSuite));
- }
- assertEquals(Collections.EMPTY_SET, remainingCipherSuites);
-
- assertEquals(StandardNames.CIPHER_SUITES.size(), cipherSuites.length);
+ StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
+ assertNotSame(cipherSuites, sf.getSupportedCipherSuites());
}
public void test_SSLSocketFactory_createSocket() throws Exception {
diff --git a/luni/src/test/java/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/javax/net/ssl/SSLSocketTest.java
index a83035c..fae21bf 100644
--- a/luni/src/test/java/javax/net/ssl/SSLSocketTest.java
+++ b/luni/src/test/java/javax/net/ssl/SSLSocketTest.java
@@ -16,19 +16,12 @@
package javax.net.ssl;
-import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
-import java.security.Key;
-import java.security.KeyStore;
import java.security.Principal;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
import junit.framework.TestCase;
public class SSLSocketTest extends TestCase {
@@ -37,25 +30,19 @@ public class SSLSocketTest extends TestCase {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
String[] cipherSuites = ssl.getSupportedCipherSuites();
- assertNotNull(cipherSuites);
- assertTrue(cipherSuites.length != 0);
- Set remainingCipherSuites = new HashSet<String>(StandardNames.CIPHER_SUITES);
- for (String cipherSuite : cipherSuites) {
- assertTrue(remainingCipherSuites.remove(cipherSuite));
- }
- assertEquals(Collections.EMPTY_SET, remainingCipherSuites);
- assertEquals(StandardNames.CIPHER_SUITES.size(), cipherSuites.length);
+ StandardNames.assertSupportedCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
+ assertNotSame(cipherSuites, ssl.getSupportedCipherSuites());
}
public void test_SSLSocket_getSupportedCipherSuites_connect() throws Exception {
TestSSLContext c = TestSSLContext.create();
String[] cipherSuites = c.sslContext.getSocketFactory().getSupportedCipherSuites();
for (String cipherSuite : cipherSuites) {
+ /*
+ * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
+ * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#KRBRequire
+ */
if (cipherSuite.startsWith("TLS_KRB5_")) {
- /*
- * Kerberos cipher suites require external setup. See "Kerberos Requirements" in
- * https://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#KRBRequire
- */
continue;
}
// System.out.println("Trying to connect cipher suite " + cipherSuite);
@@ -68,20 +55,8 @@ public class SSLSocketTest extends TestCase {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
String[] cipherSuites = ssl.getEnabledCipherSuites();
- assertNotNull(cipherSuites);
- assertTrue(cipherSuites.length != 0);
-
- // Make sure modifying the result is not observable
- String savedCipherSuite = cipherSuites[0];
- assertNotNull(savedCipherSuite);
- cipherSuites[0] = null;
- assertNotNull(ssl.getEnabledCipherSuites()[0]);
- cipherSuites[0] = savedCipherSuite;
-
- // Make sure all cipherSuites names are expected
- for (String cipherSuite : cipherSuites) {
- assertTrue(StandardNames.CIPHER_SUITES.contains(cipherSuite));
- }
+ StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
+ assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
}
public void test_SSLSocket_setEnabledCipherSuites() throws Exception {
@@ -113,40 +88,16 @@ public class SSLSocketTest extends TestCase {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
String[] protocols = ssl.getSupportedProtocols();
- assertNotNull(protocols);
- assertTrue(protocols.length != 0);
-
- // Make sure modifying the result is not observable
- String savedProtocol = protocols[0];
- assertNotNull(savedProtocol);
- protocols[0] = null;
- assertNotNull(ssl.getSupportedProtocols()[0]);
- protocols[0] = savedProtocol;
-
- // Make sure all protocol names are expected
- for (String protocol : protocols) {
- assertNotNull(StandardNames.SSL_SOCKET_PROTOCOLS.contains(protocol));
- }
+ StandardNames.assertSupportedProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
+ assertNotSame(protocols, ssl.getSupportedProtocols());
}
public void test_SSLSocket_getEnabledProtocols() throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket ssl = (SSLSocket) sf.createSocket();
String[] protocols = ssl.getEnabledProtocols();
- assertNotNull(protocols);
- assertTrue(protocols.length != 0);
-
- // Make sure modifying the result is not observable
- String savedProtocol = protocols[0];
- assertNotNull(savedProtocol);
- protocols[0] = null;
- assertNotNull(ssl.getEnabledProtocols()[0]);
- protocols[0] = savedProtocol;
-
- // Make sure all protocol names are expected
- for (String protocol : protocols) {
- assertNotNull(StandardNames.SSL_SOCKET_PROTOCOLS.contains(protocol));
- }
+ StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
+ assertNotSame(protocols, ssl.getEnabledProtocols());
}
public void test_SSLSocket_setEnabledProtocols() throws Exception {
@@ -299,9 +250,6 @@ public class SSLSocketTest extends TestCase {
assertNotNull(id);
assertEquals(32, id.length);
assertNotNull(c.sslContext.getClientSessionContext().getSession(id));
- if (!TestSSLContext.sslServerSocketSupportsSessionTickets()) {
- assertNotNull(c.sslContext.getServerSessionContext().getSession(id));
- }
assertNotNull(cipherSuite);
assertTrue(Arrays.asList(
@@ -344,6 +292,10 @@ public class SSLSocketTest extends TestCase {
});
client.startHandshake();
thread.join();
+ if (!TestSSLContext.sslServerSocketSupportsSessionTickets()) {
+ assertNotNull(c.sslContext.getServerSessionContext().getSession(
+ client.getSession().getId()));
+ }
synchronized (handshakeCompletedListenerCalled) {
while (!handshakeCompletedListenerCalled[0]) {
handshakeCompletedListenerCalled.wait();
@@ -555,7 +507,80 @@ public class SSLSocketTest extends TestCase {
thread.join();
}
- public void test_SSLSocketTest_Test_create() {
+ public void test_SSLSocket_getSSLParameters() throws Exception {
+ SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket ssl = (SSLSocket) sf.createSocket();
+
+ SSLParameters p = ssl.getSSLParameters();
+ assertNotNull(p);
+
+ String[] cipherSuites = p.getCipherSuites();
+ StandardNames.assertValidCipherSuites(StandardNames.CIPHER_SUITES, cipherSuites);
+ assertNotSame(cipherSuites, ssl.getEnabledCipherSuites());
+ assertEquals(Arrays.asList(cipherSuites), Arrays.asList(ssl.getEnabledCipherSuites()));
+
+ String[] protocols = p.getProtocols();
+ StandardNames.assertValidProtocols(StandardNames.SSL_SOCKET_PROTOCOLS, protocols);
+ assertNotSame(protocols, ssl.getEnabledProtocols());
+ assertEquals(Arrays.asList(protocols), Arrays.asList(ssl.getEnabledProtocols()));
+
+ assertEquals(p.getWantClientAuth(), ssl.getWantClientAuth());
+ assertEquals(p.getNeedClientAuth(), ssl.getNeedClientAuth());
+ }
+
+ public void test_SSLSocket_setSSLParameters() throws Exception {
+ SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket ssl = (SSLSocket) sf.createSocket();
+ String[] defaultCipherSuites = ssl.getEnabledCipherSuites();
+ String[] defaultProtocols = ssl.getEnabledProtocols();
+ String[] supportedCipherSuites = ssl.getSupportedCipherSuites();
+ String[] supportedProtocols = ssl.getSupportedProtocols();
+
+ {
+ SSLParameters p = new SSLParameters();
+ ssl.setSSLParameters(p);
+ assertEquals(Arrays.asList(defaultCipherSuites),
+ Arrays.asList(ssl.getEnabledCipherSuites()));
+ assertEquals(Arrays.asList(defaultProtocols),
+ Arrays.asList(ssl.getEnabledProtocols()));
+ }
+
+ {
+ SSLParameters p = new SSLParameters(supportedCipherSuites,
+ supportedProtocols);
+ ssl.setSSLParameters(p);
+ assertEquals(Arrays.asList(supportedCipherSuites),
+ Arrays.asList(ssl.getEnabledCipherSuites()));
+ assertEquals(Arrays.asList(supportedProtocols),
+ Arrays.asList(ssl.getEnabledProtocols()));
+ }
+ {
+ SSLParameters p = new SSLParameters();
+
+ p.setNeedClientAuth(true);
+ assertFalse(ssl.getNeedClientAuth());
+ assertFalse(ssl.getWantClientAuth());
+ ssl.setSSLParameters(p);
+ assertTrue(ssl.getNeedClientAuth());
+ assertFalse(ssl.getWantClientAuth());
+
+ p.setWantClientAuth(true);
+ assertTrue(ssl.getNeedClientAuth());
+ assertFalse(ssl.getWantClientAuth());
+ ssl.setSSLParameters(p);
+ assertFalse(ssl.getNeedClientAuth());
+ assertTrue(ssl.getWantClientAuth());
+
+ p.setWantClientAuth(false);
+ assertFalse(ssl.getNeedClientAuth());
+ assertTrue(ssl.getWantClientAuth());
+ ssl.setSSLParameters(p);
+ assertFalse(ssl.getNeedClientAuth());
+ assertFalse(ssl.getWantClientAuth());
+ }
+ }
+
+ public void test_TestSSLSocketPair_create() {
TestSSLSocketPair test = TestSSLSocketPair.create();
assertNotNull(test.c);
assertNotNull(test.server);
@@ -564,13 +589,15 @@ public class SSLSocketTest extends TestCase {
assertTrue(test.client.isConnected());
assertNotNull(test.server.getSession());
assertNotNull(test.client.getSession());
+ assertTrue(test.server.getSession().isValid());
+ assertTrue(test.client.getSession().isValid());
}
/**
* Not run by default by JUnit, but can be run by Vogar by
* specifying it explictly (or with main method below)
*/
- public void stress_test_SSLSocketTest_Test_create() {
+ public void stress_test_TestSSLSocketPair_create() {
final boolean verbose = true;
while (true) {
TestSSLSocketPair test = TestSSLSocketPair.create();
@@ -584,6 +611,6 @@ public class SSLSocketTest extends TestCase {
}
public static final void main (String[] args) {
- new SSLSocketTest().stress_test_SSLSocketTest_Test_create();
+ new SSLSocketTest().stress_test_TestSSLSocketPair_create();
}
}
diff --git a/luni/src/test/java/tests/api/javax/net/ssl/KeyStoreBuilderParametersTest.java b/luni/src/test/java/tests/api/javax/net/ssl/KeyStoreBuilderParametersTest.java
index acbbd30..8e2e093 100644
--- a/luni/src/test/java/tests/api/javax/net/ssl/KeyStoreBuilderParametersTest.java
+++ b/luni/src/test/java/tests/api/javax/net/ssl/KeyStoreBuilderParametersTest.java
@@ -75,16 +75,15 @@ public class KeyStoreBuilderParametersTest extends TestCase {
public void test_Constructor02() {
//Null parameter
- List<String> ls = null;
try {
- KeyStoreBuilderParameters ksp = new KeyStoreBuilderParameters(ls);
+ KeyStoreBuilderParameters ksp = new KeyStoreBuilderParameters(null);
fail("NullPointerException should be thrown");
} catch (NullPointerException npe) {
//expected
}
//Empty parameter
- List<String> lsEmpty = new ArrayList<String>();
+ List lsEmpty = new ArrayList<String>();
try {
KeyStoreBuilderParameters ksp = new KeyStoreBuilderParameters(lsEmpty);
fail("IllegalArgumentException should be thrown");
@@ -93,7 +92,7 @@ public class KeyStoreBuilderParametersTest extends TestCase {
}
//Not null parameter
- List<String> lsFiled = new ArrayList<String>();;
+ List lsFiled = new ArrayList<String>();
lsFiled.add("Parameter1");
lsFiled.add("Parameter2");
try {
@@ -116,13 +115,13 @@ public class KeyStoreBuilderParametersTest extends TestCase {
)
public void test_getParameters() {
String[] param = {"Parameter1", "Parameter2", "Parameter3"};
- List<String> ls = new ArrayList<String>();
+ List ls = new ArrayList<String>();
for (int i = 0; i < param.length; i++) {
ls.add(param[i]);
}
KeyStoreBuilderParameters ksp = new KeyStoreBuilderParameters(ls);
try {
- List<String> res_list = ksp.getParameters();
+ List res_list = ksp.getParameters();
try {
res_list.add("test");
} catch (UnsupportedOperationException e) {
diff --git a/support/src/test/java/javax/net/ssl/StandardNames.java b/support/src/test/java/javax/net/ssl/StandardNames.java
index debc047..58a552b 100644
--- a/support/src/test/java/javax/net/ssl/StandardNames.java
+++ b/support/src/test/java/javax/net/ssl/StandardNames.java
@@ -17,12 +17,15 @@
package javax.net.ssl;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
+import junit.framework.Assert;
/**
- * This class defines expected string names for protocols, key types, client and server auth types, cipher suites.
+ * This class defines expected string names for protocols, key types,
+ * client and server auth types, cipher suites.
*
* Initially based on "Appendix A: Standard Names" of
* <a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA">
@@ -34,14 +37,17 @@ import java.util.Set;
* Java Cryptography Architecture Sun Providers Documentation for JavaTM Platform Standard Edition 6
* </a>
*/
-public final class StandardNames {
+public final class StandardNames extends Assert {
+ public static final String SSL_CONTEXT_PROTOCOLS_DEFAULT = "Default";
public static final Set<String> SSL_CONTEXT_PROTOCOLS = new HashSet<String>(Arrays.asList(
+ SSL_CONTEXT_PROTOCOLS_DEFAULT,
"SSL",
- "SSLv2",
+ // "SSLv2",
"SSLv3",
"TLS",
"TLSv1"));
+ public static final String SSL_CONTEXT_PROTOCOL_DEFAULT = "TLS";
public static final Set<String> KEY_TYPES = new HashSet<String>(Arrays.asList(
"RSA",
@@ -50,10 +56,20 @@ public final class StandardNames {
"DH_DSA"));
public static final Set<String> SSL_SOCKET_PROTOCOLS = new HashSet<String>(Arrays.asList(
- "SSLv2",
+ // "SSLv2",
"SSLv3",
- "TLSv1",
- "SSLv2Hello"));
+ "TLSv1"));
+ static {
+ if (TestSSLContext.IS_RI) {
+ /* Even though we use OpenSSL's SSLv23_method which
+ * supports sending SSLv2 client hello messages, the
+ * OpenSSL implementation in s23_client_hello disables
+ * this if SSL_OP_NO_SSLv2 is specified, which we always
+ * do to disable general use of SSLv2.
+ */
+ SSL_SOCKET_PROTOCOLS.add("SSLv2Hello");
+ }
+ }
public static final Set<String> CLIENT_AUTH_TYPES = new HashSet<String>(KEY_TYPES);
@@ -182,4 +198,107 @@ public final class StandardNames {
CIPHER_SUITES = (TestSSLContext.IS_RI) ? CIPHER_SUITES_RI : CIPHER_SUITES_OPENSSL;
}
+
+ public static final Set<String> CIPHER_SUITES_SSLENGINE = new HashSet<String>(CIPHER_SUITES);
+ static {
+ if (!TestSSLContext.IS_RI) {
+ // Android does not include Java versions of RC4 and IDEA
+ // Java crypto implementations so these fail to work for
+ // the SSLEngine implementation.
+ CIPHER_SUITES_SSLENGINE.remove("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5");
+ CIPHER_SUITES_SSLENGINE.remove("SSL_DH_anon_WITH_RC4_128_MD5");
+ CIPHER_SUITES_SSLENGINE.remove("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5");
+ CIPHER_SUITES_SSLENGINE.remove("SSL_RSA_EXPORT_WITH_RC4_40_MD5");
+ CIPHER_SUITES_SSLENGINE.remove("SSL_RSA_WITH_RC4_128_MD5");
+ CIPHER_SUITES_SSLENGINE.remove("SSL_RSA_WITH_RC4_128_SHA");
+ CIPHER_SUITES_SSLENGINE.remove("TLS_RSA_WITH_IDEA_CBC_SHA");
+ // Harmony SSLEngine does not support AES cipher suites
+ // that are supported by the OpenSSL based SSLSocket
+ // implementations
+ CIPHER_SUITES_SSLENGINE.remove("TLS_DHE_DSS_WITH_AES_128_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.remove("TLS_DHE_DSS_WITH_AES_256_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.remove("TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.remove("TLS_DHE_RSA_WITH_AES_256_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.remove("TLS_DH_anon_WITH_AES_128_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.remove("TLS_DH_anon_WITH_AES_256_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.remove("TLS_RSA_WITH_AES_128_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.remove("TLS_RSA_WITH_AES_256_CBC_SHA");
+ // Harmony SSLEngine supports has some older cipher suites
+ CIPHER_SUITES_SSLENGINE.add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.add("SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.add("SSL_DH_DSS_WITH_DES_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.add("SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA");
+ CIPHER_SUITES_SSLENGINE.add("SSL_DH_RSA_WITH_DES_CBC_SHA");
+ }
+ }
+
+ /**
+ * Asserts that the cipher suites array is non-null and that it
+ * all of its contents are cipher suites known to this
+ * implementation. As a convenience, returns any unenabled cipher
+ * suites in a test for those that want to verify separately that
+ * all cipher suites were included.
+ */
+ public static Set<String> assertValidCipherSuites(Set<String> expected, String[] cipherSuites) {
+ assertNotNull(cipherSuites);
+ assertTrue(cipherSuites.length != 0);
+
+ // Make sure all cipherSuites names are expected
+ Set remainingCipherSuites = new HashSet<String>(expected);
+ Set unknownCipherSuites = new HashSet<String>();
+ for (String cipherSuite : cipherSuites) {
+ boolean removed = remainingCipherSuites.remove(cipherSuite);
+ if (!removed) {
+ unknownCipherSuites.add(cipherSuite);
+ }
+ }
+ assertEquals(Collections.EMPTY_SET, unknownCipherSuites);
+ return remainingCipherSuites;
+ }
+
+ /**
+ * After using assertValidCipherSuites on cipherSuites,
+ * assertSupportedCipherSuites additionally verifies that all
+ * supported cipher suites where in the input array.
+ */
+ public static void assertSupportedCipherSuites(Set<String> expected, String[] cipherSuites) {
+ Set<String> remainingCipherSuites = assertValidCipherSuites(expected, cipherSuites);
+ assertEquals(Collections.EMPTY_SET, remainingCipherSuites);
+ assertEquals(expected.size(), cipherSuites.length);
+ }
+
+ /**
+ * Asserts that the protocols array is non-null and that it all of
+ * its contents are protocols known to this implementation. As a
+ * convenience, returns any unenabled protocols in a test for
+ * those that want to verify separately that all protocols were
+ * included.
+ */
+ public static Set<String> assertValidProtocols(Set<String> expected, String[] protocols) {
+ assertNotNull(protocols);
+ assertTrue(protocols.length != 0);
+
+ // Make sure all protocols names are expected
+ Set remainingProtocols = new HashSet<String>(StandardNames.SSL_SOCKET_PROTOCOLS);
+ Set unknownProtocols = new HashSet<String>();
+ for (String protocol : protocols) {
+ if (!remainingProtocols.remove(protocol)) {
+ unknownProtocols.add(protocol);
+ }
+ }
+ assertEquals(Collections.EMPTY_SET, unknownProtocols);
+ return remainingProtocols;
+ }
+
+ /**
+ * After using assertValidProtocols on protocols,
+ * assertSupportedProtocols additionally verifies that all
+ * supported protocols where in the input array.
+ */
+ public static void assertSupportedProtocols(Set<String> expected, String[] protocols) {
+ Set<String> remainingProtocols = assertValidProtocols(expected, protocols);
+ assertEquals(Collections.EMPTY_SET, remainingProtocols);
+ assertEquals(expected.size(), protocols.length);
+ }
}
diff --git a/support/src/test/java/javax/net/ssl/TestKeyStore.java b/support/src/test/java/javax/net/ssl/TestKeyStore.java
index 97b5c23..9ef2bdd 100644
--- a/support/src/test/java/javax/net/ssl/TestKeyStore.java
+++ b/support/src/test/java/javax/net/ssl/TestKeyStore.java
@@ -106,9 +106,7 @@ public final class TestKeyStore {
char[] keyStorePassword,
String keyAlgorithm,
String publicAlias,
- String privateAlias)
- throws Exception {
-
+ String privateAlias) throws Exception {
PrivateKey privateKey;
X509Certificate x509c;
if (publicAlias == null && privateAlias == null) {
diff --git a/support/src/test/java/javax/net/ssl/TestSSLContext.java b/support/src/test/java/javax/net/ssl/TestSSLContext.java
index 5ec040c..3492a28 100644
--- a/support/src/test/java/javax/net/ssl/TestSSLContext.java
+++ b/support/src/test/java/javax/net/ssl/TestSSLContext.java
@@ -25,7 +25,7 @@ import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Collections;
-import junit.framework.AssertionFailedError;
+import junit.framework.Assert;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
@@ -33,9 +33,10 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider;
* want a canned SSLContext and related state for testing so they
* don't have to duplicate the logic.
*/
-public final class TestSSLContext {
+public final class TestSSLContext extends Assert {
- public static final boolean IS_RI = !"Dalvik Core Library".equals(System.getProperty("java.specification.name"));
+ public static final boolean IS_RI
+ = !"Dalvik Core Library".equals(System.getProperty("java.specification.name"));
public static final String PROVIDER_NAME = (IS_RI) ? "SunJSSE" : "HarmonyJSSE";
/*
@@ -68,7 +69,9 @@ public final class TestSSLContext {
* results appropriately.
*/
public static boolean sslServerSocketSupportsSessionTickets () {
- return !IS_RI;
+ // Disabled session tickets for better compatability b/2682876
+ // return !IS_RI;
+ return false;
}
public final KeyStore keyStore;
@@ -164,7 +167,8 @@ public final class TestSSLContext {
* certificate chain from the given KeyStore and a TrustManager
* using the certificates authorities from the same KeyStore.
*/
- public static final SSLContext createSSLContext(final KeyStore keyStore, final char[] keyStorePassword)
+ public static final SSLContext createSSLContext(final KeyStore keyStore,
+ final char[] keyStorePassword)
throws Exception {
String kmfa = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfa);
@@ -193,9 +197,7 @@ public final class TestSSLContext {
break;
}
}
- if (!found) {
- throw new AssertionFailedError("Could not find princial " + principal + " in key store");
- }
+ assertTrue(found);
}
public static void assertCertificateInKeyStore(Certificate certificate,
@@ -211,8 +213,6 @@ public final class TestSSLContext {
break;
}
}
- if (!found) {
- throw new AssertionFailedError("Could not find certificate " + certificate + " in key store");
- }
+ assertTrue(found);
}
}
diff --git a/support/src/test/java/javax/net/ssl/TestSSLEnginePair.java b/support/src/test/java/javax/net/ssl/TestSSLEnginePair.java
new file mode 100644
index 0000000..f3250e6
--- /dev/null
+++ b/support/src/test/java/javax/net/ssl/TestSSLEnginePair.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.net.ssl;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import junit.framework.Assert;
+
+/**
+ * TestSSLEnginePair is a convenience class for other tests that want
+ * a pair of connected and handshaked client and server SSLEngines for
+ * testing.
+ */
+public final class TestSSLEnginePair extends Assert {
+ public final TestSSLContext c;
+ public final SSLEngine server;
+ public final SSLEngine client;
+
+ private TestSSLEnginePair(TestSSLContext c,
+ SSLEngine server,
+ SSLEngine client) {
+ this.c = c;
+ this.server = server;
+ this.client = client;
+ }
+
+ public static TestSSLEnginePair create(Hooks hooks) throws IOException {
+ TestSSLContext c = TestSSLContext.create();
+ SSLEngine[] engines = connect(c, c, hooks);
+ return new TestSSLEnginePair(c, engines[0], engines[1]);
+ }
+
+ /**
+ * Create a new connected server/client engine pair within a
+ * existing SSLContext. Optionally specify clientCipherSuites to
+ * allow forcing new SSLSession to test SSLSessionContext
+ * caching. Optionally specify serverCipherSuites for testing
+ * cipher suite negotiation.
+ */
+ public static SSLEngine[] connect(final TestSSLContext clientContext,
+ final TestSSLContext serverContext,
+ Hooks hooks) throws IOException {
+ if (hooks == null) {
+ hooks = new Hooks();
+ }
+
+ SSLSession session = clientContext.sslContext.createSSLEngine().getSession();
+
+ int packetBufferSize = session.getPacketBufferSize();
+ ByteBuffer clientToServer = ByteBuffer.allocate(packetBufferSize);
+ ByteBuffer serverToClient = ByteBuffer.allocate(packetBufferSize);
+
+ int applicationBufferSize = session.getApplicationBufferSize();
+ ByteBuffer scratch = ByteBuffer.allocate(applicationBufferSize);
+
+ SSLEngine client = clientContext.sslContext.createSSLEngine();
+ SSLEngine server = serverContext.sslContext.createSSLEngine();
+ client.setUseClientMode(true);
+ server.setUseClientMode(false);
+ hooks.beforeBeginHandshake(client, server);
+ client.beginHandshake();
+ server.beginHandshake();
+
+ while (true) {
+ boolean clientDone = client.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING;
+ boolean serverDone = server.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING;
+ if (clientDone && serverDone) {
+ break;
+ }
+
+ boolean progress = false;
+ if (!clientDone) {
+ progress |= handshakeCompleted(client,
+ clientToServer,
+ serverToClient,
+ scratch);
+ }
+ if (!serverDone) {
+ progress |= handshakeCompleted(server,
+ serverToClient,
+ clientToServer,
+ scratch);
+ }
+ if (!progress) {
+ // let caller detect the problem, but don't just hang here
+ break;
+ }
+ }
+
+ return new SSLEngine[] { server, client };
+ }
+
+ public static class Hooks {
+ void beforeBeginHandshake(SSLEngine client, SSLEngine server) {}
+ }
+
+ private static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocate(0);
+
+ private static boolean handshakeCompleted(SSLEngine engine,
+ ByteBuffer output,
+ ByteBuffer input,
+ ByteBuffer scratch) throws IOException {
+ try {
+ // make the other side's output into our input
+ input.flip();
+
+ HandshakeStatus status = engine.getHandshakeStatus();
+ switch (status) {
+
+ case NEED_TASK:
+ boolean progress = false;
+ while (true) {
+ Runnable runnable = engine.getDelegatedTask();
+ if (runnable == null) {
+ return progress;
+ }
+ runnable.run();
+ progress = true;
+ }
+
+ case NEED_UNWRAP:
+ // avoid underflow
+ if (input.remaining() == 0) {
+ return false;
+ }
+ SSLEngineResult unwrapResult = engine.unwrap(input, scratch);
+ assertEquals(SSLEngineResult.Status.OK, unwrapResult.getStatus());
+ assertEquals(0, scratch.position());
+ return true;
+
+ case NEED_WRAP:
+ // avoid possible overflow
+ if (output.remaining() != output.capacity()) {
+ return false;
+ }
+ SSLEngineResult wrapResult = engine.wrap(EMPTY_BYTE_BUFFER, output);
+ assertEquals(SSLEngineResult.Status.OK, wrapResult.getStatus());
+ return true;
+
+ case NOT_HANDSHAKING:
+ // should have been checked by caller before calling
+ case FINISHED:
+ // only returned by wrap/unrap status, not getHandshakeStatus
+ throw new IllegalStateException("Unexpected HandshakeStatus = " + status);
+ default:
+ throw new IllegalStateException("Unknown HandshakeStatus = " + status);
+ }
+ } finally {
+ // shift consumed input, restore to output mode
+ input.compact();
+ }
+ }
+}
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/MySSLContextSpi.java b/support/src/test/java/org/apache/harmony/security/tests/support/MySSLContextSpi.java
index 30df601..9da7a6f 100644
--- a/support/src/test/java/org/apache/harmony/security/tests/support/MySSLContextSpi.java
+++ b/support/src/test/java/org/apache/harmony/security/tests/support/MySSLContextSpi.java
@@ -20,15 +20,15 @@ package org.apache.harmony.security.tests.support;
import java.nio.ByteBuffer;
import java.security.KeyManagementException;
import java.security.SecureRandom;
-
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContextSpi;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
-import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
@@ -79,6 +79,16 @@ public class MySSLContextSpi extends SSLContextSpi {
return null;
}
+ protected SSLParameters engineGetDefaultSSLParameters() {
+ engineGetSocketFactory();
+ return null;
+ }
+
+ protected SSLParameters engineGetSupportedSSLParameters() {
+ engineGetSocketFactory();
+ return null;
+ }
+
/*
* FIXME: add these methods
*/
diff --git a/support/src/test/java/org/apache/harmony/xnet/tests/support/MySSLContextSpi.java b/support/src/test/java/org/apache/harmony/xnet/tests/support/MySSLContextSpi.java
index 489273c..54e2a03 100644
--- a/support/src/test/java/org/apache/harmony/xnet/tests/support/MySSLContextSpi.java
+++ b/support/src/test/java/org/apache/harmony/xnet/tests/support/MySSLContextSpi.java
@@ -20,15 +20,15 @@ package org.apache.harmony.xnet.tests.support;
import java.nio.ByteBuffer;
import java.security.KeyManagementException;
import java.security.SecureRandom;
-
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContextSpi;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
-import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
@@ -77,6 +77,16 @@ public class MySSLContextSpi extends SSLContextSpi {
return null;
}
+ protected SSLParameters engineGetDefaultSSLParameters() {
+ engineGetSocketFactory();
+ return null;
+ }
+
+ protected SSLParameters engineGetSupportedSSLParameters() {
+ engineGetSocketFactory();
+ return null;
+ }
+
/*
* FIXME: add these methods
*/
@@ -142,4 +152,4 @@ public class MySSLContextSpi extends SSLContextSpi {
return null;
}
}
-} \ No newline at end of file
+}