[prev in list] [next in list] [prev in thread] [next in thread]
List: activemq-commits
Subject: svn commit: r948196 - in
From: tabish () apache ! org
Date: 2010-05-25 20:17:27
Message-ID: 20100525201727.4A6F323889FA () eris ! apache ! org
[Download RAW message or body]
Author: tabish
Date: Tue May 25 20:17:26 2010
New Revision: 948196
URL: http://svn.apache.org/viewvc?rev=948196&view=rev
Log:
https://issues.apache.org/activemq/browse/AMQCPP-140
Add code to allow the OpenSSLSocket to be used as either a client or a server based \
socket.
Modified:
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/ssl/openssl/OpenSSLSocket.cpp
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/ssl/openssl/OpenSSLSocket.h
activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ssl/SSLSocket.h
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/ssl/openssl/OpenSSLSocket.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/de \
caf/internal/net/ssl/openssl/OpenSSLSocket.cpp?rev=948196&r1=948195&r2=948196&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/ssl/openssl/OpenSSLSocket.cpp \
(original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/ssl/openssl/OpenSSLSocket.cpp \
Tue May 25 20:17:26 2010 @@ -35,6 +35,7 @@
#include <decaf/internal/net/ssl/openssl/OpenSSLSocketException.h>
#include <decaf/internal/net/ssl/openssl/OpenSSLSocketInputStream.h>
#include <decaf/internal/net/ssl/openssl/OpenSSLSocketOutputStream.h>
+#include <decaf/util/concurrent/Mutex.h>
using namespace decaf;
using namespace decaf::lang;
@@ -42,6 +43,7 @@ using namespace decaf::lang::exceptions;
using namespace decaf::io;
using namespace decaf::net;
using namespace decaf::net::ssl;
+using namespace decaf::util::concurrent;
using namespace decaf::internal;
using namespace decaf::internal::net;
using namespace decaf::internal::net::ssl;
@@ -64,10 +66,17 @@ namespace openssl {
#endif
bool needsClientAuth;
bool wantsClientAuth;
+ bool useClientMode;
+ bool handshakeStarted;
+ bool handshakeCompleted;
+ std::string commonName;
+
+ Mutex handshakeLock;
public:
- SocketData() : ssl( NULL ), needsClientAuth( false ), wantsClientAuth( false \
) { + SocketData() : ssl( NULL ), needsClientAuth( false ), wantsClientAuth( \
false ), + useClientMode( true ), handshakeStarted( false ), \
handshakeCompleted( false ) { }
~SocketData() {
@@ -139,7 +148,12 @@ void OpenSSLSocket::connect( const std::
try{
#ifdef HAVE_OPENSSL
+
+ // Perform the actual Socket connection work
SSLSocket::connect( host, port, timeout );
+
+ // If we actually connected then we can connect the Socket to an OpenSSL
+ // BIO filter so that we can use it in OpenSSL APIs.
if( isConnected() ) {
BIO* bio = BIO_new( BIO_s_socket() );
@@ -159,26 +173,9 @@ void OpenSSLSocket::connect( const std::
BIO_set_fd( bio, (int)fd->getValue(), BIO_NOCLOSE );
SSL_set_bio( this->data->ssl, bio, bio );
- // Since we are a client we want to enforce peer verification, we set a
- // callback so we can collect data on why a verify failed for debugging.
- SSL_set_verify( this->data->ssl, SSL_VERIFY_PEER, \
SocketData::verifyCallback );
-
- int result = SSL_connect( this->data->ssl );
-
- // Checks the error status, when things go right we still perform a \
deeper
- // check on the provided certificate to ensure that it matches the host \
name
- // that we connected to, this prevents someone from using any \
certificate
- // signed by a signing authority that we trust.
- switch( SSL_get_error( this->data->ssl, result ) ) {
- case SSL_ERROR_NONE:
- verifyServerCert( host );
- return;
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- case SSL_ERROR_SYSCALL:
- SSLSocket::close();
- throw OpenSSLSocketException( __FILE__, __LINE__ );
- }
+ // Later when startHandshake is called we will check for this common \
name + // in the provided certificate
+ this->data->commonName = host;
}
#else
throw SocketException( __FILE__, __LINE__, "Not Supported" );
@@ -310,6 +307,123 @@ void OpenSSLSocket::setEnabledProtocols(
}
////////////////////////////////////////////////////////////////////////////////
+void OpenSSLSocket::startHandshake() {
+
+ if( !this->isConnected() ) {
+ throw IOException( __FILE__, __LINE__, "Socket is not connected." );
+ }
+
+ if( this->isClosed() ) {
+ throw IOException( __FILE__, __LINE__, "Socket already closed." );
+ }
+
+ try {
+
+ synchronized( &(this->data->handshakeLock ) ) {
+
+ if( this->data->handshakeStarted ) {
+ return;
+ }
+
+ this->data->handshakeStarted = true;
+
+ if( this->data->useClientMode ) {
+
+ // Since we are a client we want to enforce peer verification, we \
set a + // callback so we can collect data on why a verify failed for \
debugging. + SSL_set_verify( this->data->ssl, SSL_VERIFY_PEER, \
SocketData::verifyCallback ); +
+ int result = SSL_connect( this->data->ssl );
+
+ // Checks the error status, when things go right we still perform a \
deeper + // check on the provided certificate to ensure that it \
matches the host name + // that we connected to, this prevents someone \
from using any certificate + // signed by a signing authority that we \
trust. + switch( SSL_get_error( this->data->ssl, result ) ) {
+ case SSL_ERROR_NONE:
+ verifyServerCert( this->data->commonName );
+ std::cout << "OpenSSLSocket::startHandshake() - Verified \
name: " + << this->data->commonName << std::endl;
+ break;
+ case SSL_ERROR_SSL:
+ case SSL_ERROR_ZERO_RETURN:
+ case SSL_ERROR_SYSCALL:
+ SSLSocket::close();
+ throw OpenSSLSocketException( __FILE__, __LINE__ );
+ }
+
+ } else { // We are in Server Mode.
+
+ int mode = SSL_VERIFY_NONE;
+
+ if( this->data->wantsClientAuth ) {
+ mode = SSL_VERIFY_PEER;
+ }
+
+ if( this->data->needsClientAuth ) {
+ mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+ }
+
+ // Since we are a client we want to enforce peer verification, we \
set a + // callback so we can collect data on why a verify failed for \
debugging. + SSL_set_verify( this->data->ssl, mode, \
SocketData::verifyCallback ); +
+ int result = SSL_accept( this->data->ssl );
+
+ if( result != SSL_ERROR_NONE ) {
+ SSLSocket::close();
+ throw OpenSSLSocketException( __FILE__, __LINE__ );
+ }
+ }
+
+ this->data->handshakeCompleted = true;
+ }
+ }
+ DECAF_CATCH_RETHROW( IOException )
+ DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void OpenSSLSocket::setUseClientMode( bool value ) {
+
+ synchronized( &( this->data->handshakeLock ) ) {
+ if( this->data->handshakeStarted ) {
+ throw IllegalArgumentException(
+ __FILE__, __LINE__, "Handshake has already been started cannot \
change mode." ); + }
+
+ this->data->useClientMode = value;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool OpenSSLSocket::getUseClientMode() const {
+ return this->data->useClientMode;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void OpenSSLSocket::setNeedClientAuth( bool value ) {
+ this->data->needsClientAuth = value;
+ this->data->wantsClientAuth = false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool OpenSSLSocket::getNeedClientAuth() const {
+ return this->data->needsClientAuth;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void OpenSSLSocket::setWantClientAuth( bool value ) {
+ this->data->wantsClientAuth = value;
+ this->data->needsClientAuth = false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool OpenSSLSocket::getWantClientAuth() const {
+ return this->data->wantsClientAuth;
+}
+
+////////////////////////////////////////////////////////////////////////////////
int OpenSSLSocket::read( unsigned char* buffer, int size, int offset, int length ) {
try{
@@ -347,6 +461,11 @@ int OpenSSLSocket::read( unsigned char*
}
#ifdef HAVE_OPENSSL
+
+ if( !this->data->handshakeCompleted ) {
+ this->startHandshake();
+ }
+
// Read data from the socket.
int result = SSL_read( this->data->ssl, buffer + offset, length );
@@ -408,6 +527,11 @@ void OpenSSLSocket::write( const unsigne
}
#ifdef HAVE_OPENSSL
+
+ if( !this->data->handshakeCompleted ) {
+ this->startHandshake();
+ }
+
int remaining = length;
while( remaining > 0 && !isClosed() ) {
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/ssl/openssl/OpenSSLSocket.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/de \
caf/internal/net/ssl/openssl/OpenSSLSocket.h?rev=948196&r1=948195&r2=948196&view=diff \
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/ssl/openssl/OpenSSLSocket.h \
(original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/internal/net/ssl/openssl/OpenSSLSocket.h \
Tue May 25 20:17:26 2010 @@ -133,6 +133,41 @@ namespace openssl {
*/
virtual void setEnabledProtocols( const std::vector<std::string>& protocols \
);
+ /**
+ * {@inheritDoc}
+ */
+ virtual void startHandshake();
+
+ /**
+ * {@inheritDoc}
+ */
+ virtual void setUseClientMode( bool value );
+
+ /**
+ * {@inheritDoc}
+ */
+ virtual bool getUseClientMode() const;
+
+ /**
+ * {@inheritDoc}
+ */
+ virtual void setNeedClientAuth( bool value );
+
+ /**
+ * {@inheritDoc}
+ */
+ virtual bool getNeedClientAuth() const;
+
+ /**
+ * {@inheritDoc}
+ */
+ virtual void setWantClientAuth( bool value );
+
+ /**
+ * {@inheritDoc}
+ */
+ virtual bool getWantClientAuth() const;
+
public:
/**
Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ssl/SSLSocket.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ssl/SSLSocket.h?rev=948196&r1=948195&r2=948196&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ssl/SSLSocket.h \
(original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/net/ssl/SSLSocket.h Tue \
May 25 20:17:26 2010 @@ -124,6 +124,86 @@ namespace ssl {
*/
virtual void setSSLParameters( const SSLParameters& value );
+ /**
+ * Initiates a handshake for this SSL Connection, this can be necessary for \
several reasons such + * as using new encryption keys, or starting a new \
session. + *
+ * When called for the first time after the socket connects this method \
blocks until the handshake + * is completed. The provider is not require to \
support multiple handshakes and can throw an + * IOException to indicate an \
error. + *
+ * @throw IOException if an I/O error occurs while performing the Handshake
+ */
+ virtual void startHandshake() = 0;
+
+ /**
+ * Determines the mode that the socket uses when a handshake is initiated, \
client or server. + *
+ * This method must be called prior to any handshake attempts on this \
Socket, once a handshake + * has be initiated this socket remains the the set \
mode; client or server, for the life of + * this object.
+ *
+ * @param value
+ * The mode setting, true for client or false for server.
+ *
+ * @throw IllegalArguementException if the handshake process has begun and \
mode is lcoked. + */
+ virtual void setUseClientMode( bool value ) = 0;
+
+ /**
+ * Gets whether this Socket is in Client or Server mode, true indicates that \
the mode is + * set to Client.
+ *
+ * @return true if the Socket is in Client mode, false otherwise.
+ */
+ virtual bool getUseClientMode() const = 0;
+
+ /**
+ * Sets the Socket to require that a client authenticate itself by sending a \
valid Certificate that + * is trusted by this Server mode socket. This \
option only applies to sockets in the Server mode. + *
+ * If the option is enabled an the client does not provide a certificate \
then the handshake is + * considered failed and the connection is refused. \
Calling this method resets any previous + * value for this option as well as \
clears any value set in the setWantClientAuth method. + *
+ * @param value
+ * The value indicating if a client is required to authenticate itself \
or not. + */
+ virtual void setNeedClientAuth( bool value ) = 0;
+
+ /**
+ * Returns if this socket is configured to require client authentication, \
true means that is has + * and that clients that failed to authenticate will \
be rejected. This option is only useful when + * the socket is operating in \
server mode. + *
+ * @return true if client authentication is required.
+ */
+ virtual bool getNeedClientAuth() const = 0;
+
+ /**
+ * Sets the Socket to request that a client authenticate itself by sending a \
valid Certificate that + * is trusted by this Server mode socket. This \
option only applies to sockets in the Server mode. + *
+ * If the option is enabled an the client does not provide a certificate \
then the handshake is + * considered to have succeeded, if it does send a \
certificate and that certificate is invalid the + * the handshake will fail. \
Calling this method resets any previous value for this option as well + * as \
clears any value set in the setNeedClientAuth method. + *
+ * @param value
+ * The value indicating if a client is requested to authenticate itself \
or not. + */
+ virtual void setWantClientAuth( bool value ) = 0;
+
+ /**
+ * Returns if this socket is configured to request client authentication, \
true means that is has + * and that clients that failed to authenticate will \
be rejected but that cleints that do not send + * a certificate are not \
considered to have failed authentication. This option is only useful when + \
* the socket is operating in server mode. + *
+ * @return true if client authentication is required.
+ */
+ virtual bool getWantClientAuth() const = 0;
+
};
}}}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic