You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ro...@apache.org on 2018/11/06 12:22:50 UTC
qpid-proton-j git commit: PROTON-1962: update some defaults and
related handling
Repository: qpid-proton-j
Updated Branches:
refs/heads/master 31f5fc97b -> 0cb8ca03c
PROTON-1962: update some defaults and related handling
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton-j/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton-j/commit/0cb8ca03
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton-j/tree/0cb8ca03
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton-j/diff/0cb8ca03
Branch: refs/heads/master
Commit: 0cb8ca03cec42120dcfc434561592d89a89a805e
Parents: 31f5fc9
Author: Robbie Gemmell <ro...@apache.org>
Authored: Tue Nov 6 12:17:09 2018 +0000
Committer: Robbie Gemmell <ro...@apache.org>
Committed: Tue Nov 6 12:17:09 2018 +0000
----------------------------------------------------------------------
.../apache/qpid/proton/engine/SslDomain.java | 15 +-
.../apache/qpid/proton/engine/Transport.java | 14 +-
.../impl/ssl/SimpleSslTransportWrapper.java | 8 +-
.../proton/engine/impl/ssl/SslDomainImpl.java | 12 +-
.../engine/impl/ssl/SslEngineFacadeFactory.java | 8 +
.../qpid/proton/engine/impl/ssl/SslImpl.java | 9 +
.../qpid/proton/reactor/impl/IOHandler.java | 3 +-
.../impl/ssl/SimpleSslTransportWrapperTest.java | 13 +-
.../engine/impl/ssl/SslDomainImplTest.java | 73 +++++++++
.../qpid/proton/systemtests/engine/SslTest.java | 164 +++++++++++++++++++
tests/python/proton_tests/ssl.py | 31 +++-
11 files changed, 328 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/0cb8ca03/proton-j/src/main/java/org/apache/qpid/proton/engine/SslDomain.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/SslDomain.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/SslDomain.java
index 279d934..06a3517 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/engine/SslDomain.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/SslDomain.java
@@ -49,15 +49,24 @@ public interface SslDomain
/**
* Determines the level of peer validation.
*
- * {@link #ANONYMOUS_PEER} is configured by default.
+ * {@link #VERIFY_PEER_NAME} is used by default in {@link Mode#CLIENT client}
+ * mode if not configured otherwise, with {@link #ANONYMOUS_PEER} used for
+ * {@link Mode#SERVER server} mode if not configured otherwise.
*/
public enum VerifyMode
{
/**
- * will only connect to those peers that provide a valid identifying certificate signed
- * by a trusted CA and are using an authenticated cipher
+ * Requires peers provide a valid identifying certificate signed by
+ * a trusted certificate. Does not verify hostname details of the
+ * peer certificate, use {@link #VERIFY_PEER_NAME} for this instead.
*/
VERIFY_PEER,
+ /**
+ * Requires peers provide a valid identifying certificate signed
+ * by a trusted certificate, including verifying hostname details
+ * of the certificate using peer details provided when configuring
+ * TLS via {@link Transport#ssl(SslDomain, SslPeerDetails)}.
+ */
VERIFY_PEER_NAME,
/**
* does not require a valid certificate, and permits use of ciphers that
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/0cb8ca03/proton-j/src/main/java/org/apache/qpid/proton/engine/Transport.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/Transport.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/Transport.java
index f8de042..66cde84 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/engine/Transport.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/Transport.java
@@ -194,15 +194,21 @@ public interface Transport extends Endpoint
* {@link Ssl} object, regardless of the parameters supplied.
*
* @param sslDomain the SSL settings to use
- * @param sslPeerDetails may be null, in which case SSL session resume will not be attempted
+ * @param sslPeerDetails peer details, used for SNI, hostname verification, etc when connecting. May be null.
* @return an {@link Ssl} object representing the SSL session.
+ * @throws IllegalArgumentException if the sslDomain requests hostname verification but sslPeerDetails are null.
+ * @throws IllegalStateException if the sslDomain has not been initialised.
*/
- Ssl ssl(SslDomain sslDomain, SslPeerDetails sslPeerDetails);
+ Ssl ssl(SslDomain sslDomain, SslPeerDetails sslPeerDetails) throws IllegalArgumentException;
/**
- * As per {@link #ssl(SslDomain, SslPeerDetails)} but no attempt is made to resume a previous SSL session.
+ * Equivalent to {@link #ssl(SslDomain, SslPeerDetails)} but passing null for SslPeerDetails, meaning no SNI detail
+ * is sent, hostname verification isn't supported etc when connecting.
+ *
+ * @throws IllegalArgumentException if the sslDomain requests hostname verification.
+ * @throws IllegalStateException if the sslDomain has not been initialised.
*/
- Ssl ssl(SslDomain sslDomain);
+ Ssl ssl(SslDomain sslDomain) throws IllegalArgumentException;
/**
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/0cb8ca03/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SimpleSslTransportWrapper.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SimpleSslTransportWrapper.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SimpleSslTransportWrapper.java
index a30e88b..f2454b3 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SimpleSslTransportWrapper.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SimpleSslTransportWrapper.java
@@ -360,9 +360,15 @@ public class SimpleSslTransportWrapper implements SslTransportWrapper
try {
unwrapInput();
} catch (SSLException e) {
- _logger.log(Level.WARNING, e.getMessage());
+ if(_logger.isLoggable(Level.FINEST)){
+ _logger.log(Level.FINEST, e.getMessage(), e);
+ } else {
+ _logger.log(Level.WARNING, e.getMessage());
+ }
_inputBuffer.position(_inputBuffer.limit());
_tail_closed = true;
+
+ throw new TransportException(e);
} finally {
_inputBuffer.compact();
}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/0cb8ca03/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslDomainImpl.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslDomainImpl.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslDomainImpl.java
index 3928b05..fddde1a 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslDomainImpl.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslDomainImpl.java
@@ -19,7 +19,6 @@
package org.apache.qpid.proton.engine.impl.ssl;
import javax.net.ssl.SSLContext;
-import org.apache.qpid.proton.ProtonUnsupportedOperationException;
import org.apache.qpid.proton.engine.ProtonJSslDomain;
import org.apache.qpid.proton.engine.SslDomain;
import org.apache.qpid.proton.engine.SslPeerDetails;
@@ -27,7 +26,7 @@ import org.apache.qpid.proton.engine.SslPeerDetails;
public class SslDomainImpl implements SslDomain, ProtonSslEngineProvider, ProtonJSslDomain
{
private Mode _mode;
- private VerifyMode _verifyMode = VerifyMode.ANONYMOUS_PEER;
+ private VerifyMode _verifyMode;
private String _certificateFile;
private String _privateKeyFile;
private String _privateKeyPassword;
@@ -94,10 +93,6 @@ public class SslDomainImpl implements SslDomain, ProtonSslEngineProvider, Proton
@Override
public void setPeerAuthentication(VerifyMode verifyMode)
{
- if(verifyMode == VerifyMode.VERIFY_PEER_NAME)
- {
- throw new ProtonUnsupportedOperationException();
- }
_verifyMode = verifyMode;
_sslEngineFacadeFactory.resetCache();
}
@@ -105,6 +100,11 @@ public class SslDomainImpl implements SslDomain, ProtonSslEngineProvider, Proton
@Override
public VerifyMode getPeerAuthentication()
{
+ if(_verifyMode == null)
+ {
+ return _mode == Mode.SERVER ? VerifyMode.ANONYMOUS_PEER : VerifyMode.VERIFY_PEER_NAME;
+ }
+
return _verifyMode;
}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/0cb8ca03/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslEngineFacadeFactory.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslEngineFacadeFactory.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslEngineFacadeFactory.java
index 309e0dc..6a730df 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslEngineFacadeFactory.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslEngineFacadeFactory.java
@@ -53,6 +53,7 @@ import java.util.logging.Logger;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
@@ -232,6 +233,13 @@ public class SslEngineFacadeFactory
{
sslEngine.setNeedClientAuth(true);
}
+
+ if(domain.getPeerAuthentication() == SslDomain.VerifyMode.VERIFY_PEER_NAME)
+ {
+ SSLParameters sslParameters = sslEngine.getSSLParameters();
+ sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
+ sslEngine.setSSLParameters(sslParameters);
+ }
}
if(_logger.isLoggable(Level.FINE))
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/0cb8ca03/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslImpl.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslImpl.java b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslImpl.java
index de99351..24d7c43 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslImpl.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/engine/impl/ssl/SslImpl.java
@@ -25,6 +25,7 @@ import java.nio.ByteBuffer;
import org.apache.qpid.proton.ProtonUnsupportedOperationException;
import org.apache.qpid.proton.engine.Ssl;
import org.apache.qpid.proton.engine.SslDomain;
+import org.apache.qpid.proton.engine.SslDomain.VerifyMode;
import org.apache.qpid.proton.engine.SslPeerDetails;
import org.apache.qpid.proton.engine.Transport;
import org.apache.qpid.proton.engine.TransportException;
@@ -54,6 +55,14 @@ public class SslImpl implements Ssl, TransportLayer
_domain = domain;
_protonSslEngineProvider = (ProtonSslEngineProvider)domain;
_peerDetails = peerDetails;
+
+ if(_domain.getMode() == null) {
+ throw new IllegalStateException("Client/server mode must be configured, SslDomain must have init called.");
+ }
+
+ if(_peerDetails == null && _domain.getPeerAuthentication() == VerifyMode.VERIFY_PEER_NAME) {
+ throw new IllegalArgumentException("Peer hostname verification is enabled, but no peer details were provided");
+ }
}
public TransportWrapper wrap(TransportInput inputProcessor, TransportOutput outputProcessor)
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/0cb8ca03/proton-j/src/main/java/org/apache/qpid/proton/reactor/impl/IOHandler.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/reactor/impl/IOHandler.java b/proton-j/src/main/java/org/apache/qpid/proton/reactor/impl/IOHandler.java
index 81b85ff..5d58182 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/reactor/impl/IOHandler.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/reactor/impl/IOHandler.java
@@ -37,6 +37,7 @@ import org.apache.qpid.proton.engine.EndpointState;
import org.apache.qpid.proton.engine.Event;
import org.apache.qpid.proton.engine.Sasl;
import org.apache.qpid.proton.engine.Transport;
+import org.apache.qpid.proton.engine.TransportException;
import org.apache.qpid.proton.engine.impl.TransportImpl;
import org.apache.qpid.proton.engine.Record;
import org.apache.qpid.proton.reactor.Reactor;
@@ -232,7 +233,7 @@ public class IOHandler extends BaseHandler {
} else {
transport.process();
}
- } catch (IOException e) {
+ } catch (IOException | TransportException e) {
ErrorCondition condition = new ErrorCondition();
condition.setCondition(Symbol.getSymbol("proton:io"));
condition.setDescription(e.getMessage());
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/0cb8ca03/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SimpleSslTransportWrapperTest.java
----------------------------------------------------------------------
diff --git a/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SimpleSslTransportWrapperTest.java b/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SimpleSslTransportWrapperTest.java
index 6ee1582..605046c 100644
--- a/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SimpleSslTransportWrapperTest.java
+++ b/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SimpleSslTransportWrapperTest.java
@@ -347,12 +347,19 @@ public class SimpleSslTransportWrapperTest
@Test
public void testSslUnwrapThrowsException_returnsErrorResultAndRefusesFurtherInput() throws Exception
{
- SSLException sslException = new SSLException("unwrap exception");
+ String unwrapExceptionMessage = "unwrap exception message";
+ SSLException sslException = new SSLException(unwrapExceptionMessage);
_dummySslEngine.rejectNextEncodedPacket(sslException);
_sslWrapper.tail().put("<-A->".getBytes(StandardCharsets.UTF_8));
- _sslWrapper.process();
- assertEquals(_sslWrapper.capacity(), Transport.END_OF_STREAM);
+ try {
+ _sslWrapper.process();
+ fail("no exception");
+ } catch(TransportException e) {
+ assertEquals("javax.net.ssl.SSLException: " + unwrapExceptionMessage, e.getMessage());
+ }
+
+ assertEquals(Transport.END_OF_STREAM, _sslWrapper.capacity());
}
@Test
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/0cb8ca03/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SslDomainImplTest.java
----------------------------------------------------------------------
diff --git a/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SslDomainImplTest.java b/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SslDomainImplTest.java
new file mode 100644
index 0000000..e0d7a5d
--- /dev/null
+++ b/proton-j/src/test/java/org/apache/qpid/proton/engine/impl/ssl/SslDomainImplTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.qpid.proton.engine.impl.ssl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+
+import org.apache.qpid.proton.engine.SslDomain;
+import org.apache.qpid.proton.engine.SslDomain.Mode;
+import org.apache.qpid.proton.engine.SslDomain.VerifyMode;
+import org.junit.Test;
+
+public class SslDomainImplTest {
+
+ @Test
+ public void testInitGetMode() throws Exception
+ {
+ SslDomain sslDomain = SslDomain.Factory.create();
+ assertNull("Unexpected mode, none was set", sslDomain.getMode());
+
+ sslDomain.init(Mode.CLIENT);
+ assertEquals("Unexpected mode", Mode.CLIENT, sslDomain.getMode());
+
+ sslDomain.init(Mode.SERVER);
+ assertEquals("Unexpected mode", Mode.SERVER, sslDomain.getMode());
+ }
+
+ @Test
+ public void testVerifyModeDefault() throws Exception
+ {
+ SslDomain clientSslDomain = SslDomain.Factory.create();
+ assertEquals("Unexpected default verification mode", VerifyMode.VERIFY_PEER_NAME, clientSslDomain.getPeerAuthentication());
+ clientSslDomain.init(Mode.CLIENT);
+ assertEquals("Unexpected default verification mode", VerifyMode.VERIFY_PEER_NAME, clientSslDomain.getPeerAuthentication());
+
+ SslDomain serverSslDomain = SslDomain.Factory.create();
+ serverSslDomain.init(Mode.SERVER);
+ assertEquals("Unexpected default verification mode", VerifyMode.ANONYMOUS_PEER, serverSslDomain.getPeerAuthentication());
+ }
+
+ @Test
+ public void testVerifyModeSetGet() throws Exception
+ {
+ SslDomain clientSslDomain = SslDomain.Factory.create();
+ clientSslDomain.init(Mode.CLIENT);
+ assertNotEquals("Unexpected verification mode", VerifyMode.VERIFY_PEER, clientSslDomain.getPeerAuthentication());
+ clientSslDomain.setPeerAuthentication(VerifyMode.VERIFY_PEER);
+ assertEquals("Unexpected verification mode", VerifyMode.VERIFY_PEER, clientSslDomain.getPeerAuthentication());
+
+ SslDomain serverSslDomain = SslDomain.Factory.create();
+ serverSslDomain.init(Mode.SERVER);
+ assertNotEquals("Unexpected verification mode", VerifyMode.VERIFY_PEER, serverSslDomain.getPeerAuthentication());
+ serverSslDomain.setPeerAuthentication(VerifyMode.VERIFY_PEER);
+ assertEquals("Unexpected verification mode", VerifyMode.VERIFY_PEER, serverSslDomain.getPeerAuthentication());
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/0cb8ca03/proton-j/src/test/java/org/apache/qpid/proton/systemtests/engine/SslTest.java
----------------------------------------------------------------------
diff --git a/proton-j/src/test/java/org/apache/qpid/proton/systemtests/engine/SslTest.java b/proton-j/src/test/java/org/apache/qpid/proton/systemtests/engine/SslTest.java
index 32ab62d..962bd2b 100644
--- a/proton-j/src/test/java/org/apache/qpid/proton/systemtests/engine/SslTest.java
+++ b/proton-j/src/test/java/org/apache/qpid/proton/systemtests/engine/SslTest.java
@@ -22,6 +22,8 @@ import static org.apache.qpid.proton.engine.EndpointState.ACTIVE;
import static org.apache.qpid.proton.engine.EndpointState.UNINITIALIZED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileInputStream;
@@ -31,6 +33,8 @@ import java.security.SecureRandom;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.TrustManagerFactory;
import org.apache.qpid.proton.Proton;
@@ -41,7 +45,9 @@ import org.apache.qpid.proton.engine.EndpointState;
import org.apache.qpid.proton.engine.SslDomain;
import org.apache.qpid.proton.engine.SslDomain.Mode;
import org.apache.qpid.proton.engine.SslDomain.VerifyMode;
+import org.apache.qpid.proton.engine.SslPeerDetails;
import org.apache.qpid.proton.engine.Transport;
+import org.apache.qpid.proton.engine.TransportException;
import org.junit.Test;
public class SslTest
@@ -67,6 +73,27 @@ public class SslTest
private final Connection _serverConnection = Proton.connection();
@Test
+ public void testFailureToInitSslDomainThrowsISE() throws Exception {
+ SslDomain sslDomain = SslDomain.Factory.create();
+
+ try {
+ _clientTransport.ssl(sslDomain, null);
+ fail("Expected an exception to be thrown");
+ } catch (IllegalStateException ise) {
+ // Expected
+ assertTrue(ise.getMessage().contains("Client/server mode must be configured"));
+ }
+
+ try {
+ _serverTransport.ssl(sslDomain);
+ fail("Expected an exception to be thrown");
+ } catch (IllegalStateException ise) {
+ // Expected
+ assertTrue(ise.getMessage().contains("Client/server mode must be configured"));
+ }
+ }
+
+ @Test
public void testOpenConnectionsWithProvidedSslContext() throws Exception
{
SslDomain clientSslDomain = SslDomain.Factory.create();
@@ -125,6 +152,143 @@ public class SslTest
assertConditions(_serverTransport);
}
+ @Test
+ public void testHostnameVerificationSuccess() throws Exception {
+ doHostnameVerificationTestImpl(true, true);
+ }
+
+ @Test
+ public void testHostnameVerificationFailure() throws Exception {
+ doHostnameVerificationTestImpl(false, true);
+ }
+
+ @Test
+ public void testHostnameVerificationSkipped() throws Exception {
+ doHostnameVerificationTestImpl(false, false);
+ }
+
+ private void doHostnameVerificationTestImpl(boolean useMatchingServerName, boolean useHostnameVerification) throws Exception {
+ final String serverPeerName = useMatchingServerName ? "localhost" : "anotherserverhost";
+ final VerifyMode clientVerifyMode = useHostnameVerification ? VerifyMode.VERIFY_PEER_NAME : VerifyMode.VERIFY_PEER;
+
+ SslDomain clientSslDomain = SslDomain.Factory.create();
+ clientSslDomain.init(Mode.CLIENT);
+ clientSslDomain.setPeerAuthentication(clientVerifyMode);
+
+ SSLContext clientSslContext = createSslContext(CLIENT_JKS_KEYSTORE, PASSWORD, CLIENT_JKS_TRUSTSTORE, PASSWORD);
+ clientSslDomain.setSslContext(clientSslContext);
+ SslPeerDetails sslPeerDetails = SslPeerDetails.Factory.create(serverPeerName, 1234);
+ _clientTransport.ssl(clientSslDomain, sslPeerDetails);
+
+ SslDomain serverSslDomain = SslDomain.Factory.create();
+ serverSslDomain.init(Mode.SERVER);
+ serverSslDomain.setPeerAuthentication(VerifyMode.VERIFY_PEER_NAME);
+ SSLContext serverSslContext = createSslContext(SERVER_JKS_KEYSTORE, PASSWORD, SERVER_JKS_TRUSTSTORE, PASSWORD);
+ serverSslDomain.setSslContext(serverSslContext);
+ _serverTransport.ssl(serverSslDomain, SslPeerDetails.Factory.create("client", 4567));
+
+ _clientConnection.setContainer(CLIENT_CONTAINER);
+ _serverConnection.setContainer(SERVER_CONTAINER);
+
+ _clientTransport.bind(_clientConnection);
+ _serverTransport.bind(_serverConnection);
+
+ assertConditions(_clientTransport);
+ assertConditions(_serverTransport);
+
+ _clientConnection.open();
+
+ assertEndpointState(_clientConnection, ACTIVE, UNINITIALIZED);
+ assertEndpointState(_serverConnection, UNINITIALIZED, UNINITIALIZED);
+
+ assertConditions(_clientTransport);
+ assertConditions(_serverTransport);
+
+ if(useHostnameVerification && !useMatchingServerName) {
+ // Verify the expected failures and resulting transport closures
+ pumpWithFailingNegotiation();
+
+ assertEquals(Transport.END_OF_STREAM, _clientTransport.pending());
+ assertEquals(Transport.END_OF_STREAM, _clientTransport.capacity());
+
+ assertEquals(Transport.END_OF_STREAM, _serverTransport.pending());
+ assertEquals(Transport.END_OF_STREAM, _serverTransport.capacity());
+ return;
+ } else {
+ // Verify the connections succeed
+ _pumper.pumpAll();
+
+ assertEndpointState(_clientConnection, ACTIVE, UNINITIALIZED);
+ assertEndpointState(_serverConnection, UNINITIALIZED, ACTIVE);
+
+ assertConditions(_clientTransport);
+ assertConditions(_serverTransport);
+
+ _serverConnection.open();
+
+ assertEndpointState(_clientConnection, ACTIVE, UNINITIALIZED);
+ assertEndpointState(_serverConnection, ACTIVE, ACTIVE);
+
+ assertConditions(_clientTransport);
+ assertConditions(_serverTransport);
+
+ _pumper.pumpAll();
+
+ assertEndpointState(_clientConnection, ACTIVE, ACTIVE);
+ assertEndpointState(_serverConnection, ACTIVE, ACTIVE);
+
+ assertConditions(_clientTransport);
+ assertConditions(_serverTransport);
+ }
+ }
+
+ @Test
+ public void testOmittingPeerDetailsThrowsIAEWhenRequired() throws Exception {
+ doOmitPeerDetailsThrowsIAEWhenRequiredTestImpl(true);
+ doOmitPeerDetailsThrowsIAEWhenRequiredTestImpl(false);
+ }
+
+ private void doOmitPeerDetailsThrowsIAEWhenRequiredTestImpl(boolean explicitlySetVerifyMode) {
+ SslDomain clientSslDomain = SslDomain.Factory.create();
+ clientSslDomain.init(Mode.CLIENT);
+
+ if (explicitlySetVerifyMode) {
+ clientSslDomain.setPeerAuthentication(VerifyMode.VERIFY_PEER_NAME);
+ }
+
+ try {
+ _clientTransport.ssl(clientSslDomain, null);
+ fail("Expected an exception to be thrown");
+ } catch (IllegalArgumentException ise) {
+ // Expected
+ }
+
+ try {
+ _clientTransport.ssl(clientSslDomain);
+ fail("Expected an exception to be thrown");
+ } catch (IllegalArgumentException ise) {
+ // Expected
+ }
+ }
+
+ private void pumpWithFailingNegotiation() throws Exception {
+ try {
+ _pumper.pumpAll();
+ fail("Expected an exception");
+ } catch (TransportException te) {
+ assertTrue(te.getCause().getCause() instanceof SSLHandshakeException);
+ }
+
+ try {
+ _pumper.pumpAll();
+ fail("Expected an exception");
+ } catch (TransportException te) {
+ assertTrue(te.getCause().getCause() instanceof SSLException);
+ }
+
+ _pumper.pumpAll();
+ }
+
private void assertConditions(Transport transport)
{
ErrorCondition remoteCondition = transport.getRemoteCondition();
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/0cb8ca03/tests/python/proton_tests/ssl.py
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/ssl.py b/tests/python/proton_tests/ssl.py
index 1a05780..518ef4d 100644
--- a/tests/python/proton_tests/ssl.py
+++ b/tests/python/proton_tests/ssl.py
@@ -25,6 +25,7 @@ import string
import subprocess
import sys
from proton import *
+from org.apache.qpid.proton.engine import TransportException
from .common import Skipped, pump
@@ -82,6 +83,25 @@ class SslTest(common.Test):
def _pump(self, ssl_client, ssl_server, buffer_size=1024):
pump(ssl_client.transport, ssl_server.transport, buffer_size)
+ def _pump_with_failing_negotiation(self, client, server, onesided = False):
+ # Exception once for client/server transport
+ try:
+ self._pump( client, server )
+ assert False, "Expected exception did not occur!"
+ except TransportException:
+ pass
+
+ if(onesided != True):
+ # Exception once for server/client transport
+ try:
+ self._pump( client, server )
+ assert False, "Expected exception did not occur!"
+ except TransportException:
+ pass
+
+ # Ensure both are processed to completion
+ self._pump( client, server )
+
def _do_handshake(self, client, server):
""" Attempt to connect client to server. Will throw a TransportException if the SSL
handshake fails.
@@ -154,6 +174,8 @@ class SslTest(common.Test):
self._testpath("server-private-key.pem"),
"server-password")
server = SslTest.SslTestConnection( self.server_domain, mode=Transport.SERVER )
+
+ self.client_domain.set_peer_authentication( SSLDomain.ANONYMOUS_PEER )
client = SslTest.SslTestConnection( self.client_domain )
client.connection.open()
@@ -235,7 +257,7 @@ class SslTest(common.Test):
client.connection.open()
server.connection.open()
- self._pump( client, server )
+ self._pump_with_failing_negotiation(client, server)
assert client.transport.closed
assert server.transport.closed
assert client.connection.state & Endpoint.REMOTE_UNINIT
@@ -260,7 +282,7 @@ class SslTest(common.Test):
client.connection.open()
server.connection.open()
- self._pump( client, server )
+ self._pump_with_failing_negotiation(client, server)
assert client.transport.closed
assert server.transport.closed
assert client.connection.state & Endpoint.REMOTE_UNINIT
@@ -335,7 +357,7 @@ class SslTest(common.Test):
client.connection.open()
server.connection.open()
- self._pump( client, server )
+ self._pump_with_failing_negotiation(client, server)
assert client.transport.closed
assert server.transport.closed
assert client.connection.state & Endpoint.REMOTE_UNINIT
@@ -430,7 +452,7 @@ class SslTest(common.Test):
client.connection.open()
server.connection.open()
- self._pump( client, server )
+ self._pump_with_failing_negotiation(client, server, onesided = True)
assert client.transport.closed
assert server.transport.closed
assert client.connection.state & Endpoint.REMOTE_UNINIT
@@ -479,6 +501,7 @@ class SslTest(common.Test):
def test_singleton(self):
"""Verify that only a single instance of SSL can exist per Transport"""
transport = Transport()
+ self.client_domain.set_peer_authentication( SSLDomain.VERIFY_PEER )
ssl1 = SSL(transport, self.client_domain)
ssl2 = transport.ssl(self.client_domain)
ssl3 = transport.ssl(self.client_domain)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org