summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/SslConnectionOpenSSL.cpp
diff options
context:
space:
mode:
authorAnthony Neal <aneal@zeroc.com>2002-03-05 14:26:38 +0000
committerAnthony Neal <aneal@zeroc.com>2002-03-05 14:26:38 +0000
commit088253dd72c4e65cf8230719def050d0d043aa92 (patch)
treeb54fc12cc78cef3eca7c57de368c116dfa4307bb /cpp/src/Ice/SslConnectionOpenSSL.cpp
parentbug fix for dispatching new operations (diff)
downloadice-088253dd72c4e65cf8230719def050d0d043aa92.tar.bz2
ice-088253dd72c4e65cf8230719def050d0d043aa92.tar.xz
ice-088253dd72c4e65cf8230719def050d0d043aa92.zip
Big check in. Glacier client authentication (certificate verification) has
been added, SSL logging has been removed, a few clean-ups have taken place. Getting ready for SSL Extension refactoring.
Diffstat (limited to 'cpp/src/Ice/SslConnectionOpenSSL.cpp')
-rw-r--r--cpp/src/Ice/SslConnectionOpenSSL.cpp447
1 files changed, 238 insertions, 209 deletions
diff --git a/cpp/src/Ice/SslConnectionOpenSSL.cpp b/cpp/src/Ice/SslConnectionOpenSSL.cpp
index 3b59201ccdd..3f64a2891f3 100644
--- a/cpp/src/Ice/SslConnectionOpenSSL.cpp
+++ b/cpp/src/Ice/SslConnectionOpenSSL.cpp
@@ -21,13 +21,13 @@
#include <string>
#include <sstream>
#include <Ice/Network.h>
-#include <Ice/OpenSSL.h>
+#include <Ice/OpenSSL.h>
#include <Ice/SecurityException.h>
#include <Ice/SslFactory.h>
#include <Ice/SslConnection.h>
#include <Ice/SslConnectionOpenSSL.h>
-#include <Ice/SslSystemOpenSSL.h>
-#include <Ice/SslCertificateVerifierOpenSSL.h>
+#include <Ice/SslSystemOpenSSL.h>
+#include <Ice/SslCertificateVerifierOpenSSL.h>
#include <Ice/SslOpenSSLUtils.h>
#include <Ice/TraceLevels.h>
@@ -36,129 +36,136 @@
using namespace std;
using namespace IceInternal;
+using Ice::SocketException;
+using Ice::TimeoutException;
+using Ice::ConnectionLostException;
+using Ice::LoggerPtr;
+using Ice::Int;
+
using std::endl;
using IceSecurity::Ssl::Factory;
using IceSecurity::Ssl::SystemPtr;
-
-////////////////////////////////////////////////
-////////// DefaultCertificateVerifier //////////
-////////////////////////////////////////////////
-
-IceSecurity::Ssl::OpenSSL::DefaultCertificateVerifier::DefaultCertificateVerifier()
-{
-}
-
-void
-IceSecurity::Ssl::OpenSSL::DefaultCertificateVerifier::setTraceLevels(const TraceLevelsPtr& traceLevels)
-{
- _traceLevels = traceLevels;
-}
-
-void
-IceSecurity::Ssl::OpenSSL::DefaultCertificateVerifier::setLogger(const LoggerPtr& logger)
-{
- _logger = logger;
-}
-
-int
-IceSecurity::Ssl::OpenSSL::DefaultCertificateVerifier::verify(int preVerifyOkay,
- X509_STORE_CTX* x509StoreContext,
- SSL* sslConnection)
-{
- //
- // Default verification steps.
- //
-
- int verifyError = X509_STORE_CTX_get_error(x509StoreContext);
- int errorDepth = X509_STORE_CTX_get_error_depth(x509StoreContext);
- int verifyDepth = SSL_get_verify_depth(sslConnection);
-
- // Verify Depth was set
- if (verifyError != X509_V_OK)
- {
- // If we have no errors so far, and the certificate chain is too long
- if ((verifyDepth != -1) && (verifyDepth < errorDepth))
- {
- verifyError = X509_V_ERR_CERT_CHAIN_TOO_LONG;
- }
-
- // If we have ANY errors, we bail out.
- preVerifyOkay = 0;
- }
-
- // Only if ICE_PROTOCOL level logging is on do we worry about this.
- if (_traceLevels->security >= IceSecurity::SECURITY_PROTOCOL)
- {
- char buf[256];
-
- X509* err_cert = X509_STORE_CTX_get_current_cert(x509StoreContext);
-
- X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
-
- ostringstream outStringStream;
-
- outStringStream << "depth = " << errorDepth << ":" << buf << endl;
-
- if (!preVerifyOkay)
- {
- outStringStream << "verify error: num = " << verifyError << " : "
- << X509_verify_cert_error_string(verifyError) << endl;
-
- }
-
- switch (verifyError)
- {
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- {
- X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, sizeof(buf));
- outStringStream << "issuer = " << buf << endl;
- break;
- }
-
- case X509_V_ERR_CERT_NOT_YET_VALID:
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- {
- outStringStream << "notBefore = " << getASN1time(X509_get_notBefore(err_cert)) << endl;
- break;
- }
-
- case X509_V_ERR_CERT_HAS_EXPIRED:
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- {
- outStringStream << "notAfter = " << getASN1time(X509_get_notAfter(err_cert)) << endl;
- break;
- }
- }
-
- outStringStream << "verify return = " << preVerifyOkay << endl;
-
- _logger->trace(_traceLevels->securityCat, outStringStream.str());
- }
-
- return preVerifyOkay;
-}
+
+////////////////////////////////////////////////
+////////// DefaultCertificateVerifier //////////
+////////////////////////////////////////////////
+
+IceSecurity::Ssl::OpenSSL::DefaultCertificateVerifier::DefaultCertificateVerifier()
+{
+}
+
+void
+IceSecurity::Ssl::OpenSSL::DefaultCertificateVerifier::setTraceLevels(const TraceLevelsPtr& traceLevels)
+{
+ _traceLevels = traceLevels;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::DefaultCertificateVerifier::setLogger(const LoggerPtr& logger)
+{
+ _logger = logger;
+}
+
+int
+IceSecurity::Ssl::OpenSSL::DefaultCertificateVerifier::verify(int preVerifyOkay,
+ X509_STORE_CTX* x509StoreContext,
+ SSL* sslConnection)
+{
+ //
+ // Default verification steps.
+ //
+
+ int verifyError = X509_STORE_CTX_get_error(x509StoreContext);
+ int errorDepth = X509_STORE_CTX_get_error_depth(x509StoreContext);
+ int verifyDepth = SSL_get_verify_depth(sslConnection);
+
+ // Verify Depth was set
+ if (verifyError != X509_V_OK)
+ {
+ // If we have no errors so far, and the certificate chain is too long
+ if ((verifyDepth != -1) && (verifyDepth < errorDepth))
+ {
+ verifyError = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+ X509_STORE_CTX_set_error(x509StoreContext, verifyError);
+ }
+
+ // If we have ANY errors, we bail out.
+ preVerifyOkay = 0;
+ }
+
+ // Only if ICE_PROTOCOL level logging is on do we worry about this.
+ if (_traceLevels->security >= IceSecurity::SECURITY_PROTOCOL)
+ {
+ char buf[256];
+
+ X509* err_cert = X509_STORE_CTX_get_current_cert(x509StoreContext);
+
+ X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
+
+ ostringstream outStringStream;
+
+ outStringStream << "depth = " << errorDepth << ":" << buf << endl;
+
+ if (!preVerifyOkay)
+ {
+ outStringStream << "verify error: num = " << verifyError << " : "
+ << X509_verify_cert_error_string(verifyError) << endl;
+
+ }
+
+ switch (verifyError)
+ {
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ {
+ X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, sizeof(buf));
+ outStringStream << "issuer = " << buf << endl;
+ break;
+ }
+
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ {
+ outStringStream << "notBefore = " << getASN1time(X509_get_notBefore(err_cert)) << endl;
+ break;
+ }
+
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ {
+ outStringStream << "notAfter = " << getASN1time(X509_get_notAfter(err_cert)) << endl;
+ break;
+ }
+ }
+
+ outStringStream << "verify return = " << preVerifyOkay << endl;
+
+ _logger->trace(_traceLevels->securityCat, outStringStream.str());
+ }
+
+ return preVerifyOkay;
+}
////////////////////////////////
////////// Connection //////////
////////////////////////////////
-
-//
-// Static Member Initialization
-//
-IceSecurity::Ssl::OpenSSL::SslConnectionMap IceSecurity::Ssl::OpenSSL::Connection::_connectionMap;
-::IceUtil::Mutex IceSecurity::Ssl::OpenSSL::Connection::_connectionRepositoryMutex;
+
+//
+// Static Member Initialization
+//
+IceSecurity::Ssl::OpenSSL::SslConnectionMap IceSecurity::Ssl::OpenSSL::Connection::_connectionMap;
+::IceUtil::Mutex IceSecurity::Ssl::OpenSSL::Connection::_connectionRepositoryMutex;
//
// Public Methods
//
-void ::IceInternal::incRef(::IceSecurity::Ssl::OpenSSL::Connection* p) { p->__incRef(); }
-void ::IceInternal::decRef(::IceSecurity::Ssl::OpenSSL::Connection* p) { p->__decRef(); }
-
-IceSecurity::Ssl::OpenSSL::Connection::Connection(const CertificateVerifierPtr& certificateVerifier,
- SSL* sslConnection,
- const SystemPtr& system) :
+void ::IceInternal::incRef(::IceSecurity::Ssl::OpenSSL::Connection* p) { p->__incRef(); }
+void ::IceInternal::decRef(::IceSecurity::Ssl::OpenSSL::Connection* p) { p->__decRef(); }
+
+IceSecurity::Ssl::OpenSSL::Connection::Connection(const CertificateVerifierPtr& certificateVerifier,
+ SSL* sslConnection,
+ const SystemPtr& system) :
IceSecurity::Ssl::Connection(certificateVerifier),
_sslConnection(sslConnection),
_system(system)
@@ -173,17 +180,17 @@ IceSecurity::Ssl::OpenSSL::Connection::Connection(const CertificateVerifierPtr&
_initWantWrite = 0;
// None configured, default to indicated timeout
- _handshakeReadTimeout = 0;
-
- // Set up the SSL to be able to refer back to our connection object.
- addConnection(_sslConnection, this);
+ _handshakeReadTimeout = 0;
+
+ // Set up the SSL to be able to refer back to our connection object.
+ addConnection(_sslConnection, this);
}
IceSecurity::Ssl::OpenSSL::Connection::~Connection()
{
if (_sslConnection != 0)
{
- removeConnection(_sslConnection);
+ removeConnection(_sslConnection);
Factory::removeSystemHandle(_sslConnection);
SSL_free(_sslConnection);
_sslConnection = 0;
@@ -195,13 +202,13 @@ IceSecurity::Ssl::OpenSSL::Connection::shutdown()
{
if (_sslConnection != 0)
{
- if (_traceLevels->security >= IceSecurity::SECURITY_WARNINGS)
- {
- _logger->trace(_traceLevels->securityCat, "WRN " +
- string("shutting down SSL connection\n") +
- fdToString(SSL_get_fd(_sslConnection)));
- }
-
+ if (_traceLevels->security >= IceSecurity::SECURITY_WARNINGS)
+ {
+ _logger->trace(_traceLevels->securityCat, "WRN " +
+ string("shutting down SSL connection\n") +
+ fdToString(SSL_get_fd(_sslConnection)));
+ }
+
int shutdown = 0;
int retries = 100;
@@ -217,64 +224,85 @@ IceSecurity::Ssl::OpenSSL::Connection::shutdown()
ostringstream s;
s << "SSL shutdown failure encountered: code[" << shutdown << "] retries[";
s << retries << "]\n" << fdToString(SSL_get_fd(_sslConnection));
- _logger->trace(_traceLevels->securityCat, s.str());
+ _logger->trace(_traceLevels->securityCat, s.str());
+ }
+ }
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::setTrace(const TraceLevelsPtr& traceLevels)
+{
+ _traceLevels = traceLevels;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::setLogger(const LoggerPtr& traceLevels)
+{
+ _logger = traceLevels;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::setHandshakeReadTimeout(int timeout)
+{
+ _handshakeReadTimeout = timeout;
+}
+
+IceSecurity::Ssl::OpenSSL::ConnectionPtr
+IceSecurity::Ssl::OpenSSL::Connection::getConnection(SSL* sslPtr)
+{
+ IceUtil::Mutex::Lock sync(_connectionRepositoryMutex);
+
+ assert(sslPtr);
+
+ Connection* connection = _connectionMap[sslPtr];
+
+ assert(connection);
+
+ return ConnectionPtr(connection);
+}
+
+int
+IceSecurity::Ssl::OpenSSL::Connection::verifyCertificate(int preVerifyOkay, X509_STORE_CTX* x509StoreContext)
+{
+ // Should NEVER be able to happen.
+ assert(_certificateVerifier.get() != 0);
+
+ // Get the verifier, make sure it is for OpenSSL connections
+ IceSecurity::Ssl::OpenSSL::CertificateVerifier* verifier;
+ verifier = dynamic_cast<IceSecurity::Ssl::OpenSSL::CertificateVerifier*>(_certificateVerifier.get());
+
+ // Check to make sure we have a proper verifier for the operation.
+ if (verifier)
+ {
+ // Use the verifier to verify the certificate
+ preVerifyOkay = verifier->verify(preVerifyOkay, x509StoreContext, _sslConnection);
+ }
+ else
+ {
+ // Note: This code should NEVER be able to be reached, as we check each
+ // CertificateVerifier as it is added to the System.
+
+ if (_traceLevels->security >= IceSecurity::SECURITY_WARNINGS)
+ {
+ string errorString;
+
+ if (_certificateVerifier.get())
+ {
+ errorString = "WRN Improper CertificateVerifier type.";
+ }
+ else
+ {
+ // NOTE: This should NEVER be able to happen, but just in case.
+ errorString = "WRN CertificateVerifier not set.";
+ }
+
+ _logger->trace(_traceLevels->securityCat, errorString);
}
}
+
+ return preVerifyOkay;
}
-void
-IceSecurity::Ssl::OpenSSL::Connection::setTrace(const TraceLevelsPtr& traceLevels)
-{
- _traceLevels = traceLevels;
-}
-
-void
-IceSecurity::Ssl::OpenSSL::Connection::setLogger(const LoggerPtr& traceLevels)
-{
- _logger = traceLevels;
-}
-
-void
-IceSecurity::Ssl::OpenSSL::Connection::setHandshakeReadTimeout(int timeout)
-{
- _handshakeReadTimeout = timeout;
-}
-
-IceSecurity::Ssl::OpenSSL::ConnectionPtr
-IceSecurity::Ssl::OpenSSL::Connection::getConnection(SSL* sslPtr)
-{
- IceUtil::Mutex::Lock sync(_connectionRepositoryMutex);
-
- assert(sslPtr);
-
- Connection* connection = _connectionMap[sslPtr];
-
- assert(connection);
-
- return ConnectionPtr(connection);
-}
-
-int
-IceSecurity::Ssl::OpenSSL::Connection::verifyCertificate(int preVerifyOkay, X509_STORE_CTX* x509StoreContext)
-{
- // Get the verifier, make sure it is for OpenSSL connections
- IceSecurity::Ssl::OpenSSL::CertificateVerifier* verifier;
- verifier = dynamic_cast<IceSecurity::Ssl::OpenSSL::CertificateVerifier*>(_certificateVerifier.get());
-
- // Check to make sure we have a proper verifier for the operation.
- if (!verifier)
- {
- // TODO: Throw exception here
- // throw SslIncorrectVerifierTypeException(__FILE__, __LINE__);
- return 0;
- }
-
- // Use the verifier to verify the certificate
- preVerifyOkay = verifier->verify(preVerifyOkay, x509StoreContext, _sslConnection);
-
- return preVerifyOkay;
-}
-
//
// Protected Methods
//
@@ -309,7 +337,7 @@ int
IceSecurity::Ssl::OpenSSL::Connection::initialize(int timeout)
{
int retCode = 0;
-
+
while (true)
{
// One lucky thread will get the honor of carrying out the hanshake,
@@ -421,12 +449,11 @@ IceSecurity::Ssl::OpenSSL::Connection::readInBuffer(Buffer& buf)
if (_traceLevels->security >= IceSecurity::SECURITY_PROTOCOL)
{
- string protocolString = "Copied ";
- protocolString += Int(bytesRead);
- protocolString += string(" bytes from SSL buffer\n");
- protocolString += fdToString(SSL_get_fd(_sslConnection));
-
- _logger->trace(_traceLevels->securityCat, protocolString);
+ ostringstream protocolMsg;
+ protocolMsg << "Copied " << dec << bytesRead << " bytes from SSL buffer\n";
+ protocolMsg << fdToString(SSL_get_fd(_sslConnection));
+
+ _logger->trace(_traceLevels->securityCat, protocolMsg.str());
}
}
@@ -544,6 +571,7 @@ IceSecurity::Ssl::OpenSSL::Connection::readSSL(Buffer& buf, int timeout)
if (initReturn == -1)
{
// Handshake underway, timeout immediately, easy way to deal with this.
+ // _logger->trace(_traceLevels->securityCat, "Throwing TimeoutException, Line 566");
throw TimeoutException(__FILE__, __LINE__);
}
@@ -566,10 +594,10 @@ IceSecurity::Ssl::OpenSSL::Connection::readSSL(Buffer& buf, int timeout)
if (!bytesPending)
{
- if (_traceLevels->security >= IceSecurity::SECURITY_PROTOCOL)
- {
- _logger->trace(_traceLevels->securityCat, "No pending application-level bytes.");
- }
+ if (_traceLevels->security >= IceSecurity::SECURITY_PROTOCOL)
+ {
+ _logger->trace(_traceLevels->securityCat, "No pending application-level bytes.");
+ }
// We're done here.
break;
@@ -663,7 +691,7 @@ IceSecurity::Ssl::OpenSSL::Connection::readSSL(Buffer& buf, int timeout)
// Protocol Error: Unexpected EOF
protocolEx._message = "Encountered an EOF that violates the SSL Protocol.\n";
- protocolEx._message += sslGetErrors();
+ protocolEx._message += sslGetErrors();
throw protocolEx;
}
@@ -674,7 +702,7 @@ IceSecurity::Ssl::OpenSSL::Connection::readSSL(Buffer& buf, int timeout)
ProtocolException protocolEx(__FILE__, __LINE__);
protocolEx._message = "Encountered a violation of the SSL Protocol.\n";
- protocolEx._message += sslGetErrors();
+ protocolEx._message += sslGetErrors();
throw protocolEx;
}
@@ -737,23 +765,24 @@ IceSecurity::Ssl::OpenSSL::Connection::sslGetErrors()
return errorMessage;
}
-
-void
-IceSecurity::Ssl::OpenSSL::Connection::addConnection(SSL* sslPtr, Connection* connection)
-{
- assert(sslPtr);
- assert(connection);
- _connectionMap[sslPtr] = connection;
-}
-
-void
-IceSecurity::Ssl::OpenSSL::Connection::removeConnection(SSL* sslPtr)
-{
- IceUtil::Mutex::Lock sync(_connectionRepositoryMutex);
- assert(sslPtr);
- _connectionMap.erase(sslPtr);
-}
-
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::addConnection(SSL* sslPtr, Connection* connection)
+{
+ assert(sslPtr);
+ assert(connection);
+ IceUtil::Mutex::Lock sync(_connectionRepositoryMutex);
+ _connectionMap[sslPtr] = connection;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::removeConnection(SSL* sslPtr)
+{
+ assert(sslPtr);
+ IceUtil::Mutex::Lock sync(_connectionRepositoryMutex);
+ _connectionMap.erase(sslPtr);
+}
+
void
IceSecurity::Ssl::OpenSSL::Connection::showCertificateChain(BIO* bio)
{