diff options
author | Anthony Neal <aneal@zeroc.com> | 2002-03-05 14:26:38 +0000 |
---|---|---|
committer | Anthony Neal <aneal@zeroc.com> | 2002-03-05 14:26:38 +0000 |
commit | 088253dd72c4e65cf8230719def050d0d043aa92 (patch) | |
tree | b54fc12cc78cef3eca7c57de368c116dfa4307bb /cpp/src/Ice/SslConnectionOpenSSL.cpp | |
parent | bug fix for dispatching new operations (diff) | |
download | ice-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.cpp | 447 |
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) { |