diff options
Diffstat (limited to 'cpp/src')
37 files changed, 6472 insertions, 6118 deletions
diff --git a/cpp/src/Ice/Makefile b/cpp/src/Ice/Makefile index 56fb40fc63f..f09445e3505 100644 --- a/cpp/src/Ice/Makefile +++ b/cpp/src/Ice/Makefile @@ -90,11 +90,11 @@ SLICECMD = $(SLICE2CPP) --include-dir Ice --dll-export ICE_API -I$(slicedir) include $(top_srcdir)/config/Make.rules -CPPFLAGS := -I.. $(CPPFLAGS) -I$(OPENSSL)/include -I$(XERCESC)/include/xercesc -DUSE_SOCKETS -DSSL_EXTENSION +CPPFLAGS := -I.. $(CPPFLAGS) -I$(OPENSSL)/include -I$(XERCESC)/include/xercesc $(VERSIONED_NAME): $(OBJS) rm -f $@ - $(CXX) $(CXXFLAGS) -DUSE_SOCKETS -DSSL_EXTENSION $(LDFLAGS) -shared \ + $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared \ -o $@ $(OBJS) $(NAME): $(VERSIONED_NAME) diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp index 86dbf9bfea4..a6ebb4a2ffd 100644 --- a/cpp/src/Ice/ObjectAdapterI.cpp +++ b/cpp/src/Ice/ObjectAdapterI.cpp @@ -361,8 +361,17 @@ Ice::ObjectAdapterI::newProxy(const string& ident) transform(_collectorFactories.begin(), _collectorFactories.end(), back_inserter(endpoints), Ice::constMemFun(&CollectorFactory::endpoint)); - ReferencePtr reference = new Reference(_instance, ident, "", Reference::ModeTwoway, false, endpoints, endpoints); - return _instance->proxyFactory()->referenceToProxy(reference); + // TODO: This is a bandaid, and should be replaced by a better approach.
+ bool makeSecure = false;
+ size_t numSecureEndpoints = count_if(endpoints.begin(), endpoints.end(), Ice::constMemFun(&Endpoint::secure));
+
+ if (numSecureEndpoints >= endpoints.size())
+ {
+ makeSecure = true;
+ }
+
+ ReferencePtr reference = new Reference(_instance, ident, "", Reference::ModeTwoway, makeSecure /* false */, endpoints, endpoints);
+ return _instance->proxyFactory()->referenceToProxy(reference);
} bool diff --git a/cpp/src/Ice/Security.h b/cpp/src/Ice/Security.h index 8e3944cb239..b5a04542abf 100644 --- a/cpp/src/Ice/Security.h +++ b/cpp/src/Ice/Security.h @@ -1,92 +1,141 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** -#ifndef ICE_SECURITY_H -#define ICE_SECURITY_H - -// NOTE: Define USE_SOCKETS in order to turn on use of sockets in OpenSSL -#ifndef USE_SOCKETS -#define USE_SOCKETS -#endif - -#include <openssl/ssl.h> - -namespace IceSecurity -{ - -typedef enum -{ - NO_SECURITY_TRACE = 0, - SECURITY_WARNINGS, - SECURITY_PARSE_WARNINGS, - SECURITY_METHODS, - SECURITY_EXCEPTIONS, - SECURITY_PROTOCOL, - SECURITY_PROTOCOL_DEBUG -} SecurityTraceLevel; - -} - -#define SECURITY_LEVEL_METHODS (_traceLevels->security >= IceSecurity::SECURITY_METHODS) -#define SECURITY_LEVEL_PARSEWARNINGS (_traceLevels->security >= IceSecurity::SECURITY_PARSE_WARNINGS) -#define SECURITY_LEVEL_WARNINGS (_traceLevels->security >= IceSecurity::SECURITY_WARNINGS) -#define SECURITY_LEVEL_EXCEPTIONS (_traceLevels->security >= IceSecurity::SECURITY_EXCEPTIONS) -#define SECURITY_LEVEL_PROTOCOL (_traceLevels->security >= IceSecurity::SECURITY_PROTOCOL) -#define SECURITY_LEVEL_PROTOCOL_DEBUG (_traceLevels->security >= IceSecurity::SECURITY_PROTOCOL_DEBUG) - -#define SECURITY_LOGGER(s) _logger->trace(_traceLevels->securityCat, s); - -#define METHOD_INV(s) \ - if (_traceLevels->security >= IceSecurity::SECURITY_METHODS) \ - { \ - _logger->trace(_traceLevels->securityCat, "INV " + string(s)); \ - } - -#define METHOD_INS(s) \ - if (_traceLevels->security >= IceSecurity::SECURITY_METHODS) \ - { \ - _logger->trace(_traceLevels->securityCat, "INS " + string(s)); \ - } - -#define METHOD_RET(s) \ - if (_traceLevels->security >= IceSecurity::SECURITY_METHODS) \ - { \ - _logger->trace(_traceLevels->securityCat, "RET " + string(s)); \ - } - -#define PARSE_WARNING(s) \ - if (_traceLevels->security >= IceSecurity::SECURITY_PARSE_WARNINGS) \ - { \ - _logger->trace(_traceLevels->securityCat, "PWN " + string(s)); \ - } - -#define WARNING(s) \ - if (_traceLevels->security >= IceSecurity::SECURITY_WARNINGS) \ - { \ - _logger->trace(_traceLevels->securityCat, "WRN " + string(s)); \ - } - -#define EXCEPTION(s) \ - if (_traceLevels->security >= IceSecurity::SECURITY_EXCEPTIONS) \ - { \ - _logger->trace(_traceLevels->securityCat, "EXC " + string(s)); \ - } - -#define PROTOCOL(s) \ - if (_traceLevels->security >= IceSecurity::SECURITY_PROTOCOL) \ - { \ - _logger->trace(_traceLevels->securityCat, "PTL " + string(s)); \ - } - -#define PROTOCOL_DEBUG(s) \ - if (_traceLevels->security >= IceSecurity::SECURITY_PROTOCOL_DEBUG) \ - { \ - _logger->trace(_traceLevels->securityCat, "DBG " + string(s)); \ - } -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+#ifndef ICE_SECURITY_H
+#define ICE_SECURITY_H
+
+// NOTE: Define USE_SOCKETS in order to turn on use of sockets in OpenSSL
+#ifndef USE_SOCKETS
+#define USE_SOCKETS
+#endif
+
+#include <openssl/ssl.h>
+
+namespace IceSecurity
+{
+
+typedef enum
+{
+ NO_SECURITY_TRACE = 0,
+ SECURITY_WARNINGS,
+ SECURITY_PARSE_WARNINGS,
+ SECURITY_METHODS,
+ SECURITY_EXCEPTIONS,
+ SECURITY_PROTOCOL,
+ SECURITY_PROTOCOL_DEBUG
+} SecurityTraceLevel;
+
+}
+
+#define ICE_SECURITY_LOGGER(s) _logger->trace(_traceLevels->securityCat, s);
+
+#ifdef ICE_SECURITY_DEBUG
+
+#define ICE_SECURITY_LEVEL_METHODS (_traceLevels->security >= IceSecurity::SECURITY_METHODS)
+#define ICE_SECURITY_LEVEL_PARSEWARNINGS (_traceLevels->security >= IceSecurity::SECURITY_PARSE_WARNINGS)
+#define ICE_SECURITY_LEVEL_WARNINGS (_traceLevels->security >= IceSecurity::SECURITY_WARNINGS)
+#define ICE_SECURITY_LEVEL_EXCEPTIONS (_traceLevels->security >= IceSecurity::SECURITY_EXCEPTIONS)
+#define ICE_SECURITY_LEVEL_PROTOCOL (_traceLevels->security >= IceSecurity::SECURITY_PROTOCOL)
+#define ICE_SECURITY_LEVEL_PROTOCOL_DEBUG (_traceLevels->security >= IceSecurity::SECURITY_PROTOCOL_DEBUG)
+
+#define ICE_SECURITY_LEVEL_PROTOCOL_GLOBAL \
+ (IceSecurity::Ssl::OpenSSL::System::_globalTraceLevels->security >= IceSecurity::SECURITY_PROTOCOL)
+
+#define ICE_METHOD_INV(s) \
+ if (ICE_SECURITY_LEVEL_METHODS) \
+ { \
+ ICE_SECURITY_LOGGER("INV " + string(s)); \
+ }
+
+#define ICE_METHOD_INS(s) \
+ if (ICE_SECURITY_LEVEL_METHODS) \
+ { \
+ ICE_SECURITY_LOGGER("INS " + string(s)); \
+ }
+
+#define ICE_METHOD_RET(s) \
+ if (ICE_SECURITY_LEVEL_METHODS) \
+ { \
+ ICE_SECURITY_LOGGER("RET " + string(s)); \
+ }
+
+#define ICE_PARSE_WARNING(s) \
+ if (ICE_SECURITY_LEVEL_PARSEWARNINGS) \
+ { \
+ ICE_SECURITY_LOGGER("PWN " + string(s)); \
+ }
+
+#define ICE_WARNING(s) \
+ if (ICE_SECURITY_LEVEL_WARNINGS) \
+ { \
+ ICE_SECURITY_LOGGER("WRN " + string(s)); \
+ }
+
+#define ICE_EXCEPTION(s) \
+ if (ICE_SECURITY_LEVEL_EXCEPTIONS) \
+ { \
+ ICE_SECURITY_LOGGER("EXC " + string(s)); \
+ }
+
+#define ICE_PROTOCOL(s) \
+ if (ICE_SECURITY_LEVEL_PROTOCOL) \
+ { \
+ ICE_SECURITY_LOGGER("PTL " + string(s)); \
+ }
+
+#define ICE_PROTOCOL_DEBUG(s) \
+ if (ICE_SECURITY_LEVEL_PROTOCOL_DEBUG) \
+ { \
+ ICE_SECURITY_LOGGER("DBG " + string(s)); \
+ }
+
+#else
+
+#define ICE_SECURITY_LEVEL_METHODS false
+#define ICE_SECURITY_LEVEL_PARSEWARNINGS (_traceLevels->security >= IceSecurity::SECURITY_PARSE_WARNINGS)
+#define ICE_SECURITY_LEVEL_WARNINGS (_traceLevels->security >= IceSecurity::SECURITY_WARNINGS)
+#define ICE_SECURITY_LEVEL_EXCEPTIONS false
+#define ICE_SECURITY_LEVEL_PROTOCOL false
+#define ICE_SECURITY_LEVEL_PROTOCOL_DEBUG false
+#define ICE_SECURITY_LEVEL_PROTOCOL_GLOBAL false
+
+#define ICE_METHOD_INV(s)
+#define ICE_METHOD_INS(s)
+#define ICE_METHOD_RET(s)
+
+#define ICE_PARSE_WARNING(s) \
+ if (ICE_SECURITY_LEVEL_PARSEWARNINGS) \
+ { \
+ ICE_SECURITY_LOGGER("PWN " + string(s)); \
+ }
+
+#define ICE_WARNING(s) \
+ if (ICE_SECURITY_LEVEL_WARNINGS) \
+ { \
+ ICE_SECURITY_LOGGER("WRN " + string(s)); \
+ }
+
+#define ICE_EXCEPTION(s)
+#define ICE_PROTOCOL(s)
+#define ICE_PROTOCOL_DEBUG(s)
+
+#endif
+
+#define ICE_SSLERRORS(s) \
+ if (!s.empty()) \
+ { \
+ s += "\n"; \
+ s += sslGetErrors(); \
+ } \
+ else \
+ { \
+ s = sslGetErrors(); \
+ }
+
+#endif
diff --git a/cpp/src/Ice/SslAcceptor.cpp b/cpp/src/Ice/SslAcceptor.cpp index a1aeac543f0..194fa5188a5 100644 --- a/cpp/src/Ice/SslAcceptor.cpp +++ b/cpp/src/Ice/SslAcceptor.cpp @@ -7,13 +7,13 @@ // All Rights Reserved // // ********************************************************************** -#ifdef WIN32 -#pragma warning(disable:4786) -#endif +#ifdef WIN32
+#pragma warning(disable:4786)
+#endif
-#include <Ice/SslFactory.h> -#include <Ice/SslSystem.h> -#include <Ice/Properties.h> +#include <Ice/SslFactory.h>
+#include <Ice/SslSystem.h>
+#include <Ice/Properties.h>
#include <Ice/SslAcceptor.h> #include <Ice/SslTransceiver.h> #include <Ice/Instance.h> @@ -21,20 +21,20 @@ #include <Ice/Logger.h> #include <Ice/Network.h> #include <Ice/Exception.h> -#include <Ice/SslException.h> -#include <sstream> +#include <Ice/SslException.h>
+#include <sstream>
using namespace std; using namespace Ice; using namespace IceInternal; -using std::string; -using std::ostringstream; -using IceSecurity::Ssl::Connection; -using IceSecurity::Ssl::Factory; -using IceSecurity::Ssl::System; -using IceSecurity::Ssl::ShutdownException; - +using std::string;
+using std::ostringstream;
+using IceSecurity::Ssl::Connection;
+using IceSecurity::Ssl::Factory;
+using IceSecurity::Ssl::System;
+using IceSecurity::Ssl::ShutdownException;
+
int IceInternal::SslAcceptor::fd() { @@ -101,51 +101,58 @@ IceInternal::SslAcceptor::accept(int timeout) s << "accepted ssl connection\n" << fdToString(fd); _logger->trace(_traceLevels->networkCat, s.str()); } - - // This is the Ice SSL Configuration File on which we will base - // all connections in this communicator. - string configFile = _instance->properties()->getProperty("Ice.Ssl.Config"); - - // Get an instance of the SslSystem singleton. - System* sslSystem = Factory::getSystem(configFile); - - if (!sslSystem->isTraceSet()) - { - sslSystem->setTrace(_traceLevels); - } - - if (!sslSystem->isLoggerSet()) - { - sslSystem->setLogger(_logger); - } - - // Initialize the server (if needed) - if (!sslSystem->isConfigLoaded()) - { - sslSystem->loadConfig(); - } - - Connection* sslConnection = 0; - - try - { - sslConnection = sslSystem->createServerConnection(fd); - } - catch (...) +
+ PropertiesPtr properties = _instance->properties();
+ + // This is the Ice SSL Configuration File on which we will base
+ // all connections in this communicator.
+ string configFile = properties->getProperty("Ice.Ssl.Config");
+
+ // Get an instance of the SslSystem singleton.
+ System* sslSystem = Factory::getSystem(configFile);
+
+ if (!sslSystem->isTraceSet())
+ {
+ sslSystem->setTrace(_traceLevels);
+ }
+
+ if (!sslSystem->isLoggerSet())
+ {
+ sslSystem->setLogger(_logger);
+ }
+
+ if (!sslSystem->isPropertiesSet())
+ {
+ sslSystem->setProperties(properties);
+ }
+
+ // Initialize the server (if needed)
+ if (!sslSystem->isConfigLoaded())
+ {
+ sslSystem->loadConfig();
+ }
+
+ Connection* sslConnection = 0;
+
+ try
{ - Factory::releaseSystem(sslSystem); - sslSystem = 0; - - // Shutdown the connection. - throw; - } - - TransceiverPtr transPtr = new SslTransceiver(_instance, fd, sslConnection); - - Factory::releaseSystem(sslSystem); - sslSystem = 0; - - return transPtr; + sslConnection = sslSystem->createServerConnection(fd);
+ }
+ catch (...)
+ {
+ Factory::releaseSystem(sslSystem);
+ sslSystem = 0;
+
+ // Shutdown the connection.
+ throw;
+ }
+
+ TransceiverPtr transPtr = new SslTransceiver(_instance, fd, sslConnection);
+
+ Factory::releaseSystem(sslSystem);
+ sslSystem = 0;
+ + return transPtr;
} string diff --git a/cpp/src/Ice/SslBaseCerts.cpp b/cpp/src/Ice/SslBaseCerts.cpp index eb2ace00b13..ad5ddb34488 100644 --- a/cpp/src/Ice/SslBaseCerts.cpp +++ b/cpp/src/Ice/SslBaseCerts.cpp @@ -1,34 +1,34 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include <Ice/SslBaseCerts.h> - -using namespace IceSecurity::Ssl; - -IceSecurity::Ssl::BaseCertificates::BaseCertificates() -{ -} - -IceSecurity::Ssl::BaseCertificates::BaseCertificates(CertificateDesc& rsaCert, - CertificateDesc& dsaCert, - DiffieHellmanParamsFile& dhParams) : - _rsaCert(rsaCert), - _dsaCert(dsaCert), - _dhParams(dhParams) -{ -} - -IceSecurity::Ssl::BaseCertificates::BaseCertificates(BaseCertificates& baseCerts) : - _rsaCert(baseCerts._rsaCert), - _dsaCert(baseCerts._dsaCert), - _dhParams(baseCerts._dhParams) -{ -} - +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/SslBaseCerts.h>
+
+using namespace IceSecurity::Ssl;
+
+IceSecurity::Ssl::BaseCertificates::BaseCertificates()
+{
+}
+
+IceSecurity::Ssl::BaseCertificates::BaseCertificates(CertificateDesc& rsaCert,
+ CertificateDesc& dsaCert,
+ DiffieHellmanParamsFile& dhParams) :
+ _rsaCert(rsaCert),
+ _dsaCert(dsaCert),
+ _dhParams(dhParams)
+{
+}
+
+IceSecurity::Ssl::BaseCertificates::BaseCertificates(BaseCertificates& baseCerts) :
+ _rsaCert(baseCerts._rsaCert),
+ _dsaCert(baseCerts._dsaCert),
+ _dhParams(baseCerts._dhParams)
+{
+}
+
diff --git a/cpp/src/Ice/SslBaseCerts.h b/cpp/src/Ice/SslBaseCerts.h index b423813441e..840112324ba 100644 --- a/cpp/src/Ice/SslBaseCerts.h +++ b/cpp/src/Ice/SslBaseCerts.h @@ -1,75 +1,75 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_SSL_BASE_CERTS_H -#define ICE_SSL_BASE_CERTS_H - -#include <Ice/SslCertificateDesc.h> -#include <ostream> - -namespace IceSecurity -{ - -namespace Ssl -{ - -class BaseCertificates -{ - -public: - BaseCertificates(); - BaseCertificates(CertificateDesc&, CertificateDesc&, DiffieHellmanParamsFile&); - BaseCertificates(BaseCertificates&); - - inline const CertificateDesc& getRSACert() const { return _rsaCert; }; - inline const CertificateDesc& getDSACert() const { return _dsaCert; }; - - inline const DiffieHellmanParamsFile& getDHParams() const { return _dhParams; }; - -protected: - CertificateDesc _rsaCert; - CertificateDesc _dsaCert; - DiffieHellmanParamsFile _dhParams; -}; - -using std::endl; - -template<class Stream> -inline Stream& operator << (Stream& target, const BaseCertificates& baseCerts) -{ - if (baseCerts.getRSACert().getKeySize() != 0) - { - target << "RSA\n{" << endl; - target << baseCerts.getRSACert(); - target << "}\n" << endl; - } - - if (baseCerts.getDSACert().getKeySize() != 0) - { - target << "DSA\n{" << endl; - target << baseCerts.getDSACert(); - target << "}\n" << endl; - } - - if (baseCerts.getDHParams().getKeySize() != 0) - { - target << "DH\n{" << endl; - target << baseCerts.getDHParams(); - target << "}\n" << endl; - } - - return target; -} - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_BASE_CERTS_H
+#define ICE_SSL_BASE_CERTS_H
+
+#include <Ice/SslCertificateDesc.h>
+#include <ostream>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+class BaseCertificates
+{
+
+public:
+ BaseCertificates();
+ BaseCertificates(CertificateDesc&, CertificateDesc&, DiffieHellmanParamsFile&);
+ BaseCertificates(BaseCertificates&);
+
+ inline const CertificateDesc& getRSACert() const { return _rsaCert; };
+ inline const CertificateDesc& getDSACert() const { return _dsaCert; };
+
+ inline const DiffieHellmanParamsFile& getDHParams() const { return _dhParams; };
+
+protected:
+ CertificateDesc _rsaCert;
+ CertificateDesc _dsaCert;
+ DiffieHellmanParamsFile _dhParams;
+};
+
+using std::endl;
+
+template<class Stream>
+inline Stream& operator << (Stream& target, const BaseCertificates& baseCerts)
+{
+ if (baseCerts.getRSACert().getKeySize() != 0)
+ {
+ target << "RSA\n{" << endl;
+ target << baseCerts.getRSACert();
+ target << "}\n" << endl;
+ }
+
+ if (baseCerts.getDSACert().getKeySize() != 0)
+ {
+ target << "DSA\n{" << endl;
+ target << baseCerts.getDSACert();
+ target << "}\n" << endl;
+ }
+
+ if (baseCerts.getDHParams().getKeySize() != 0)
+ {
+ target << "DH\n{" << endl;
+ target << baseCerts.getDHParams();
+ target << "}\n" << endl;
+ }
+
+ return target;
+}
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslCertificateAuthority.cpp b/cpp/src/Ice/SslCertificateAuthority.cpp index 9247819d4e5..0c1a42146ed 100644 --- a/cpp/src/Ice/SslCertificateAuthority.cpp +++ b/cpp/src/Ice/SslCertificateAuthority.cpp @@ -1,41 +1,41 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include <Ice/SslCertificateAuthority.h> - -using namespace std; - -IceSecurity::Ssl::CertificateAuthority::CertificateAuthority() -{ -} - -IceSecurity::Ssl::CertificateAuthority::CertificateAuthority(string& fileName, string& path) : - _fileName(fileName), - _path(path) -{ -} - -IceSecurity::Ssl::CertificateAuthority::CertificateAuthority(CertificateAuthority& certAuthority) : - _fileName(certAuthority._fileName), - _path(certAuthority._path) -{ -} - -void -IceSecurity::Ssl::CertificateAuthority::setCAFileName(string& fileName) -{ - _fileName = fileName; -} - -void -IceSecurity::Ssl::CertificateAuthority::setCAPath(string& caPath) -{ - _path = caPath; -} +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/SslCertificateAuthority.h>
+
+using namespace std;
+
+IceSecurity::Ssl::CertificateAuthority::CertificateAuthority()
+{
+}
+
+IceSecurity::Ssl::CertificateAuthority::CertificateAuthority(string& fileName, string& path) :
+ _fileName(fileName),
+ _path(path)
+{
+}
+
+IceSecurity::Ssl::CertificateAuthority::CertificateAuthority(CertificateAuthority& certAuthority) :
+ _fileName(certAuthority._fileName),
+ _path(certAuthority._path)
+{
+}
+
+void
+IceSecurity::Ssl::CertificateAuthority::setCAFileName(string& fileName)
+{
+ _fileName = fileName;
+}
+
+void
+IceSecurity::Ssl::CertificateAuthority::setCAPath(string& caPath)
+{
+ _path = caPath;
+}
diff --git a/cpp/src/Ice/SslCertificateAuthority.h b/cpp/src/Ice/SslCertificateAuthority.h index 1cd72d3a482..69452024235 100644 --- a/cpp/src/Ice/SslCertificateAuthority.h +++ b/cpp/src/Ice/SslCertificateAuthority.h @@ -1,47 +1,47 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_SSL_CERTIFICATE_AUTHORITY_H -#define ICE_SSL_CERTIFICATE_AUTHORITY_H - -#include <string> - -namespace IceSecurity -{ - -namespace Ssl -{ - -using namespace std; - -class CertificateAuthority -{ - -public: - CertificateAuthority(); - CertificateAuthority(string&, string&); - CertificateAuthority(CertificateAuthority&); - - void setCAFileName(string&); - void setCAPath(string&); - - inline const string& getCAFileName() const { return _fileName; }; - inline const string& getCAPath() const { return _path; }; - -private: - string _fileName; - string _path; -}; - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_CERTIFICATE_AUTHORITY_H
+#define ICE_SSL_CERTIFICATE_AUTHORITY_H
+
+#include <string>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+using namespace std;
+
+class CertificateAuthority
+{
+
+public:
+ CertificateAuthority();
+ CertificateAuthority(string&, string&);
+ CertificateAuthority(CertificateAuthority&);
+
+ void setCAFileName(string&);
+ void setCAPath(string&);
+
+ inline const string& getCAFileName() const { return _fileName; };
+ inline const string& getCAPath() const { return _path; };
+
+private:
+ string _fileName;
+ string _path;
+};
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslCertificateDesc.cpp b/cpp/src/Ice/SslCertificateDesc.cpp index 73e636292d4..cc1d8e1f2e4 100644 --- a/cpp/src/Ice/SslCertificateDesc.cpp +++ b/cpp/src/Ice/SslCertificateDesc.cpp @@ -1,92 +1,92 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** -#ifdef WIN32 -#pragma warning(disable:4786) -#endif - -#include <openssl/ssl.h> -#include <Ice/SslCertificateDesc.h> - -using namespace std; -using namespace IceSecurity::Ssl; - -///////////////////////// -//// CertificateFile //// -///////////////////////// - -IceSecurity::Ssl::CertificateFile::CertificateFile() : - _fileName(""), - _encoding(0) -{ -} - -IceSecurity::Ssl::CertificateFile::CertificateFile(const string& filename, const int encoding) : - _fileName(filename), - _encoding(encoding) -{ -} - -IceSecurity::Ssl::CertificateFile::CertificateFile(const CertificateFile& certFile) : - _fileName(certFile._fileName), - _encoding(certFile._encoding) -{ -} - -///////////////////////////////// -//// DiffieHellmanParamsFile //// -///////////////////////////////// - -IceSecurity::Ssl::DiffieHellmanParamsFile::DiffieHellmanParamsFile() : - CertificateFile(), - _keySize(0) -{ -} - -IceSecurity::Ssl::DiffieHellmanParamsFile::DiffieHellmanParamsFile(const int keySize, - const string& filename, - const int encoding) : - CertificateFile(filename, encoding), - _keySize(keySize) -{ -} - -IceSecurity::Ssl::DiffieHellmanParamsFile::DiffieHellmanParamsFile(const DiffieHellmanParamsFile& dhParams) : - CertificateFile(dhParams._fileName, dhParams._encoding), - _keySize(dhParams._keySize) -{ -} - -///////////////////////// -//// CertificateDesc //// -///////////////////////// - -IceSecurity::Ssl::CertificateDesc::CertificateDesc() : - _keySize(0), - _public(), - _private() -{ -} - -IceSecurity::Ssl::CertificateDesc::CertificateDesc(const int keySize, - const CertificateFile& publicFile, - const CertificateFile& privateFile) : - _keySize(keySize), - _public(publicFile), - _private(privateFile) -{ -} - -IceSecurity::Ssl::CertificateDesc::CertificateDesc(const CertificateDesc& certDesc) : - _keySize(certDesc._keySize), - _public(certDesc._public), - _private(certDesc._private) -{ -} - +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+#ifdef WIN32
+#pragma warning(disable:4786)
+#endif
+
+#include <openssl/ssl.h>
+#include <Ice/SslCertificateDesc.h>
+
+using namespace std;
+using namespace IceSecurity::Ssl;
+
+/////////////////////////
+//// CertificateFile ////
+/////////////////////////
+
+IceSecurity::Ssl::CertificateFile::CertificateFile() :
+ _fileName(""),
+ _encoding(0)
+{
+}
+
+IceSecurity::Ssl::CertificateFile::CertificateFile(const string& filename, const int encoding) :
+ _fileName(filename),
+ _encoding(encoding)
+{
+}
+
+IceSecurity::Ssl::CertificateFile::CertificateFile(const CertificateFile& certFile) :
+ _fileName(certFile._fileName),
+ _encoding(certFile._encoding)
+{
+}
+
+/////////////////////////////////
+//// DiffieHellmanParamsFile ////
+/////////////////////////////////
+
+IceSecurity::Ssl::DiffieHellmanParamsFile::DiffieHellmanParamsFile() :
+ CertificateFile(),
+ _keySize(0)
+{
+}
+
+IceSecurity::Ssl::DiffieHellmanParamsFile::DiffieHellmanParamsFile(const int keySize,
+ const string& filename,
+ const int encoding) :
+ CertificateFile(filename, encoding),
+ _keySize(keySize)
+{
+}
+
+IceSecurity::Ssl::DiffieHellmanParamsFile::DiffieHellmanParamsFile(const DiffieHellmanParamsFile& dhParams) :
+ CertificateFile(dhParams._fileName, dhParams._encoding),
+ _keySize(dhParams._keySize)
+{
+}
+
+/////////////////////////
+//// CertificateDesc ////
+/////////////////////////
+
+IceSecurity::Ssl::CertificateDesc::CertificateDesc() :
+ _keySize(0),
+ _public(),
+ _private()
+{
+}
+
+IceSecurity::Ssl::CertificateDesc::CertificateDesc(const int keySize,
+ const CertificateFile& publicFile,
+ const CertificateFile& privateFile) :
+ _keySize(keySize),
+ _public(publicFile),
+ _private(privateFile)
+{
+}
+
+IceSecurity::Ssl::CertificateDesc::CertificateDesc(const CertificateDesc& certDesc) :
+ _keySize(certDesc._keySize),
+ _public(certDesc._public),
+ _private(certDesc._private)
+{
+}
+
diff --git a/cpp/src/Ice/SslCertificateDesc.h b/cpp/src/Ice/SslCertificateDesc.h index 830b3df076f..d1eb8a03578 100644 --- a/cpp/src/Ice/SslCertificateDesc.h +++ b/cpp/src/Ice/SslCertificateDesc.h @@ -1,128 +1,128 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** -#ifdef WIN32 -#pragma warning(disable:4786) -#endif - -#ifndef ICE_SSL_CERTIFICATE_DESC_H -#define ICE_SSL_CERTIFICATE_DESC_H - -#include <string> -#include <vector> -#include <ostream> - -namespace IceSecurity -{ - -namespace Ssl -{ - -using std::string; -using std::ostream; -using std::vector; - -class CertificateFile -{ - -public: - CertificateFile(); - CertificateFile(const string&, const int); - CertificateFile(const CertificateFile&); - - inline string getFileName() const { return _fileName; }; - inline int getEncoding() const { return _encoding; }; - -protected: - string _fileName; - int _encoding; -}; - -class DiffieHellmanParamsFile : public CertificateFile -{ - -public: - DiffieHellmanParamsFile(); - DiffieHellmanParamsFile(const int, const string&, const int); - DiffieHellmanParamsFile(const DiffieHellmanParamsFile&); - - inline int getKeySize() const { return _keySize; }; - -protected: - int _keySize; -}; - -class CertificateDesc -{ - -public: - CertificateDesc(); - CertificateDesc(const int, const CertificateFile&, const CertificateFile&); - CertificateDesc(const CertificateDesc&); - - inline int getKeySize() const { return _keySize; }; - - inline const CertificateFile& getPublic() const { return _public; }; - inline const CertificateFile& getPrivate() const { return _private; }; - -protected: - int _keySize; - CertificateFile _public; - CertificateFile _private; -}; - -typedef vector<CertificateDesc> RSAVector; -typedef vector<CertificateDesc> DSAVector; -typedef vector<DiffieHellmanParamsFile> DHVector; - -template<class Stream> -inline Stream& operator << (Stream& target, const CertificateFile& certFile) -{ - if (certFile.getEncoding() == SSL_FILETYPE_PEM) - { - target << "[PEM]: " << certFile.getFileName(); - } - else if (certFile.getEncoding() == SSL_FILETYPE_ASN1) - { - target << "[ASN1]: " << certFile.getFileName(); - } - - return target; -} - -template<class Stream> -inline Stream& operator << (Stream& target, const DiffieHellmanParamsFile& dhParams) -{ - if (dhParams.getKeySize() != 0) - { - target << "Keysize: " << dhParams.getKeySize() << endl; - target << "File: " << ((CertificateFile&)dhParams) << endl; - } - - return target; -} - -template<class Stream> -inline Stream& operator << (Stream& target, const CertificateDesc& certDesc) -{ - if (certDesc.getKeySize() != 0) - { - target << "Keysize: " << certDesc.getKeySize() << endl; - target << "Public: " << certDesc.getPublic() << endl; - target << "Private: " << certDesc.getPrivate() << endl; - } - - return target; -} - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+#ifdef WIN32
+#pragma warning(disable:4786)
+#endif
+
+#ifndef ICE_SSL_CERTIFICATE_DESC_H
+#define ICE_SSL_CERTIFICATE_DESC_H
+
+#include <string>
+#include <vector>
+#include <ostream>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+using std::string;
+using std::ostream;
+using std::vector;
+
+class CertificateFile
+{
+
+public:
+ CertificateFile();
+ CertificateFile(const string&, const int);
+ CertificateFile(const CertificateFile&);
+
+ inline string getFileName() const { return _fileName; };
+ inline int getEncoding() const { return _encoding; };
+
+protected:
+ string _fileName;
+ int _encoding;
+};
+
+class DiffieHellmanParamsFile : public CertificateFile
+{
+
+public:
+ DiffieHellmanParamsFile();
+ DiffieHellmanParamsFile(const int, const string&, const int);
+ DiffieHellmanParamsFile(const DiffieHellmanParamsFile&);
+
+ inline int getKeySize() const { return _keySize; };
+
+protected:
+ int _keySize;
+};
+
+class CertificateDesc
+{
+
+public:
+ CertificateDesc();
+ CertificateDesc(const int, const CertificateFile&, const CertificateFile&);
+ CertificateDesc(const CertificateDesc&);
+
+ inline int getKeySize() const { return _keySize; };
+
+ inline const CertificateFile& getPublic() const { return _public; };
+ inline const CertificateFile& getPrivate() const { return _private; };
+
+protected:
+ int _keySize;
+ CertificateFile _public;
+ CertificateFile _private;
+};
+
+typedef vector<CertificateDesc> RSAVector;
+typedef vector<CertificateDesc> DSAVector;
+typedef vector<DiffieHellmanParamsFile> DHVector;
+
+template<class Stream>
+inline Stream& operator << (Stream& target, const CertificateFile& certFile)
+{
+ if (certFile.getEncoding() == SSL_FILETYPE_PEM)
+ {
+ target << "[PEM]: " << certFile.getFileName();
+ }
+ else if (certFile.getEncoding() == SSL_FILETYPE_ASN1)
+ {
+ target << "[ASN1]: " << certFile.getFileName();
+ }
+
+ return target;
+}
+
+template<class Stream>
+inline Stream& operator << (Stream& target, const DiffieHellmanParamsFile& dhParams)
+{
+ if (dhParams.getKeySize() != 0)
+ {
+ target << "Keysize: " << dhParams.getKeySize() << endl;
+ target << "File: " << ((CertificateFile&)dhParams) << endl;
+ }
+
+ return target;
+}
+
+template<class Stream>
+inline Stream& operator << (Stream& target, const CertificateDesc& certDesc)
+{
+ if (certDesc.getKeySize() != 0)
+ {
+ target << "Keysize: " << certDesc.getKeySize() << endl;
+ target << "Public: " << certDesc.getPublic() << endl;
+ target << "Private: " << certDesc.getPrivate() << endl;
+ }
+
+ return target;
+}
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslConfig.cpp b/cpp/src/Ice/SslConfig.cpp index cdac35128b0..ddba7ef5250 100644 --- a/cpp/src/Ice/SslConfig.cpp +++ b/cpp/src/Ice/SslConfig.cpp @@ -1,548 +1,580 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** -#ifdef WIN32 -#pragma warning(disable:4786) -#endif - -#include <sstream> -#include <iostream> - -#include <util/PlatformUtils.hpp> -#include <parsers/DOMParser.hpp> - -#include <Ice/SslException.h> -#include <Ice/SslConfigErrorReporter.h> -#include <Ice/SslConfig.h> - -using namespace std; -using namespace IceSecurity::Ssl::OpenSSL; - -// -// Public Methods -// - -IceSecurity::Ssl::Parser::Parser(const string& configFile) : - _configFile(configFile) -{ - _traceLevels = 0; - _logger = 0; -} - -IceSecurity::Ssl::Parser::~Parser() -{ -} - -void -IceSecurity::Ssl::Parser::process() -{ - try - { - XMLPlatformUtils::Initialize(); - } - catch(const XMLException& toCatch) - { - if (_traceLevels->network >= 1) - { - ostringstream s; - s << "Xerces-c Init Exception: " << DOMString(toCatch.getMessage()); - _logger->trace(_traceLevels->networkCat, s.str()); - } - - throw ContextException("Xerces-c Init Exception.", __FILE__, __LINE__); - } - - int errorCount = 0; - - ErrorReporter* errReporter = new ErrorReporter(_traceLevels, _logger); - assert(errReporter != 0); - - // Create our parser, then attach an error handler to the parser. - // The parser will call back to methods of the ErrorHandler if it - // discovers errors during the course of parsing the XML document. - DOMParser *parser = new DOMParser; - parser->setValidationScheme(DOMParser::Val_Auto); - parser->setDoNamespaces(false); - parser->setDoSchema(false); - parser->setCreateEntityReferenceNodes(false); - parser->setToCreateXMLDeclTypeNode(true); - parser->setErrorHandler(errReporter); - - try - { - parser->parse(_configFile.c_str()); - - errorCount = parser->getErrorCount(); - - if (errorCount == 0) - { - // Get the root of the parse tree. - _root = parser->getDocument(); - } - } - catch (const XMLException& e) - { - if (errReporter != 0) - { - delete errReporter; - } - - ostringstream s; - s << "Xerces-c Parsing Error: " << DOMString(e.getMessage()); - - if (_traceLevels->network >= 1) - { - _logger->trace(_traceLevels->networkCat, s.str()); - } - - throw ContextException(s.str().c_str(), __FILE__, __LINE__); - } - catch (const DOM_DOMException& e) - { - if (errReporter != 0) - { - delete errReporter; - } - - ostringstream s; - s << "Xerces-c DOM Parsing Error, DOMException code: " << e.code; - - if (_traceLevels->network >= 1) - { - _logger->trace(_traceLevels->networkCat, s.str()); - } - - throw ContextException(s.str().c_str(), __FILE__, __LINE__); - } - catch (...) - { - if (errReporter != 0) - { - delete errReporter; - } - - string s = "An error occured during parsing"; - - if (_traceLevels->network >= 1) - { - _logger->trace(_traceLevels->networkCat, s); - } - - throw ContextException(s.c_str(), __FILE__, __LINE__); - } - - if (errReporter != 0) - { - delete errReporter; - } - - if (errorCount) - { - string s = errorCount + "Errors occured during parsing"; - - if (_traceLevels->network >= 1) - { - _logger->trace(_traceLevels->networkCat, s); - } - - throw ContextException(s.c_str(), __FILE__, __LINE__); - } -} - -bool -IceSecurity::Ssl::Parser::loadClientConfig(GeneralConfig& general, - CertificateAuthority& certAuth, - BaseCertificates& baseCerts) -{ - bool retCode = false; - string clientSectionString("SSLConfig:client"); - DOM_Node clientSection = find(clientSectionString); - - // If we actually have a client section. - if (clientSection != 0) - { - getGeneral(clientSection, general); - getCertAuth(clientSection, certAuth); - getBaseCerts(clientSection, baseCerts); - retCode = true; - } - - return retCode; -} - -bool -IceSecurity::Ssl::Parser::loadServerConfig(GeneralConfig& general, - CertificateAuthority& certAuth, - BaseCertificates& baseCerts, - TempCertificates& tempCerts) -{ - bool retCode = false; - string serverSectionString("SSLConfig:server"); - DOM_Node serverSection = find(serverSectionString); - - // If we actually have a client section. - if (serverSection != 0) - { - getGeneral(serverSection, general); - getCertAuth(serverSection, certAuth); - getBaseCerts(serverSection, baseCerts); - getTempCerts(serverSection, tempCerts); - retCode = true; - } - - return retCode; -} - -// -// Private Methods -// - -// path is of the form "sslconfig:client:general" -void -IceSecurity::Ssl::Parser::popRoot(string& path, string& root, string& tail) -{ - string::size_type pos = path.find_first_of(':'); - - if (pos != string::npos) - { - root = path.substr(0,pos); - tail = path.substr(pos+1); - } - else - { - root = path; - tail = ""; - } -} - -DOM_Node -IceSecurity::Ssl::Parser::find(string& nodePath) -{ - return find(_root, nodePath); -} - -DOM_Node -IceSecurity::Ssl::Parser::find(DOM_Node rootNode, string& nodePath) -{ - // The target node that we're looking for. - DOM_Node tNode; - - if (rootNode != 0) - { - string rootNodeName; - string tailNodes; - - // Pop the root off the path. - popRoot(nodePath, rootNodeName, tailNodes); - - DOM_Node child = rootNode.getFirstChild(); - - while (child != 0) - { - // Ignore any other node types - we're only interested in ELEMENT_NODEs. - if (child.getNodeType() == DOM_Node::ELEMENT_NODE) - { - string nodeName = toString(child.getNodeName()); - - if (nodeName.compare(rootNodeName) == 0) - { - // No further to recurse, this must be it. - if (tailNodes.empty()) - { - tNode = child; - } - else - { - // Recursive call. - tNode = find(child, tailNodes); - } - } - } - - child = child.getNextSibling(); - } - } - - return tNode; -} - -void -IceSecurity::Ssl::Parser::getGeneral(DOM_Node rootNode, GeneralConfig& generalConfig) -{ - if (rootNode != 0) - { - string generalString("general"); - DOM_Node general = find(rootNode, generalString); - - DOM_NamedNodeMap attributes = general.getAttributes(); - - int attrCount = attributes.getLength(); - - for (int i = 0; i < attrCount; i++) - { - DOM_Node attribute = attributes.item(i); - string nodeName = toString(attribute.getNodeName()); - string nodeValue = toString(attribute.getNodeValue()); - - // Set the property. - generalConfig.set(nodeName, nodeValue); - } - } -} - -void -IceSecurity::Ssl::Parser::getCertAuth(DOM_Node rootNode, CertificateAuthority& certAuth) -{ - if (rootNode != 0) - { - string certAuthorityString("certauthority"); - DOM_Node certAuthNode = find(rootNode, certAuthorityString); - - if (certAuthNode != 0) - { - DOM_NamedNodeMap attributes = certAuthNode.getAttributes(); - - int attrCount = attributes.getLength(); - - for (int i = 0; i < attrCount; i++) - { - DOM_Node attribute = attributes.item(i); - string nodeName = toString(attribute.getNodeName()); - string nodeValue = toString(attribute.getNodeValue()); - - if (nodeName.compare("file") == 0) - { - certAuth.setCAFileName(nodeValue); - } - else if (nodeName.compare("path") == 0) - { - certAuth.setCAPath(nodeValue); - } - } - } - } -} - -void -IceSecurity::Ssl::Parser::getBaseCerts(DOM_Node rootNode, BaseCertificates& baseCerts) -{ - if (rootNode != 0) - { - string baseCertsString("basecerts"); - DOM_Node baseCertsRoot = find(rootNode, baseCertsString); - - if (baseCertsRoot != 0) - { - CertificateDesc rsaCert; - CertificateDesc dsaCert; - DiffieHellmanParamsFile dhParams; - - string rsaCertString("rsacert"); - string dsaCertString("dsacert"); - string dhParamsString("dhparams"); - - getCert(find(baseCertsRoot, rsaCertString), rsaCert); - getCert(find(baseCertsRoot, dsaCertString), dsaCert); - - getDHParams(find(baseCertsRoot, dhParamsString), dhParams); - - baseCerts = BaseCertificates(rsaCert, dsaCert, dhParams); - } - } -} - -void -IceSecurity::Ssl::Parser::getTempCerts(DOM_Node rootNode, TempCertificates& tempCerts) -{ - if (rootNode != 0) - { - string tempCertsString("tempcerts"); - DOM_Node tempCertsRoot = find(rootNode, tempCertsString); - - if (tempCertsRoot != 0) - { - DOM_Node child = tempCertsRoot.getFirstChild(); - - while (child != 0) - { - DOMString nodeName = child.getNodeName(); - string name = toString(nodeName); - - if (name.compare("dhparams") == 0) - { - loadDHParams(child, tempCerts); - } - else if (name.compare("rsacert") == 0) - { - loadRSACert(child, tempCerts); - } - else if (name.compare("dsacert") == 0) - { - loadDSACert(child, tempCerts); - } - - child = child.getNextSibling(); - } - } - } -} - -void -IceSecurity::Ssl::Parser::loadDHParams(DOM_Node rootNode, TempCertificates& tempCerts) -{ - DiffieHellmanParamsFile dhParams; - - getDHParams(rootNode, dhParams); - - tempCerts.addDHParams(dhParams); -} - -void -IceSecurity::Ssl::Parser::loadRSACert(DOM_Node rootNode, TempCertificates& tempCerts) -{ - CertificateDesc rsaCert; - - getCert(rootNode, rsaCert); - - tempCerts.addRSACert(rsaCert); -} - -void -IceSecurity::Ssl::Parser::loadDSACert(DOM_Node rootNode, TempCertificates& tempCerts) -{ - CertificateDesc dsaCert; - - getCert(rootNode, dsaCert); - - tempCerts.addDSACert(dsaCert); -} - -void -IceSecurity::Ssl::Parser::getCert(DOM_Node rootNode, CertificateDesc& certDesc) -{ - if (rootNode != 0) - { - CertificateFile publicFile; - CertificateFile privateFile; - int keySize = 0; - - DOM_NamedNodeMap attributes = rootNode.getAttributes(); - int attrCount = attributes.getLength(); - - for (int i = 0; i < attrCount; i++) - { - DOM_Node attribute = attributes.item(i); - string nodeName = toString(attribute.getNodeName()); - string nodeValue = toString(attribute.getNodeValue()); - - if (nodeName.compare("keysize") == 0) - { - keySize = atoi(nodeValue.c_str()); - } - } - - string publicString("public"); - string privateString("private"); - - loadCertificateFile(find(rootNode, publicString), publicFile); - loadCertificateFile(find(rootNode, privateString), privateFile); - - // Initialize the certificate description. - certDesc = CertificateDesc(keySize, publicFile, privateFile); - } -} - -void -IceSecurity::Ssl::Parser::getDHParams(DOM_Node rootNode, DiffieHellmanParamsFile& dhParams) -{ - if (rootNode != 0) - { - CertificateFile certFile; - loadCertificateFile(rootNode, certFile); - - DOM_NamedNodeMap attributes = rootNode.getAttributes(); - int keySize = 0; - int attrCount = attributes.getLength(); - - for (int i = 0; i < attrCount; i++) - { - DOM_Node attribute = attributes.item(i); - string nodeName = toString(attribute.getNodeName()); - string nodeValue = toString(attribute.getNodeValue()); - - if (nodeName.compare("keysize") == 0) - { - keySize = atoi(nodeValue.c_str()); - } - } - - dhParams = DiffieHellmanParamsFile(keySize, certFile.getFileName(), certFile.getEncoding()); - } -} - -void -IceSecurity::Ssl::Parser::loadCertificateFile(DOM_Node rootNode, CertificateFile& certFile) -{ - if (rootNode != 0) - { - string filename; - int encoding; - - DOM_NamedNodeMap attributes = rootNode.getAttributes(); - int attrCount = attributes.getLength(); - - for (int i = 0; i < attrCount; i++) - { - DOM_Node attribute = attributes.item(i); - string nodeName = toString(attribute.getNodeName()); - string nodeValue = toString(attribute.getNodeValue()); - - if (nodeName.compare("encoding") == 0) - { - encoding = parseEncoding(nodeValue); - } - else if (nodeName.compare("filename") == 0) - { - filename = nodeValue; - } - } - - certFile = CertificateFile(filename, encoding); - } -} - -int -IceSecurity::Ssl::Parser::parseEncoding(string& encodingString) -{ - int encoding = 0; - - if (encodingString.compare("PEM") == 0) - { - encoding = SSL_FILETYPE_PEM; - } - else if (encodingString.compare("ASN1") == 0) - { - encoding = SSL_FILETYPE_ASN1; - } - - return encoding; -} - -string -IceSecurity::Ssl::Parser::toString(const DOMString& domString) -{ - char* cString = domString.transcode(); - - string stlString(cString); - - delete []cString; - - return stlString; -} - +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+#ifdef WIN32
+#pragma warning(disable:4786)
+#endif
+
+#include <sstream>
+#include <iostream>
+
+#include <util/PlatformUtils.hpp>
+#include <parsers/DOMParser.hpp>
+#include <framework/LocalFileInputSource.hpp>
+#include <util/Janitor.hpp>
+
+#include <Ice/Security.h>
+#include <Ice/SslException.h>
+#include <Ice/SslConfigErrorReporter.h>
+#include <Ice/SslConfig.h>
+
+using namespace std;
+using namespace IceSecurity::Ssl;
+
+//
+// Public Methods
+//
+
+IceSecurity::Ssl::Parser::Parser(const string& configFile) :
+ _configFile(configFile)
+{
+ _configPath = "./";
+ _traceLevels = 0;
+ _logger = 0;
+}
+
+IceSecurity::Ssl::Parser::Parser(const string& configFile, const string& configPath) :
+ _configFile(configFile),
+ _configPath(configPath)
+{
+ _traceLevels = 0;
+ _logger = 0;
+}
+
+IceSecurity::Ssl::Parser::~Parser()
+{
+}
+
+void
+IceSecurity::Ssl::Parser::process()
+{
+ try
+ {
+ XMLPlatformUtils::Initialize();
+ }
+ catch(const XMLException& toCatch)
+ {
+ ostringstream s;
+ s << "While parsing " << _configFile << flush;
+ s << "Xerces-c Init Exception: " << DOMString(toCatch.getMessage());
+
+ throw ConfigParseException(s.str().c_str(), __FILE__, __LINE__);
+ }
+
+ int errorCount = 0;
+
+ ErrorReporter* errReporter = new ErrorReporter(_traceLevels, _logger);
+ assert(errReporter != 0);
+
+ // Create our parser, then attach an error handler to the parser.
+ // The parser will call back to methods of the ErrorHandler if it
+ // discovers errors during the course of parsing the XML document.
+ DOMParser* parser = new DOMParser;
+ parser->setValidationScheme(DOMParser::Val_Auto);
+ parser->setDoNamespaces(false);
+ parser->setDoSchema(false);
+ parser->setCreateEntityReferenceNodes(false);
+ parser->setToCreateXMLDeclTypeNode(true);
+ parser->setErrorHandler(errReporter);
+
+ try
+ {
+ string::iterator fileBegin = _configFile.begin();
+
+ if (*fileBegin != '/')
+ {
+ string::iterator pathEnd = _configPath.end();
+
+ if (*pathEnd != '/')
+ {
+ _configPath += "/";
+ }
+
+ XMLCh* xmlConfigPath = XMLString::transcode(_configPath.c_str());
+ XMLCh* xmlConfigFile = XMLString::transcode(_configFile.c_str());
+ ArrayJanitor<XMLCh> janPath(xmlConfigPath);
+ ArrayJanitor<XMLCh> janFile(xmlConfigFile);
+ LocalFileInputSource configSource(xmlConfigPath, xmlConfigFile);
+
+ parser->parse(configSource);
+ }
+ else
+ {
+ XMLCh* xmlConfigFile = XMLString::transcode(_configFile.c_str());
+ ArrayJanitor<XMLCh> janFile(xmlConfigFile);
+ LocalFileInputSource configSource(xmlConfigFile);
+
+ parser->parse(configSource);
+ }
+
+ errorCount = parser->getErrorCount();
+
+ if (errorCount == 0)
+ {
+ // Get the root of the parse tree.
+ _root = parser->getDocument();
+ }
+ }
+ catch (const XMLException& e)
+ {
+ if (errReporter != 0)
+ {
+ delete errReporter;
+ }
+
+ ostringstream s;
+ s << "While parsing " << _configFile << flush;
+ s << "Xerces-c Parsing Error: " << DOMString(e.getMessage());
+
+ throw ConfigParseException(s.str().c_str(), __FILE__, __LINE__);
+ }
+ catch (const DOM_DOMException& e)
+ {
+ if (errReporter != 0)
+ {
+ delete errReporter;
+ }
+
+ ostringstream s;
+ s << "While parsing " << _configFile << flush;
+ s << "Xerces-c DOM Parsing Error, DOMException code: " << e.code;
+ s << ", message: " << e.msg;
+
+ throw ConfigParseException(s.str().c_str(), __FILE__, __LINE__);
+ }
+ catch (...)
+ {
+ if (errReporter != 0)
+ {
+ delete errReporter;
+ }
+
+ string s = "While parsing " + _configFile + "\n" + "An unknown error occured during parsing.";
+
+ throw ConfigParseException(s.c_str(), __FILE__, __LINE__);
+ }
+
+ if (errReporter != 0)
+ {
+ delete errReporter;
+ }
+
+ if (errorCount)
+ {
+ string s = errorCount + "errors occured during parsing.";
+
+ throw ConfigParseException(s.c_str(), __FILE__, __LINE__);
+ }
+}
+
+bool
+IceSecurity::Ssl::Parser::loadClientConfig(GeneralConfig& general,
+ CertificateAuthority& certAuth,
+ BaseCertificates& baseCerts)
+{
+ bool retCode = false;
+ string clientSectionString("SSLConfig:client");
+ DOM_Node clientSection = find(clientSectionString);
+
+ // If we actually have a client section.
+ if (clientSection != 0)
+ {
+ getGeneral(clientSection, general);
+ getCertAuth(clientSection, certAuth);
+ getBaseCerts(clientSection, baseCerts);
+ retCode = true;
+ }
+
+ return retCode;
+}
+
+bool
+IceSecurity::Ssl::Parser::loadServerConfig(GeneralConfig& general,
+ CertificateAuthority& certAuth,
+ BaseCertificates& baseCerts,
+ TempCertificates& tempCerts)
+{
+ bool retCode = false;
+ string serverSectionString("SSLConfig:server");
+ DOM_Node serverSection = find(serverSectionString);
+
+ // If we actually have a client section.
+ if (serverSection != 0)
+ {
+ getGeneral(serverSection, general);
+ getCertAuth(serverSection, certAuth);
+ getBaseCerts(serverSection, baseCerts);
+ getTempCerts(serverSection, tempCerts);
+ retCode = true;
+ }
+
+ return retCode;
+}
+
+//
+// Private Methods
+//
+
+// path is of the form "sslconfig:client:general"
+void
+IceSecurity::Ssl::Parser::popRoot(string& path, string& root, string& tail)
+{
+ string::size_type pos = path.find_first_of(':');
+
+ if (pos != string::npos)
+ {
+ root = path.substr(0,pos);
+ tail = path.substr(pos+1);
+ }
+ else
+ {
+ root = path;
+ tail = "";
+ }
+}
+
+DOM_Node
+IceSecurity::Ssl::Parser::find(string& nodePath)
+{
+ return find(_root, nodePath);
+}
+
+DOM_Node
+IceSecurity::Ssl::Parser::find(DOM_Node rootNode, string& nodePath)
+{
+ // The target node that we're looking for.
+ DOM_Node tNode;
+
+ if (rootNode != 0)
+ {
+ string rootNodeName;
+ string tailNodes;
+
+ // Pop the root off the path.
+ popRoot(nodePath, rootNodeName, tailNodes);
+
+ DOM_Node child = rootNode.getFirstChild();
+
+ while (child != 0)
+ {
+ // Ignore any other node types - we're only interested in ELEMENT_NODEs.
+ if (child.getNodeType() == DOM_Node::ELEMENT_NODE)
+ {
+ string nodeName = toString(child.getNodeName());
+
+ if (nodeName.compare(rootNodeName) == 0)
+ {
+ // No further to recurse, this must be it.
+ if (tailNodes.empty())
+ {
+ tNode = child;
+ }
+ else
+ {
+ // Recursive call.
+ tNode = find(child, tailNodes);
+ }
+ }
+ }
+
+ child = child.getNextSibling();
+ }
+ }
+
+ return tNode;
+}
+
+void
+IceSecurity::Ssl::Parser::getGeneral(DOM_Node rootNode, GeneralConfig& generalConfig)
+{
+ if (rootNode != 0)
+ {
+ string generalString("general");
+ DOM_Node general = find(rootNode, generalString);
+
+ DOM_NamedNodeMap attributes = general.getAttributes();
+
+ int attrCount = attributes.getLength();
+
+ for (int i = 0; i < attrCount; i++)
+ {
+ DOM_Node attribute = attributes.item(i);
+ string nodeName = toString(attribute.getNodeName());
+ string nodeValue = toString(attribute.getNodeValue());
+
+ // Set the property.
+ generalConfig.set(nodeName, nodeValue);
+ }
+ }
+}
+
+void
+IceSecurity::Ssl::Parser::getCertAuth(DOM_Node rootNode, CertificateAuthority& certAuth)
+{
+ if (rootNode != 0)
+ {
+ string certAuthorityString("certauthority");
+ DOM_Node certAuthNode = find(rootNode, certAuthorityString);
+
+ if (certAuthNode != 0)
+ {
+ DOM_NamedNodeMap attributes = certAuthNode.getAttributes();
+
+ int attrCount = attributes.getLength();
+
+ for (int i = 0; i < attrCount; i++)
+ {
+ DOM_Node attribute = attributes.item(i);
+ string nodeName = toString(attribute.getNodeName());
+ string nodeValue = toString(attribute.getNodeValue());
+
+ if (nodeName.compare("file") == 0)
+ {
+ string filename = nodeValue;
+
+ // Just a filename, no path component, append path.
+ if ((filename.find("/") == string::npos) && (filename.find("\\") == string::npos))
+ {
+ filename = _configPath + filename;
+ }
+
+ certAuth.setCAFileName(filename);
+ }
+ else if (nodeName.compare("path") == 0)
+ {
+ certAuth.setCAPath(nodeValue);
+ }
+ }
+ }
+ }
+}
+
+void
+IceSecurity::Ssl::Parser::getBaseCerts(DOM_Node rootNode, BaseCertificates& baseCerts)
+{
+ if (rootNode != 0)
+ {
+ string baseCertsString("basecerts");
+ DOM_Node baseCertsRoot = find(rootNode, baseCertsString);
+
+ if (baseCertsRoot != 0)
+ {
+ CertificateDesc rsaCert;
+ CertificateDesc dsaCert;
+ DiffieHellmanParamsFile dhParams;
+
+ string rsaCertString("rsacert");
+ string dsaCertString("dsacert");
+ string dhParamsString("dhparams");
+
+ getCert(find(baseCertsRoot, rsaCertString), rsaCert);
+ getCert(find(baseCertsRoot, dsaCertString), dsaCert);
+
+ getDHParams(find(baseCertsRoot, dhParamsString), dhParams);
+
+ baseCerts = BaseCertificates(rsaCert, dsaCert, dhParams);
+ }
+ }
+}
+
+void
+IceSecurity::Ssl::Parser::getTempCerts(DOM_Node rootNode, TempCertificates& tempCerts)
+{
+ if (rootNode != 0)
+ {
+ string tempCertsString("tempcerts");
+ DOM_Node tempCertsRoot = find(rootNode, tempCertsString);
+
+ if (tempCertsRoot != 0)
+ {
+ DOM_Node child = tempCertsRoot.getFirstChild();
+
+ while (child != 0)
+ {
+ DOMString nodeName = child.getNodeName();
+ string name = toString(nodeName);
+
+ if (name.compare("dhparams") == 0)
+ {
+ loadDHParams(child, tempCerts);
+ }
+ else if (name.compare("rsacert") == 0)
+ {
+ loadRSACert(child, tempCerts);
+ }
+ else if (name.compare("dsacert") == 0)
+ {
+ loadDSACert(child, tempCerts);
+ }
+
+ child = child.getNextSibling();
+ }
+ }
+ }
+}
+
+void
+IceSecurity::Ssl::Parser::loadDHParams(DOM_Node rootNode, TempCertificates& tempCerts)
+{
+ DiffieHellmanParamsFile dhParams;
+
+ getDHParams(rootNode, dhParams);
+
+ tempCerts.addDHParams(dhParams);
+}
+
+void
+IceSecurity::Ssl::Parser::loadRSACert(DOM_Node rootNode, TempCertificates& tempCerts)
+{
+ CertificateDesc rsaCert;
+
+ getCert(rootNode, rsaCert);
+
+ tempCerts.addRSACert(rsaCert);
+}
+
+void
+IceSecurity::Ssl::Parser::loadDSACert(DOM_Node rootNode, TempCertificates& tempCerts)
+{
+ CertificateDesc dsaCert;
+
+ getCert(rootNode, dsaCert);
+
+ tempCerts.addDSACert(dsaCert);
+}
+
+void
+IceSecurity::Ssl::Parser::getCert(DOM_Node rootNode, CertificateDesc& certDesc)
+{
+ if (rootNode != 0)
+ {
+ CertificateFile publicFile;
+ CertificateFile privateFile;
+ int keySize = 0;
+
+ DOM_NamedNodeMap attributes = rootNode.getAttributes();
+ int attrCount = attributes.getLength();
+
+ for (int i = 0; i < attrCount; i++)
+ {
+ DOM_Node attribute = attributes.item(i);
+ string nodeName = toString(attribute.getNodeName());
+ string nodeValue = toString(attribute.getNodeValue());
+
+ if (nodeName.compare("keysize") == 0)
+ {
+ keySize = atoi(nodeValue.c_str());
+ }
+ }
+
+ string publicString("public");
+ string privateString("private");
+
+ loadCertificateFile(find(rootNode, publicString), publicFile);
+ loadCertificateFile(find(rootNode, privateString), privateFile);
+
+ // Initialize the certificate description.
+ certDesc = CertificateDesc(keySize, publicFile, privateFile);
+ }
+}
+
+void
+IceSecurity::Ssl::Parser::getDHParams(DOM_Node rootNode, DiffieHellmanParamsFile& dhParams)
+{
+ if (rootNode != 0)
+ {
+ CertificateFile certFile;
+ loadCertificateFile(rootNode, certFile);
+
+ DOM_NamedNodeMap attributes = rootNode.getAttributes();
+ int keySize = 0;
+ int attrCount = attributes.getLength();
+
+ for (int i = 0; i < attrCount; i++)
+ {
+ DOM_Node attribute = attributes.item(i);
+ string nodeName = toString(attribute.getNodeName());
+ string nodeValue = toString(attribute.getNodeValue());
+
+ if (nodeName.compare("keysize") == 0)
+ {
+ keySize = atoi(nodeValue.c_str());
+ }
+ }
+
+ dhParams = DiffieHellmanParamsFile(keySize, certFile.getFileName(), certFile.getEncoding());
+ }
+}
+
+void
+IceSecurity::Ssl::Parser::loadCertificateFile(DOM_Node rootNode, CertificateFile& certFile)
+{
+ if (rootNode != 0)
+ {
+ string filename;
+ int encoding;
+
+ DOM_NamedNodeMap attributes = rootNode.getAttributes();
+ int attrCount = attributes.getLength();
+
+ for (int i = 0; i < attrCount; i++)
+ {
+ DOM_Node attribute = attributes.item(i);
+ string nodeName = toString(attribute.getNodeName());
+ string nodeValue = toString(attribute.getNodeValue());
+
+ if (nodeName.compare("encoding") == 0)
+ {
+ encoding = parseEncoding(nodeValue);
+ }
+ else if (nodeName.compare("filename") == 0)
+ {
+ filename = nodeValue;
+
+ // Just a filename, no path component, append path.
+ if ((filename.find("/") == string::npos) && (filename.find("\\") == string::npos))
+ {
+ filename = _configPath + filename;
+ }
+ }
+ }
+
+ certFile = CertificateFile(filename, encoding);
+ }
+}
+
+int
+IceSecurity::Ssl::Parser::parseEncoding(string& encodingString)
+{
+ int encoding = 0;
+
+ if (encodingString.compare("PEM") == 0)
+ {
+ encoding = SSL_FILETYPE_PEM;
+ }
+ else if (encodingString.compare("ASN1") == 0)
+ {
+ encoding = SSL_FILETYPE_ASN1;
+ }
+
+ return encoding;
+}
+
+string
+IceSecurity::Ssl::Parser::toString(const DOMString& domString)
+{
+ char* cString = domString.transcode();
+
+ string stlString(cString);
+
+ delete []cString;
+
+ return stlString;
+}
+
diff --git a/cpp/src/Ice/SslConfig.h b/cpp/src/Ice/SslConfig.h index cd2fa448d6c..3a0a7cd6c55 100644 --- a/cpp/src/Ice/SslConfig.h +++ b/cpp/src/Ice/SslConfig.h @@ -1,95 +1,97 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_SSL_CONFIG_H -#define ICE_SSL_CONFIG_H - -#include <string> - -#include <dom/DOM.hpp> -#include <Ice/TraceLevels.h> -#include <Ice/Logger.h> - -#include <Ice/SslCertificateDesc.h> -#include <Ice/SslGeneralConfig.h> -#include <Ice/SslCertificateAuthority.h> -#include <Ice/SslBaseCerts.h> -#include <Ice/SslTempCerts.h> - -namespace IceSecurity -{ - -namespace Ssl -{ - -using namespace std; -using namespace IceInternal; - -class Parser -{ - -public: - // Constructor, based on the indicated file. - Parser(const string&); - ~Parser(); - - // Performs a complete parsing of the file. - void process(); - - // Loads the Client/Server portions of the config. - bool loadClientConfig(GeneralConfig&, CertificateAuthority&, BaseCertificates&); - bool loadServerConfig(GeneralConfig&, CertificateAuthority&, BaseCertificates&, TempCertificates&); - - inline void setTrace(TraceLevelsPtr traceLevels) { _traceLevels = traceLevels; }; - inline bool isTraceSet() const { return (_traceLevels == 0 ? false : true); }; - - inline void setLogger(LoggerPtr traceLevels) { _logger = traceLevels; }; - inline bool isLoggerSet() const { return (_logger == 0 ? false : true); }; - -private: - - DOM_Node _root; - string _configFile; - - TraceLevelsPtr _traceLevels; - LoggerPtr _logger; - - // Tree walking utility methods. - void popRoot(string&, string&, string&); - DOM_Node find(string&); - DOM_Node find(DOM_Node, string&); - - // Loading of the base elements of the file. - void getGeneral(DOM_Node, GeneralConfig&); - void getCertAuth(DOM_Node, CertificateAuthority&); - void getBaseCerts(DOM_Node, BaseCertificates&); - void getTempCerts(DOM_Node, TempCertificates&); - - // Loading of temporary certificates/params (Ephemeral Keys). - void loadDHParams(DOM_Node, TempCertificates&); - void loadRSACert(DOM_Node, TempCertificates&); - void loadDSACert(DOM_Node, TempCertificates&); - - // Populates classes with information from the indicated node in the parse tree. - void getCert(DOM_Node, CertificateDesc&); - void getDHParams(DOM_Node, DiffieHellmanParamsFile&); - - // Populate a certificate file object, basis of all certificates. - void loadCertificateFile(DOM_Node, CertificateFile&); - int parseEncoding(string&); - - string toString(const DOMString&); -}; - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_CONFIG_H
+#define ICE_SSL_CONFIG_H
+
+#include <string>
+
+#include <dom/DOM.hpp>
+#include <Ice/TraceLevels.h>
+#include <Ice/Logger.h>
+
+#include <Ice/SslCertificateDesc.h>
+#include <Ice/SslGeneralConfig.h>
+#include <Ice/SslCertificateAuthority.h>
+#include <Ice/SslBaseCerts.h>
+#include <Ice/SslTempCerts.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+using namespace std;
+using namespace IceInternal;
+
+class Parser
+{
+
+public:
+ // Constructor, based on the indicated file.
+ Parser(const string&);
+ Parser(const string&, const string&);
+ ~Parser();
+
+ // Performs a complete parsing of the file.
+ void process();
+
+ // Loads the Client/Server portions of the config.
+ bool loadClientConfig(GeneralConfig&, CertificateAuthority&, BaseCertificates&);
+ bool loadServerConfig(GeneralConfig&, CertificateAuthority&, BaseCertificates&, TempCertificates&);
+
+ inline void setTrace(TraceLevelsPtr traceLevels) { _traceLevels = traceLevels; };
+ inline bool isTraceSet() const { return (_traceLevels == 0 ? false : true); };
+
+ inline void setLogger(LoggerPtr traceLevels) { _logger = traceLevels; };
+ inline bool isLoggerSet() const { return (_logger == 0 ? false : true); };
+
+private:
+
+ DOM_Node _root;
+ string _configFile;
+ string _configPath;
+
+ TraceLevelsPtr _traceLevels;
+ LoggerPtr _logger;
+
+ // Tree walking utility methods.
+ void popRoot(string&, string&, string&);
+ DOM_Node find(string&);
+ DOM_Node find(DOM_Node, string&);
+
+ // Loading of the base elements of the file.
+ void getGeneral(DOM_Node, GeneralConfig&);
+ void getCertAuth(DOM_Node, CertificateAuthority&);
+ void getBaseCerts(DOM_Node, BaseCertificates&);
+ void getTempCerts(DOM_Node, TempCertificates&);
+
+ // Loading of temporary certificates/params (Ephemeral Keys).
+ void loadDHParams(DOM_Node, TempCertificates&);
+ void loadRSACert(DOM_Node, TempCertificates&);
+ void loadDSACert(DOM_Node, TempCertificates&);
+
+ // Populates classes with information from the indicated node in the parse tree.
+ void getCert(DOM_Node, CertificateDesc&);
+ void getDHParams(DOM_Node, DiffieHellmanParamsFile&);
+
+ // Populate a certificate file object, basis of all certificates.
+ void loadCertificateFile(DOM_Node, CertificateFile&);
+ int parseEncoding(string&);
+
+ string toString(const DOMString&);
+};
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslConfigErrorReporter.cpp b/cpp/src/Ice/SslConfigErrorReporter.cpp index 247db4f50d5..bd466b4a611 100644 --- a/cpp/src/Ice/SslConfigErrorReporter.cpp +++ b/cpp/src/Ice/SslConfigErrorReporter.cpp @@ -1,82 +1,85 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include <iostream> -#include <sstream> - -#include <sax/SAXParseException.hpp> -#include <Ice/SslConfigErrorReporter.h> -#include <stdlib.h> -#include <string.h> -#include <Ice/Security.h> - -using namespace std; - -void -IceSecurity::Ssl::ErrorReporter::warning(const SAXParseException& toCatch) -{ - if (_traceLevels->security >= SECURITY_PARSE_WARNINGS) - { - ostringstream s; - - s << "Xerces-c Init Exception: "<< "Warning at file \"" - << DOMString(toCatch.getSystemId()) - << "\", line " << toCatch.getLineNumber() - << ", column " << toCatch.getColumnNumber() - << "\n Message: " << DOMString(toCatch.getMessage()) << endl; - - _logger->trace(_traceLevels->securityCat, s.str()); - } -} - -void -IceSecurity::Ssl::ErrorReporter::error(const SAXParseException& toCatch) -{ - _sawErrors = true; - - if (_traceLevels->security >= SECURITY_PARSE_WARNINGS) - { - ostringstream s; - - s << "Xerces-c Init Exception: "<< "Error at file \"" - << DOMString(toCatch.getSystemId()) - << "\", line " << toCatch.getLineNumber() - << ", column " << toCatch.getColumnNumber() - << "\n Message: " << DOMString(toCatch.getMessage()) << endl; - - _logger->trace(_traceLevels->securityCat, s.str()); - } -} - -void -IceSecurity::Ssl::ErrorReporter::fatalError(const SAXParseException& toCatch) -{ - _sawErrors = true; - - if (_traceLevels->security >= SECURITY_PARSE_WARNINGS) - { - ostringstream s; - - s << "Xerces-c Init Exception: "<< "Fatal error at file \"" - << DOMString(toCatch.getSystemId()) - << "\", line " << toCatch.getLineNumber() - << ", column " << toCatch.getColumnNumber() - << "\n Message: " << DOMString(toCatch.getMessage()) << endl; - - _logger->trace(_traceLevels->securityCat, s.str()); - } -} - -void -IceSecurity::Ssl::ErrorReporter::resetErrors() -{ - // No-op in this case -} - +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <iostream>
+#include <sstream>
+
+#include <sax/SAXParseException.hpp>
+#include <Ice/SslConfigErrorReporter.h>
+#include <stdlib.h>
+#include <string.h>
+#include <Ice/Security.h>
+
+using namespace std;
+
+void
+IceSecurity::Ssl::ErrorReporter::warning(const SAXParseException& toCatch)
+{
+ if (ICE_SECURITY_LEVEL_PARSEWARNINGS)
+ {
+ ostringstream s;
+
+ s << "SSL configuration file parse warning.\n"
+ << "Xerces-c Init Exception: "<< "Warning at file \""
+ << DOMString(toCatch.getSystemId())
+ << "\", line " << toCatch.getLineNumber()
+ << ", column " << toCatch.getColumnNumber()
+ << "\n Message: " << DOMString(toCatch.getMessage()) << endl;
+
+ ICE_PARSE_WARNING(s.str());
+ }
+}
+
+void
+IceSecurity::Ssl::ErrorReporter::error(const SAXParseException& toCatch)
+{
+ _sawErrors = true;
+
+ if (ICE_SECURITY_LEVEL_PARSEWARNINGS)
+ {
+ ostringstream s;
+
+ s << "SSL configuration file parse error.\n"
+ << "Xerces-c Init Exception: "<< "Error at file \""
+ << DOMString(toCatch.getSystemId())
+ << "\", line " << toCatch.getLineNumber()
+ << ", column " << toCatch.getColumnNumber()
+ << "\n Message: " << DOMString(toCatch.getMessage()) << endl;
+
+ ICE_PARSE_WARNING(s.str());
+ }
+}
+
+void
+IceSecurity::Ssl::ErrorReporter::fatalError(const SAXParseException& toCatch)
+{
+ _sawErrors = true;
+
+ if (ICE_SECURITY_LEVEL_PARSEWARNINGS)
+ {
+ ostringstream s;
+
+ s << "SSL configuration file parse error.\n"
+ << "Xerces-c Init Exception: "<< "Fatal error at file \""
+ << DOMString(toCatch.getSystemId())
+ << "\", line " << toCatch.getLineNumber()
+ << ", column " << toCatch.getColumnNumber()
+ << "\n Message: " << DOMString(toCatch.getMessage()) << endl;
+
+ ICE_PARSE_WARNING(s.str());
+ }
+}
+
+void
+IceSecurity::Ssl::ErrorReporter::resetErrors()
+{
+ // No-op in this case
+}
+
diff --git a/cpp/src/Ice/SslConfigErrorReporter.h b/cpp/src/Ice/SslConfigErrorReporter.h index 4de2df0e6b9..7e01761076e 100644 --- a/cpp/src/Ice/SslConfigErrorReporter.h +++ b/cpp/src/Ice/SslConfigErrorReporter.h @@ -1,76 +1,76 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_SSL_CONFIG_ERROR_REPORTER_H -#define ICE_SSL_CONFIG_ERROR_REPORTER_H - -#include <iostream> -#include <util/XercesDefs.hpp> -#include <dom/DOMString.hpp> -#include <sax/ErrorHandler.hpp> -#include <Ice/TraceLevels.h> -#include <Ice/Logger.h> - -namespace IceSecurity -{ - -namespace Ssl -{ - -using IceInternal::TraceLevelsPtr; -using Ice::LoggerPtr; - -class ErrorReporter : public ErrorHandler -{ - -public: - - ErrorReporter(TraceLevelsPtr traceLevels, LoggerPtr logger) : - _sawErrors(false), - _traceLevels(traceLevels), - _logger(logger) - { - } - - ~ErrorReporter() { } - - // Implementation of the error handler interface. - void warning(const SAXParseException& toCatch); - void error(const SAXParseException& toCatch); - void fatalError(const SAXParseException& toCatch); - void resetErrors(); - - inline bool getSawErrors() const { return _sawErrors; }; - -private: - // This is set if we get any errors, and is queryable via a getter method. - // It's used by the main code to suppress output if there are errors. - bool _sawErrors; - - TraceLevelsPtr _traceLevels; - LoggerPtr _logger; -}; - -using std::ostream; - -inline ostream& -operator << (ostream& target, const DOMString& s) -{ - char *p = s.transcode(); - target << p; - delete [] p; - return target; -} - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_CONFIG_ERROR_REPORTER_H
+#define ICE_SSL_CONFIG_ERROR_REPORTER_H
+
+#include <iostream>
+#include <util/XercesDefs.hpp>
+#include <dom/DOMString.hpp>
+#include <sax/ErrorHandler.hpp>
+#include <Ice/TraceLevels.h>
+#include <Ice/Logger.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+using IceInternal::TraceLevelsPtr;
+using Ice::LoggerPtr;
+
+class ErrorReporter : public ErrorHandler
+{
+
+public:
+
+ ErrorReporter(TraceLevelsPtr traceLevels, LoggerPtr logger) :
+ _sawErrors(false),
+ _traceLevels(traceLevels),
+ _logger(logger)
+ {
+ }
+
+ ~ErrorReporter() { }
+
+ // Implementation of the error handler interface.
+ void warning(const SAXParseException& toCatch);
+ void error(const SAXParseException& toCatch);
+ void fatalError(const SAXParseException& toCatch);
+ void resetErrors();
+
+ inline bool getSawErrors() const { return _sawErrors; };
+
+private:
+ // This is set if we get any errors, and is queryable via a getter method.
+ // It's used by the main code to suppress output if there are errors.
+ bool _sawErrors;
+
+ TraceLevelsPtr _traceLevels;
+ LoggerPtr _logger;
+};
+
+using std::ostream;
+
+inline ostream&
+operator << (ostream& target, const DOMString& s)
+{
+ char *p = s.transcode();
+ target << p;
+ delete [] p;
+ return target;
+}
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslConnection.h b/cpp/src/Ice/SslConnection.h index e65b297304b..0bd0a587bda 100644 --- a/cpp/src/Ice/SslConnection.h +++ b/cpp/src/Ice/SslConnection.h @@ -1,48 +1,48 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_SSL_CONNECTION_H -#define ICE_SSL_CONNECTION_H - -#include <Ice/Buffer.h> -#include <Ice/TraceLevels.h> -#include <Ice/Logger.h> - -namespace IceSecurity -{ - -namespace Ssl -{ - -using IceInternal::Buffer; -using IceInternal::TraceLevelsPtr; -using Ice::LoggerPtr; - -class Connection -{ - -public: - - virtual ~Connection() {}; - - virtual void shutdown() = 0; - - virtual int read(Buffer&, int) = 0; - virtual int write(Buffer&, int) = 0; - - virtual void setTrace(TraceLevelsPtr) = 0; - virtual void setLogger(LoggerPtr) = 0; -}; - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_CONNECTION_H
+#define ICE_SSL_CONNECTION_H
+
+#include <Ice/Buffer.h>
+#include <Ice/TraceLevels.h>
+#include <Ice/Logger.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+using IceInternal::Buffer;
+using IceInternal::TraceLevelsPtr;
+using Ice::LoggerPtr;
+
+class Connection
+{
+
+public:
+
+ virtual ~Connection() {};
+
+ virtual void shutdown() = 0;
+
+ virtual int read(Buffer&, int) = 0;
+ virtual int write(Buffer&, int) = 0;
+
+ virtual void setTrace(TraceLevelsPtr) = 0;
+ virtual void setLogger(LoggerPtr) = 0;
+};
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslConnectionOpenSSL.cpp b/cpp/src/Ice/SslConnectionOpenSSL.cpp index ae670b5063d..0dbcd79a689 100644 --- a/cpp/src/Ice/SslConnectionOpenSSL.cpp +++ b/cpp/src/Ice/SslConnectionOpenSSL.cpp @@ -1,688 +1,766 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** -#ifdef WIN32 -#pragma warning(disable:4786) -#endif - -#include <string> -#include <sstream> -#include <Ice/Network.h> -#include <JTC/JTC.h> -#include <Ice/Security.h> -#include <Ice/SslException.h> -#include <Ice/SslConnection.h> -#include <Ice/SslSystemOpenSSL.h> - -using namespace std; -using namespace IceInternal; - -using std::endl; - -//////////////////////////////// -////////// Connection ////////// -//////////////////////////////// - -// -// Public Methods -// - -IceSecurity::Ssl::OpenSSL::Connection::Connection(SSL* sslConnection, string& systemID) -{ - if (sslConnection == 0) - { - string errorString = "Construction of Connection with NULL SSL pointer."; - - throw ContextException(errorString.c_str(), __FILE__, __LINE__); - } - - // Get the system we were generated from - _system = IceSecurity::Ssl::Factory::getSystem(systemID); - - _sslConnection = sslConnection; - - _lastError = SSL_ERROR_NONE; - - initWantRead = 0; - initWantWrite = 0; -} - -IceSecurity::Ssl::OpenSSL::Connection::~Connection() -{ - METHOD_INV("OpenSSL::Connection::~Connection()"); - - shutdown(); - - IceSecurity::Ssl::Factory::releaseSystem(_system); - - METHOD_RET("OpenSSL::Connection::~Connection()"); -} - -void -IceSecurity::Ssl::OpenSSL::Connection::shutdown() -{ - METHOD_INV("OpenSSL::Connection::shutdown()"); - - if (_sslConnection != 0) - { - WARNING(string("shutting down SSL connection\n") + fdToString(SSL_get_fd(_sslConnection))); - - SSL_free(_sslConnection); - _sslConnection = 0; - } - - METHOD_RET("OpenSSL::Connection::shutdown()"); -} - -// -// Protected Methods -// - -int -IceSecurity::Ssl::OpenSSL::Connection::connect() -{ - METHOD_INV("OpenSSL::Connection::connect()"); - - int result = SSL_connect(_sslConnection); - - setLastError(result); - - METHOD_RET("OpenSSL::Connection::connect()"); - - return result; -} - -int -IceSecurity::Ssl::OpenSSL::Connection::accept() -{ - METHOD_INV("OpenSSL::Connection::accept()"); - - int result = SSL_accept(_sslConnection); - - setLastError(result); - - METHOD_RET("OpenSSL::Connection::accept()"); - - return result; -} - -int -IceSecurity::Ssl::OpenSSL::Connection::renegotiate() -{ - METHOD_INS("OpenSSL::Connection::renegotiate()"); - - return SSL_renegotiate(_sslConnection); -} - -int -IceSecurity::Ssl::OpenSSL::Connection::sslRead(char* buffer, int bufferSize) -{ - METHOD_INV("OpenSSL::Connection::sslRead()"); - - int bytesRead = SSL_read(_sslConnection, buffer, bufferSize); - - setLastError(bytesRead); - - METHOD_RET("OpenSSL::Connection::sslRead()"); - - return bytesRead; -} - -int -IceSecurity::Ssl::OpenSSL::Connection::sslWrite(char* buffer, int bufferSize) -{ - METHOD_INV("OpenSSL::Connection::sslWrite()"); - - int bytesWritten = SSL_write(_sslConnection, buffer, bufferSize); - - setLastError(bytesWritten); - - METHOD_RET("OpenSSL::Connection::sslWrite()"); - - return bytesWritten; -} - - -void -IceSecurity::Ssl::OpenSSL::Connection::printGetError(int errCode) -{ - if (SECURITY_LEVEL_PROTOCOL_DEBUG) - { - string errorString; - - switch (errCode) - { - case SSL_ERROR_NONE : - { - errorString = "SSL_ERROR_NONE"; - break; - } - - case SSL_ERROR_ZERO_RETURN : - { - errorString = "SSL_ERROR_ZERO_RETURN"; - break; - } - - case SSL_ERROR_WANT_READ : - { - errorString = "SSL_ERROR_WANT_READ"; - break; - } - - case SSL_ERROR_WANT_WRITE : - { - errorString = "SSL_ERROR_WANT_WRITE"; - break; - } - - case SSL_ERROR_WANT_CONNECT : - { - errorString = "SSL_ERROR_WANT_CONNECT"; - break; - } - - case SSL_ERROR_WANT_X509_LOOKUP : - { - errorString = "SSL_ERROR_WANT_X509_LOOKUP"; - break; - } - - case SSL_ERROR_SYSCALL : - { - errorString = "SSL_ERROR_SYSCALL"; - break; - } - - case SSL_ERROR_SSL : - { - errorString = "SSL_ERROR_SSL"; - break; - } - } - - if (!errorString.empty()) - { - SECURITY_LOGGER(string("Encountered: ") + errorString) - } - } -} - -// protocolWrite() -// -// The entire purpose of this strange little routine is to provide OpenSSL with a -// SSL_write() when they request one (this is for handshaking purposes). It writes -// nothing at all. Its entire purpose is jut to call the SSL_write() through one. -// of our defined methods. The SSL_write() will end up only writing protocol handshake -// packets, not application packets. This looks wierd, but it is essentially what -// the demo programs are doing, so I feel okay copying them. The only reason that I -// have defined the buffer[] array is so that I have a valid buffer pointer. -void -IceSecurity::Ssl::OpenSSL::Connection::protocolWrite() -{ - METHOD_INV("OpenSSL::Connection::protocolWrite()"); - - static char buffer[10]; - - memset(buffer, 0, sizeof(buffer)); - - // Note: We should be calling the write(char*,int) method here, - // not the write(Buffer&,int) method. If things start acting - // strangely, check this! - sslWrite(buffer,0); - - METHOD_RET("OpenSSL::Connection::protocolWrite()"); -} - -int -IceSecurity::Ssl::OpenSSL::Connection::readInBuffer(Buffer& buf) -{ - JTCSyncT<JTCMutex> sync(_inBufferMutex); - - METHOD_INV("OpenSSL::Connection::readInBuffer()"); - - int bytesRead = 0; - - if (!_inBuffer.b.empty()) - { - // Just how big is the destination? - int bufferSize = buf.b.end() - buf.i; - - // And how much do we have in our _inBuffer to copy? - int inBufferSize = _inBuffer.i - _inBuffer.b.begin(); - - // Select how many bytes we can handle. - bytesRead = min(bufferSize, inBufferSize); - - // Iterators that indicate how much of the _inBuffer we're going to copy - Buffer::Container::iterator inBufferBegin = _inBuffer.b.begin(); - Buffer::Container::iterator inBufferEndAt = (_inBuffer.b.begin() + bytesRead); - - // Copy over the bytes from the _inBuffer to our destination buffer - buf.i = copy(inBufferBegin, inBufferEndAt, buf.i); - - // Erase the data that we've copied out of the _inBuffer. - _inBuffer.b.erase(inBufferBegin, inBufferEndAt); - - if (SECURITY_LEVEL_PROTOCOL) - { - string protocolString = "Copied "; - protocolString += Int(bytesRead); - protocolString += string(" bytes from SSL buffer\n"); - protocolString += fdToString(SSL_get_fd(_sslConnection)); - - PROTOCOL(protocolString); - } - } - - METHOD_RET("OpenSSL::Connection::readInBuffer()"); - - return bytesRead; -} - -int -IceSecurity::Ssl::OpenSSL::Connection::readSelect(int timeout) -{ - METHOD_INV("OpenSSL::Connection::readSelect()"); - - int ret; - int fd = SSL_get_fd(_sslConnection); - fd_set rFdSet; - - struct timeval tv; - - if (timeout >= 0) - { - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000; - } - - do - { - FD_ZERO(&rFdSet); - FD_SET(fd, &rFdSet); - - if (timeout >= 0) - { - ret = ::select(fd + 1, &rFdSet, 0, 0, &tv); - } - else - { - ret = ::select(fd + 1, &rFdSet, 0, 0, 0); - } - } - while (ret == SOCKET_ERROR && interrupted()); - - if (ret == SOCKET_ERROR) - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - - if (ret == 0) - { - throw TimeoutException(__FILE__, __LINE__); - } - - METHOD_RET("OpenSSL::Connection::readSelect()"); - - return FD_ISSET(fd, &rFdSet); -} - -int -IceSecurity::Ssl::OpenSSL::Connection::writeSelect(int timeout) -{ - METHOD_INV("OpenSSL::Connection::writeSelect()"); - - int ret; - int fd = SSL_get_fd(_sslConnection); - fd_set wFdSet; - - struct timeval tv; - - if (timeout >= 0) - { - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000; - } - - do - { - FD_ZERO(&wFdSet); - FD_SET(fd, &wFdSet); - - if (timeout >= 0) - { - ret = ::select(fd + 1, 0, &wFdSet, 0, &tv); - } - else - { - ret = ::select(fd + 1, 0, &wFdSet, 0, 0); - } - } - while (ret == SOCKET_ERROR && interrupted()); - - if (ret == SOCKET_ERROR) - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - - if (ret == 0) - { - throw TimeoutException(__FILE__, __LINE__); - } - - METHOD_RET("OpenSSL::Connection::writeSelect()"); - - return FD_ISSET(fd, &wFdSet); -} - -int -IceSecurity::Ssl::OpenSSL::Connection::readSSL(Buffer& buf, int timeout) -{ - METHOD_INV("OpenSSL::Connection::readSSL()"); - - int packetSize = buf.b.end() - buf.i; - int totalBytesRead = 0; - int bytesPending; - int bytesRead; - - // We keep reading until we're done. - while (buf.i != buf.b.end()) - { - // Ensure we're initialized. - if (init(timeout)) - { - bytesPending = pending(); - - if (!bytesPending && readSelect(timeout)) - { - bytesPending = 1; - } - - if (!bytesPending) - { - // We're done here. - break; - } - - bytesRead = sslRead((char *)buf.i, packetSize); - - switch (getLastError()) - { - case SSL_ERROR_NONE: - { - if (bytesRead > 0) - { - ostringstream s; - - s << "received " << bytesRead << " of " << packetSize; - s << " bytes via SSL\n" << fdToString(SSL_get_fd(_sslConnection)); - - PROTOCOL(s.str()); - - totalBytesRead += bytesRead; - - buf.i += bytesRead; - - if (packetSize > buf.b.end() - buf.i) - { - packetSize = buf.b.end() - buf.i; - } - } - else - { - // TODO: The client application performs a cleanup at this point, - // not even shutting down SSL - it just frees the SSL - // structure. The server does nothing. I'm ignoring this, - // at the moment, I'm sure it will come back at me. - - PROTOCOL("Error SSL_ERROR_NONE: Repeating as per protocol."); - } - continue; - } - - case SSL_ERROR_WANT_WRITE: - { - // If we get this error here, it HAS to be because the protocol wants - // to do something handshake related. As such, We're going to call - // write with an empty buffer. I've seen this done in the demo - // programs, so this should be valid. No actual application data - // will be sent, just protocol packets. - - PROTOCOL("Error SSL_ERROR_WANT_WRITE."); - - protocolWrite(); - - continue; - } - - case SSL_ERROR_WANT_READ: - { - // Repeat with the same arguments! (as in the OpenSSL documentation) - // Whatever happened, the last read didn't actually read anything for - // us. This is effectively a retry. - - PROTOCOL("Error SSL_ERROR_WANT_READ: Repeating as per protocol."); - - continue; - } - - case SSL_ERROR_WANT_X509_LOOKUP: - { - // Perform another read. The read should take care of this. - - PROTOCOL("Error SSL_ERROR_WANT_X509_LOOKUP: Repeating as per protocol."); - - continue; - } - - case SSL_ERROR_SYSCALL: - { - if(bytesRead == -1) - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - else - { - string errorString = "SSL_ERROR_SYSCALL"; - - EXCEPTION(errorString); - - throw ShutdownException(errorString.c_str(), __FILE__, __LINE__); - } - } - - case SSL_ERROR_SSL: - { - string errorString = "SSL_ERROR_SSL"; - - EXCEPTION(errorString); - - throw ShutdownException(errorString.c_str(), __FILE__, __LINE__); - } - - case SSL_ERROR_ZERO_RETURN: - { - string errorString = "SSL_ERROR_ZERO_RETURN"; - - EXCEPTION(errorString); - - throw ShutdownException(errorString.c_str(), __FILE__, __LINE__); - } - } - } - } - - METHOD_RET("OpenSSL::Connection::readSSL()"); - - return totalBytesRead; -} - -void -IceSecurity::Ssl::OpenSSL::Connection::showCertificateChain(BIO* bio) -{ - STACK_OF(X509)* sk; - - // Big nasty buffer - char buffer[4096]; - - if ((sk = SSL_get_peer_cert_chain(_sslConnection)) != 0) - { - BIO_printf(bio,"---\nCertificate chain\n"); - - for (int i = 0; i < sk_X509_num(sk); i++) - { - X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk,i)), buffer, sizeof(buffer)); - BIO_printf(bio, "%2d s:%s\n", i, buffer); - - X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk,i)), buffer, sizeof(buffer)); - BIO_printf(bio, " i:%s\n", buffer); - - PEM_write_bio_X509(bio, sk_X509_value(sk, i)); - } - } - else - { - BIO_printf(bio, "---\nNo peer certificate chain available.\n"); - } -} - -void -IceSecurity::Ssl::OpenSSL::Connection::showPeerCertificate(BIO* bio, const char* connType) -{ - X509* peerCert = 0; - char buffer[4096]; - - if ((peerCert = SSL_get_peer_certificate(_sslConnection)) != 0) - { - BIO_printf(bio, "%s Certificate\n", connType); - PEM_write_bio_X509(bio, peerCert); - - X509_NAME_oneline(X509_get_subject_name(peerCert), buffer, sizeof(buffer)); - BIO_printf(bio, "subject=%s\n", buffer); - - X509_NAME_oneline(X509_get_issuer_name(peerCert), buffer, sizeof(buffer)); - BIO_printf(bio, "issuer=%s\n", buffer); - - EVP_PKEY *pktmp; - pktmp = X509_get_pubkey(peerCert); - BIO_printf(bio,"%s public key is %d bit\n", connType, EVP_PKEY_bits(pktmp)); - EVP_PKEY_free(pktmp); - - X509_free(peerCert); - } - else - { - BIO_printf(bio, "No %s certificate available.\n", connType); - } -} - -void -IceSecurity::Ssl::OpenSSL::Connection::showSharedCiphers(BIO* bio) -{ - char buffer[4096]; - char* strpointer = 0; - - if ((strpointer = SSL_get_shared_ciphers(_sslConnection, buffer, sizeof(buffer))) != 0) - { - // This works only for SSL 2. In later protocol - // versions, the client does not know what other - // ciphers (in addition to the one to be used - // in the current connection) the server supports. - - BIO_printf(bio, "---\nShared Ciphers:\n"); - - int j = 0; - int i = 0; - - while (*strpointer) - { - if (*strpointer == ':') - { - BIO_write(bio, " ", (15-j%25)); - i++; - j=0; - BIO_write(bio, ((i%3)?" ":"\n"), 1); - } - else - { - BIO_write(bio, strpointer, 1); - j++; - } - - strpointer++; - } - - BIO_write(bio,"\n",1); - } -} - -void -IceSecurity::Ssl::OpenSSL::Connection::showSessionInfo(BIO* bio) -{ - if (_sslConnection->hit) - { - BIO_printf(bio, "Reused session-id\n"); - } - - PEM_write_bio_SSL_SESSION(bio, SSL_get_session(_sslConnection)); -} - -void -IceSecurity::Ssl::OpenSSL::Connection::showSelectedCipherInfo(BIO* bio) -{ - const char* str; - SSL_CIPHER* cipher; - - // Show the cipher that was finally selected. - cipher = SSL_get_current_cipher(_sslConnection); - - str = SSL_CIPHER_get_name(cipher); - BIO_printf(bio, "Cipher Version: %s\n", ((str != 0) ? str : "(NONE)")); - - str = SSL_CIPHER_get_version(cipher); - BIO_printf(bio, "Cipher Name: %s\n", ((str != 0) ? str : "(NONE)")); -} - -void -IceSecurity::Ssl::OpenSSL::Connection::showHandshakeStats(BIO* bio) -{ - BIO_printf(bio, "---\nSSL handshake has read %ld bytes and written %ld bytes\n", - BIO_number_read(SSL_get_rbio(_sslConnection)), - BIO_number_written(SSL_get_wbio(_sslConnection))); -} - -void -IceSecurity::Ssl::OpenSSL::Connection::showClientCAList(BIO* bio, const char* connType) -{ - char buffer[4096]; - STACK_OF(X509_NAME)* sk = SSL_get_client_CA_list(_sslConnection); - - if ((sk != 0) && (sk_X509_NAME_num(sk) > 0)) - { - BIO_printf(bio,"---\nAcceptable %s certificate CA names\n", connType); - - for (int i = 0; i < sk_X509_NAME_num(sk); i++) - { - X509_NAME_oneline(sk_X509_NAME_value(sk, i), buffer, sizeof(buffer)); - BIO_write(bio, buffer, strlen(buffer)); - BIO_write(bio,"\n", 1); - } - } - else - { - BIO_printf(bio,"---\nNo %s certificate CA names sent\n", connType); - } -} +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+#ifdef WIN32
+#pragma warning(disable:4786)
+#endif
+
+#include <openssl/err.h>
+#include <string>
+#include <sstream>
+#include <Ice/Network.h>
+#include <JTC/JTC.h>
+#include <Ice/Security.h>
+#include <Ice/SslException.h>
+#include <Ice/SslConnection.h>
+#include <Ice/SslSystemOpenSSL.h>
+
+using namespace std;
+using namespace IceInternal;
+
+using std::endl;
+
+////////////////////////////////
+////////// Connection //////////
+////////////////////////////////
+
+//
+// Public Methods
+//
+
+IceSecurity::Ssl::OpenSSL::Connection::Connection(SSL* sslConnection, string& systemID)
+{
+ assert(sslConnection);
+
+ // Get the system we were generated from
+ _system = IceSecurity::Ssl::Factory::getSystem(systemID);
+
+ _sslConnection = sslConnection;
+
+ _lastError = SSL_ERROR_NONE;
+
+ initWantRead = 0;
+ initWantWrite = 0;
+}
+
+IceSecurity::Ssl::OpenSSL::Connection::~Connection()
+{
+ ICE_METHOD_INV("OpenSSL::Connection::~Connection()");
+
+ shutdown();
+
+ IceSecurity::Ssl::Factory::releaseSystem(_system);
+
+ ICE_METHOD_RET("OpenSSL::Connection::~Connection()");
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::shutdown()
+{
+ ICE_METHOD_INV("OpenSSL::Connection::shutdown()");
+
+ if (_sslConnection != 0)
+ {
+ ICE_WARNING(string("shutting down SSL connection\n") + fdToString(SSL_get_fd(_sslConnection)));
+
+ SSL_free(_sslConnection);
+ _sslConnection = 0;
+ }
+
+ ICE_METHOD_RET("OpenSSL::Connection::shutdown()");
+}
+
+//
+// Protected Methods
+//
+
+int
+IceSecurity::Ssl::OpenSSL::Connection::connect()
+{
+ ICE_METHOD_INV("OpenSSL::Connection::connect()");
+
+ int result = SSL_connect(_sslConnection);
+
+ setLastError(result);
+
+ ICE_METHOD_RET("OpenSSL::Connection::connect()");
+
+ return result;
+}
+
+int
+IceSecurity::Ssl::OpenSSL::Connection::accept()
+{
+ ICE_METHOD_INV("OpenSSL::Connection::accept()");
+
+ int result = SSL_accept(_sslConnection);
+
+ setLastError(result);
+
+ ICE_METHOD_RET("OpenSSL::Connection::accept()");
+
+ return result;
+}
+
+int
+IceSecurity::Ssl::OpenSSL::Connection::renegotiate()
+{
+ ICE_METHOD_INS("OpenSSL::Connection::renegotiate()");
+
+ return SSL_renegotiate(_sslConnection);
+}
+
+int
+IceSecurity::Ssl::OpenSSL::Connection::sslRead(char* buffer, int bufferSize)
+{
+ ICE_METHOD_INV("OpenSSL::Connection::sslRead()");
+
+ int bytesRead = SSL_read(_sslConnection, buffer, bufferSize);
+
+ setLastError(bytesRead);
+
+ ICE_METHOD_RET("OpenSSL::Connection::sslRead()");
+
+ return bytesRead;
+}
+
+int
+IceSecurity::Ssl::OpenSSL::Connection::sslWrite(char* buffer, int bufferSize)
+{
+ ICE_METHOD_INV("OpenSSL::Connection::sslWrite()");
+
+ int bytesWritten = SSL_write(_sslConnection, buffer, bufferSize);
+
+ setLastError(bytesWritten);
+
+ ICE_METHOD_RET("OpenSSL::Connection::sslWrite()");
+
+ return bytesWritten;
+}
+
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::printGetError(int errCode)
+{
+ if (ICE_SECURITY_LEVEL_PROTOCOL_DEBUG)
+ {
+ string errorString;
+
+ switch (errCode)
+ {
+ case SSL_ERROR_NONE :
+ {
+ errorString = "SSL_ERROR_NONE";
+ break;
+ }
+
+ case SSL_ERROR_ZERO_RETURN :
+ {
+ errorString = "SSL_ERROR_ZERO_RETURN";
+ break;
+ }
+
+ case SSL_ERROR_WANT_READ :
+ {
+ errorString = "SSL_ERROR_WANT_READ";
+ break;
+ }
+
+ case SSL_ERROR_WANT_WRITE :
+ {
+ errorString = "SSL_ERROR_WANT_WRITE";
+ break;
+ }
+
+ case SSL_ERROR_WANT_CONNECT :
+ {
+ errorString = "SSL_ERROR_WANT_CONNECT";
+ break;
+ }
+
+ case SSL_ERROR_WANT_X509_LOOKUP :
+ {
+ errorString = "SSL_ERROR_WANT_X509_LOOKUP";
+ break;
+ }
+
+ case SSL_ERROR_SYSCALL :
+ {
+ errorString = "SSL_ERROR_SYSCALL";
+ break;
+ }
+
+ case SSL_ERROR_SSL :
+ {
+ errorString = "SSL_ERROR_SSL";
+ break;
+ }
+ }
+
+ if (!errorString.empty())
+ {
+ ICE_SECURITY_LOGGER(string("Encountered: ") + errorString)
+ }
+ }
+}
+
+// protocolWrite()
+//
+// The entire purpose of this strange little routine is to provide OpenSSL with a
+// SSL_write() when they request one (this is for handshaking purposes). It writes
+// nothing at all. Its entire purpose is jut to call the SSL_write() through one.
+// of our defined methods. The SSL_write() will end up only writing protocol handshake
+// packets, not application packets. This looks wierd, but it is essentially what
+// the demo programs are doing, so I feel okay copying them. The only reason that I
+// have defined the buffer[] array is so that I have a valid buffer pointer.
+void
+IceSecurity::Ssl::OpenSSL::Connection::protocolWrite()
+{
+ ICE_METHOD_INV("OpenSSL::Connection::protocolWrite()");
+
+ static char buffer[10];
+
+ memset(buffer, 0, sizeof(buffer));
+
+ // Note: We should be calling the write(char*,int) method here,
+ // not the write(Buffer&,int) method. If things start acting
+ // strangely, check this!
+ sslWrite(buffer,0);
+
+ ICE_METHOD_RET("OpenSSL::Connection::protocolWrite()");
+}
+
+int
+IceSecurity::Ssl::OpenSSL::Connection::readInBuffer(Buffer& buf)
+{
+ JTCSyncT<JTCMutex> sync(_inBufferMutex);
+
+ ICE_METHOD_INV("OpenSSL::Connection::readInBuffer()");
+
+ int bytesRead = 0;
+
+ if (!_inBuffer.b.empty())
+ {
+ // Just how big is the destination?
+ int bufferSize = buf.b.end() - buf.i;
+
+ // And how much do we have in our _inBuffer to copy?
+ int inBufferSize = _inBuffer.i - _inBuffer.b.begin();
+
+ // Select how many bytes we can handle.
+ bytesRead = min(bufferSize, inBufferSize);
+
+ // Iterators that indicate how much of the _inBuffer we're going to copy
+ Buffer::Container::iterator inBufferBegin = _inBuffer.b.begin();
+ Buffer::Container::iterator inBufferEndAt = (_inBuffer.b.begin() + bytesRead);
+
+ // Copy over the bytes from the _inBuffer to our destination buffer
+ buf.i = copy(inBufferBegin, inBufferEndAt, buf.i);
+
+ // Erase the data that we've copied out of the _inBuffer.
+ _inBuffer.b.erase(inBufferBegin, inBufferEndAt);
+
+ if (ICE_SECURITY_LEVEL_PROTOCOL)
+ {
+ string protocolString = "Copied ";
+ protocolString += Int(bytesRead);
+ protocolString += string(" bytes from SSL buffer\n");
+ protocolString += fdToString(SSL_get_fd(_sslConnection));
+
+ ICE_PROTOCOL(protocolString);
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::Connection::readInBuffer()");
+
+ return bytesRead;
+}
+
+int
+IceSecurity::Ssl::OpenSSL::Connection::readSelect(int timeout)
+{
+ ICE_METHOD_INV("OpenSSL::Connection::readSelect()");
+
+ int ret;
+ int fd = SSL_get_fd(_sslConnection);
+ fd_set rFdSet;
+
+ struct timeval tv;
+
+ if (timeout >= 0)
+ {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
+ }
+
+ do
+ {
+ FD_ZERO(&rFdSet);
+ FD_SET(fd, &rFdSet);
+
+ if (timeout >= 0)
+ {
+ ret = ::select(fd + 1, &rFdSet, 0, 0, &tv);
+ }
+ else
+ {
+ ret = ::select(fd + 1, &rFdSet, 0, 0, 0);
+ }
+ }
+ while (ret == SOCKET_ERROR && interrupted());
+
+ if (ret == SOCKET_ERROR)
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+
+ if (ret == 0)
+ {
+ throw TimeoutException(__FILE__, __LINE__);
+ }
+
+ ICE_METHOD_RET("OpenSSL::Connection::readSelect()");
+
+ return FD_ISSET(fd, &rFdSet);
+}
+
+int
+IceSecurity::Ssl::OpenSSL::Connection::writeSelect(int timeout)
+{
+ ICE_METHOD_INV("OpenSSL::Connection::writeSelect()");
+
+ int ret;
+ int fd = SSL_get_fd(_sslConnection);
+ fd_set wFdSet;
+
+ struct timeval tv;
+
+ if (timeout >= 0)
+ {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000;
+ }
+
+ do
+ {
+ FD_ZERO(&wFdSet);
+ FD_SET(fd, &wFdSet);
+
+ if (timeout >= 0)
+ {
+ ret = ::select(fd + 1, 0, &wFdSet, 0, &tv);
+ }
+ else
+ {
+ ret = ::select(fd + 1, 0, &wFdSet, 0, 0);
+ }
+ }
+ while (ret == SOCKET_ERROR && interrupted());
+
+ if (ret == SOCKET_ERROR)
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+
+ if (ret == 0)
+ {
+ throw TimeoutException(__FILE__, __LINE__);
+ }
+
+ ICE_METHOD_RET("OpenSSL::Connection::writeSelect()");
+
+ return FD_ISSET(fd, &wFdSet);
+}
+
+int
+IceSecurity::Ssl::OpenSSL::Connection::readSSL(Buffer& buf, int timeout)
+{
+ ICE_METHOD_INV("OpenSSL::Connection::readSSL()");
+
+ int packetSize = buf.b.end() - buf.i;
+ int totalBytesRead = 0;
+ int bytesPending;
+ int bytesRead;
+
+ // We keep reading until we're done.
+ while (buf.i != buf.b.end())
+ {
+ // Ensure we're initialized.
+ if (init(timeout))
+ {
+ bytesPending = pending();
+
+ if (!bytesPending && readSelect(timeout))
+ {
+ bytesPending = 1;
+ }
+
+ if (!bytesPending)
+ {
+ // We're done here.
+ break;
+ }
+
+ bytesRead = sslRead((char *)buf.i, packetSize);
+
+ switch (getLastError())
+ {
+ case SSL_ERROR_NONE:
+ {
+ if (bytesRead > 0)
+ {
+ ostringstream s;
+
+ s << "received " << bytesRead << " of " << packetSize;
+ s << " bytes via SSL\n" << fdToString(SSL_get_fd(_sslConnection));
+
+ ICE_PROTOCOL(s.str());
+
+ totalBytesRead += bytesRead;
+
+ buf.i += bytesRead;
+
+ if (packetSize > buf.b.end() - buf.i)
+ {
+ packetSize = buf.b.end() - buf.i;
+ }
+ }
+ else
+ {
+ // TODO: The client application performs a cleanup at this point,
+ // not even shutting down SSL - it just frees the SSL
+ // structure. The server does nothing. I'm ignoring this,
+ // at the moment, I'm sure it will come back at me.
+
+ ICE_PROTOCOL("Error SSL_ERROR_NONE: Repeating as per protocol.");
+ }
+ continue;
+ }
+
+ case SSL_ERROR_WANT_WRITE:
+ {
+ // If we get this error here, it HAS to be because the protocol wants
+ // to do something handshake related. As such, We're going to call
+ // write with an empty buffer. I've seen this done in the demo
+ // programs, so this should be valid. No actual application data
+ // will be sent, just protocol packets.
+
+ ICE_PROTOCOL("Error SSL_ERROR_WANT_WRITE.");
+
+ protocolWrite();
+
+ continue;
+ }
+
+ case SSL_ERROR_WANT_READ:
+ {
+ // Repeat with the same arguments! (as in the OpenSSL documentation)
+ // Whatever happened, the last read didn't actually read anything for
+ // us. This is effectively a retry.
+
+ ICE_PROTOCOL("Error SSL_ERROR_WANT_READ: Repeating as per protocol.");
+
+ continue;
+ }
+
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ {
+ // Perform another read. The read should take care of this.
+
+ ICE_PROTOCOL("Error SSL_ERROR_WANT_X509_LOOKUP: Repeating as per protocol.");
+
+ continue;
+ }
+
+ case SSL_ERROR_SYSCALL:
+ {
+ if(bytesRead == -1)
+ {
+ // IO Error in underlying BIO
+
+ if (interrupted())
+ {
+ break;
+ }
+
+ if (wouldBlock())
+ {
+ break;
+ }
+
+ if (connectionLost())
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+ else // (bytesRead == 0)
+ {
+ // Protocol Error: Unexpected EOF
+ string errorString = "Encountered an EOF that violates the SSL Protocol.\n";
+
+ ICE_SSLERRORS(errorString);
+ ICE_EXCEPTION(errorString);
+
+ throw ProtocolException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+
+ case SSL_ERROR_SSL:
+ {
+ string errorString = "Encountered a violation the SSL Protocol.\n";
+
+ ICE_SSLERRORS(errorString);
+ ICE_EXCEPTION(errorString);
+
+ throw ProtocolException(errorString.c_str(), __FILE__, __LINE__);
+ }
+
+ case SSL_ERROR_ZERO_RETURN:
+ {
+ // string errorString = "SSL_ERROR_ZERO_RETURN";
+ // ICE_EXCEPTION(errorString);
+ // throw ShutdownException(errorString.c_str(), __FILE__, __LINE__);
+
+ if (connectionLost())
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+ }
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::Connection::readSSL()");
+
+ return totalBytesRead;
+}
+
+string
+IceSecurity::Ssl::OpenSSL::Connection::sslGetErrors()
+{
+ ICE_METHOD_INV("OpenSSL::Connection::sslGetErrors()");
+
+ string errorMessage;
+ char buf[200];
+ char bigBuffer[1024];
+ const char* file = 0;
+ const char* data = 0;
+ int line = 0;
+ int flags = 0;
+ unsigned errorCode = 0;
+ int errorNum = 1;
+
+ unsigned long es = CRYPTO_thread_id();
+
+ while ((errorCode = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0)
+ {
+ sprintf(bigBuffer,"%6d - Thread ID: %lu\n", errorNum, es);
+ errorMessage += bigBuffer;
+
+ sprintf(bigBuffer,"%6d - Error: %u\n", errorNum, errorCode);
+ errorMessage += bigBuffer;
+
+ // Request an error from the OpenSSL library
+ ERR_error_string_n(errorCode, buf, sizeof(buf));
+ sprintf(bigBuffer,"%6d - Message: %s\n", errorNum, buf);
+ errorMessage += bigBuffer;
+
+ sprintf(bigBuffer,"%6d - Location: %s, %d\n", errorNum, file, line);
+ errorMessage += bigBuffer;
+
+ if (flags & ERR_TXT_STRING)
+ {
+ sprintf(bigBuffer,"%6d - Data: %s\n", errorNum, data);
+ errorMessage += bigBuffer;
+ }
+
+ errorNum++;
+ }
+
+ ICE_METHOD_RET("OpenSSL::Connection::sslGetErrors()");
+
+ return errorMessage;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::showCertificateChain(BIO* bio)
+{
+ STACK_OF(X509)* sk;
+
+ // Big nasty buffer
+ char buffer[4096];
+
+ if ((sk = SSL_get_peer_cert_chain(_sslConnection)) != 0)
+ {
+ BIO_printf(bio,"---\nCertificate chain\n");
+
+ for (int i = 0; i < sk_X509_num(sk); i++)
+ {
+ X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk,i)), buffer, sizeof(buffer));
+ BIO_printf(bio, "%2d s:%s\n", i, buffer);
+
+ X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk,i)), buffer, sizeof(buffer));
+ BIO_printf(bio, " i:%s\n", buffer);
+
+ PEM_write_bio_X509(bio, sk_X509_value(sk, i));
+ }
+ }
+ else
+ {
+ BIO_printf(bio, "---\nNo peer certificate chain available.\n");
+ }
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::showPeerCertificate(BIO* bio, const char* connType)
+{
+ X509* peerCert = 0;
+ char buffer[4096];
+
+ if ((peerCert = SSL_get_peer_certificate(_sslConnection)) != 0)
+ {
+ BIO_printf(bio, "%s Certificate\n", connType);
+ PEM_write_bio_X509(bio, peerCert);
+
+ X509_NAME_oneline(X509_get_subject_name(peerCert), buffer, sizeof(buffer));
+ BIO_printf(bio, "subject=%s\n", buffer);
+
+ X509_NAME_oneline(X509_get_issuer_name(peerCert), buffer, sizeof(buffer));
+ BIO_printf(bio, "issuer=%s\n", buffer);
+
+ EVP_PKEY *pktmp;
+ pktmp = X509_get_pubkey(peerCert);
+ BIO_printf(bio,"%s public key is %d bit\n", connType, EVP_PKEY_bits(pktmp));
+ EVP_PKEY_free(pktmp);
+
+ X509_free(peerCert);
+ }
+ else
+ {
+ BIO_printf(bio, "No %s certificate available.\n", connType);
+ }
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::showSharedCiphers(BIO* bio)
+{
+ char buffer[4096];
+ char* strpointer = 0;
+
+ if ((strpointer = SSL_get_shared_ciphers(_sslConnection, buffer, sizeof(buffer))) != 0)
+ {
+ // This works only for SSL 2. In later protocol
+ // versions, the client does not know what other
+ // ciphers (in addition to the one to be used
+ // in the current connection) the server supports.
+
+ BIO_printf(bio, "---\nShared Ciphers:\n");
+
+ int j = 0;
+ int i = 0;
+
+ while (*strpointer)
+ {
+ if (*strpointer == ':')
+ {
+ BIO_write(bio, " ", (15-j%25));
+ i++;
+ j=0;
+ BIO_write(bio, ((i%3)?" ":"\n"), 1);
+ }
+ else
+ {
+ BIO_write(bio, strpointer, 1);
+ j++;
+ }
+
+ strpointer++;
+ }
+
+ BIO_write(bio,"\n",1);
+ }
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::showSessionInfo(BIO* bio)
+{
+ if (_sslConnection->hit)
+ {
+ BIO_printf(bio, "Reused session-id\n");
+ }
+
+ PEM_write_bio_SSL_SESSION(bio, SSL_get_session(_sslConnection));
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::showSelectedCipherInfo(BIO* bio)
+{
+ const char* str;
+ SSL_CIPHER* cipher;
+
+ // Show the cipher that was finally selected.
+ cipher = SSL_get_current_cipher(_sslConnection);
+
+ str = SSL_CIPHER_get_name(cipher);
+ BIO_printf(bio, "Cipher Version: %s\n", ((str != 0) ? str : "(NONE)"));
+
+ str = SSL_CIPHER_get_version(cipher);
+ BIO_printf(bio, "Cipher Name: %s\n", ((str != 0) ? str : "(NONE)"));
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::showHandshakeStats(BIO* bio)
+{
+ BIO_printf(bio, "---\nSSL handshake has read %ld bytes and written %ld bytes\n",
+ BIO_number_read(SSL_get_rbio(_sslConnection)),
+ BIO_number_written(SSL_get_wbio(_sslConnection)));
+}
+
+void
+IceSecurity::Ssl::OpenSSL::Connection::showClientCAList(BIO* bio, const char* connType)
+{
+ char buffer[4096];
+ STACK_OF(X509_NAME)* sk = SSL_get_client_CA_list(_sslConnection);
+
+ if ((sk != 0) && (sk_X509_NAME_num(sk) > 0))
+ {
+ BIO_printf(bio,"---\nAcceptable %s certificate CA names\n", connType);
+
+ for (int i = 0; i < sk_X509_NAME_num(sk); i++)
+ {
+ X509_NAME_oneline(sk_X509_NAME_value(sk, i), buffer, sizeof(buffer));
+ BIO_write(bio, buffer, strlen(buffer));
+ BIO_write(bio,"\n", 1);
+ }
+ }
+ else
+ {
+ BIO_printf(bio,"---\nNo %s certificate CA names sent\n", connType);
+ }
+}
diff --git a/cpp/src/Ice/SslConnectionOpenSSL.h b/cpp/src/Ice/SslConnectionOpenSSL.h index 22f6ad3e943..fa14a3542f6 100644 --- a/cpp/src/Ice/SslConnectionOpenSSL.h +++ b/cpp/src/Ice/SslConnectionOpenSSL.h @@ -1,113 +1,116 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_SSL_CONNECTION_OPENSSL_H -#define ICE_SSL_CONNECTION_OPENSSL_H - -#include <openssl/ssl.h> -#include <Ice/SslConnection.h> -#include <Ice/SslSystem.h> -#include <Ice/Buffer.h> -#include <Ice/TraceLevels.h> -#include <Ice/Logger.h> - -namespace IceSecurity -{ - -namespace Ssl -{ - -namespace OpenSSL -{ - -using namespace Ice; - -class Connection : public IceSecurity::Ssl::Connection -{ - -public: - - Connection(SSL*, string&); - virtual ~Connection(); - - virtual void shutdown(); - - virtual int read(Buffer&, int) = 0; - virtual int write(Buffer&, int) = 0; - - virtual int init(int timeout = 0) = 0; - - void setTrace(TraceLevelsPtr traceLevels) { _traceLevels = traceLevels; }; - void setLogger(LoggerPtr traceLevels) { _logger = traceLevels; }; - - -protected: - - int connect(); - int accept(); - int renegotiate(); - - inline int pending() { return SSL_pending(_sslConnection); }; - inline int getLastError() const { return SSL_get_error(_sslConnection, _lastError); }; - - int sslRead(char*, int); - int sslWrite(char*, int); - - void printGetError(int); - - void protocolWrite(); - - int readInBuffer(Buffer&); - - int readSelect(int); - int writeSelect(int); - - int readSSL(Buffer&, int); - - virtual void showConnectionInfo() = 0; - - void showCertificateChain(BIO*); - void showPeerCertificate(BIO*, const char*); - void showSharedCiphers(BIO*); - void showSessionInfo(BIO*); - void showSelectedCipherInfo(BIO*); - void showHandshakeStats(BIO*); - void showClientCAList(BIO*, const char*); - - void setLastError(int errorCode) { _lastError = errorCode; }; - - // Pointer to the OpenSSL Connection structure. - SSL* _sslConnection; - - int _lastError; - - // TODO: Review this after a healthy stint of testing - // Buffer for application data that may be returned during handshake - // (probably won't contain anything, may be removed later). - Buffer _inBuffer; - JTCMutex _inBufferMutex; - - TraceLevelsPtr _traceLevels; - LoggerPtr _logger; - - System* _system; - - JTCMutex _initMutex; - int initWantRead; - int initWantWrite; -}; - -} - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_CONNECTION_OPENSSL_H
+#define ICE_SSL_CONNECTION_OPENSSL_H
+
+#include <openssl/ssl.h>
+#include <Ice/SslConnection.h>
+#include <Ice/SslSystem.h>
+#include <Ice/Buffer.h>
+#include <Ice/TraceLevels.h>
+#include <Ice/Logger.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+namespace OpenSSL
+{
+
+using namespace Ice;
+
+class Connection : public IceSecurity::Ssl::Connection
+{
+
+public:
+
+ Connection(SSL*, string&);
+ virtual ~Connection();
+
+ virtual void shutdown();
+
+ virtual int read(Buffer&, int) = 0;
+ virtual int write(Buffer&, int) = 0;
+
+ virtual int init(int timeout = 0) = 0;
+
+ void setTrace(TraceLevelsPtr traceLevels) { _traceLevels = traceLevels; };
+ void setLogger(LoggerPtr traceLevels) { _logger = traceLevels; };
+
+
+protected:
+
+ int connect();
+ int accept();
+ int renegotiate();
+
+ inline int pending() { return SSL_pending(_sslConnection); };
+ inline int getLastError() const { return SSL_get_error(_sslConnection, _lastError); };
+
+ int sslRead(char*, int);
+ int sslWrite(char*, int);
+
+ void printGetError(int);
+
+ void protocolWrite();
+
+ int readInBuffer(Buffer&);
+
+ int readSelect(int);
+ int writeSelect(int);
+
+ int readSSL(Buffer&, int);
+
+ // Retrieves errors from the OpenSSL library.
+ string sslGetErrors();
+
+ virtual void showConnectionInfo() = 0;
+
+ void showCertificateChain(BIO*);
+ void showPeerCertificate(BIO*, const char*);
+ void showSharedCiphers(BIO*);
+ void showSessionInfo(BIO*);
+ void showSelectedCipherInfo(BIO*);
+ void showHandshakeStats(BIO*);
+ void showClientCAList(BIO*, const char*);
+
+ void setLastError(int errorCode) { _lastError = errorCode; };
+
+ // Pointer to the OpenSSL Connection structure.
+ SSL* _sslConnection;
+
+ int _lastError;
+
+ // TODO: Review this after a healthy stint of testing
+ // Buffer for application data that may be returned during handshake
+ // (probably won't contain anything, may be removed later).
+ Buffer _inBuffer;
+ JTCMutex _inBufferMutex;
+
+ TraceLevelsPtr _traceLevels;
+ LoggerPtr _logger;
+
+ System* _system;
+
+ JTCMutex _initMutex;
+ int initWantRead;
+ int initWantWrite;
+};
+
+}
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslConnectionOpenSSLClient.cpp b/cpp/src/Ice/SslConnectionOpenSSLClient.cpp index 01ef26924ed..f4a7ad02a58 100644 --- a/cpp/src/Ice/SslConnectionOpenSSLClient.cpp +++ b/cpp/src/Ice/SslConnectionOpenSSLClient.cpp @@ -1,437 +1,481 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include <string> -#include <sstream> -#include <Ice/Network.h> -#include <Ice/Security.h> -#include <Ice/SslException.h> -#include <Ice/SslConnectionOpenSSLClient.h> - -using IceSecurity::Ssl::ShutdownException; -using namespace IceInternal; -using namespace std; - -//////////////////////////////////////////////// -////////// SslConnectionOpenSSLClient ////////// -//////////////////////////////////////////////// - -// -// Public Methods -// - -IceSecurity::Ssl::OpenSSL::ClientConnection::ClientConnection(SSL* connection, string& systemID) : - Connection(connection, systemID) -{ -} - -IceSecurity::Ssl::OpenSSL::ClientConnection::~ClientConnection() -{ - METHOD_INV("OpenSSL::ClientConnection::~ClientConnection()"); - - shutdown(); - - METHOD_RET("OpenSSL::ClientConnection::~ClientConnection()"); -} - -void -IceSecurity::Ssl::OpenSSL::ClientConnection::shutdown() -{ - METHOD_INV("OpenSSL::ClientConnection::shutdown()"); - - if (_sslConnection != 0) - { - int shutdown = 0; - int retries = 100; - - do - { - shutdown = SSL_shutdown(_sslConnection); - retries--; - } - while ((shutdown == 0) && (retries > 0)); - - if (shutdown <= 0) - { - ostringstream s; - s << "SSL shutdown failure encountered: code[" << shutdown << "] retries["; - s << retries << "]\n" << fdToString(SSL_get_fd(_sslConnection)); - PROTOCOL_DEBUG(s.str()); - } - } - - Connection::shutdown(); - - METHOD_RET("OpenSSL::ClientConnection::shutdown()"); -} - -int -IceSecurity::Ssl::OpenSSL::ClientConnection::init(int timeout) -{ - JTCSyncT<JTCMutex> sync(_initMutex); - - int retCode = 0; - - METHOD_INV("OpenSSL::ClientConnection::init()"); - - if (!SSL_is_init_finished(_sslConnection)) - { - int i = 0; - - if (initWantRead) - { - i = readSelect(timeout); - } - else if (initWantWrite) - { - i = writeSelect(timeout); - } - - if (initWantRead && i == 0) - { - return 0; - } - - if (initWantWrite && i == 0) - { - return 0; - } - - initWantRead = 0; - initWantWrite = 0; - - int result = connect(); - - // Find out what the error was (if any). - int code = getLastError(); - - printGetError(code); - - switch (code) - { - case SSL_ERROR_WANT_READ: - { - initWantRead = 1; - break; - } - - case SSL_ERROR_WANT_WRITE: - { - initWantWrite = 1; - break; - } - - - case SSL_ERROR_NONE: - case SSL_ERROR_WANT_X509_LOOKUP: - { - // Retry connect. - break; - } - - case SSL_ERROR_SYSCALL: - { - // This is a SOCKET_ERROR, but we don't use - // this define here as OpenSSL doesn't refer - // to it as a SOCKET_ERROR (but that's what it is - // if you look at their code). - if(result == -1) - { - if (interrupted()) - { - break; - } - - if (wouldBlock()) - { - readSelect(timeout); - break; - } - - if (connectionLost()) - { - ConnectionLostException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - else - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - } - else // result == 0 - { - string errorString = "SSL_ERROR_SYSCALL: During init()"; - - EXCEPTION(errorString); - - throw IceSecurity::Ssl::InitException(errorString.c_str(), __FILE__, __LINE__); - } - } - - case SSL_ERROR_SSL: - { - string errorString = "SSL_ERROR_SSL: During init()"; - - EXCEPTION(errorString); - - throw IceSecurity::Ssl::InitException(errorString.c_str(), __FILE__, __LINE__); - } - } - - retCode = SSL_is_init_finished(_sslConnection); - - if (retCode > 0) - { - // Init finished, look at the connection information. - showConnectionInfo(); - } - } - else - { - retCode = 1; - } - - METHOD_RET("OpenSSL::ClientConnection::init()"); - - return retCode; -} - -int -IceSecurity::Ssl::OpenSSL::ClientConnection::read(Buffer& buf, int timeout) -{ - METHOD_INV("OpenSSL::ClientConnection::read(Buffer&,int)"); - - int totalBytesRead = 0; - - // Initialization to 1 is a cheap trick to ensure we enter the loop. - int bytesRead = 1; - - // We keep reading until we're done. - while ((buf.i != buf.b.end()) && bytesRead) - { - // Copy over bytes from _inBuffer to buf. - bytesRead = readInBuffer(buf); - - // Nothing in the _inBuffer? - if (!bytesRead) - { - // Read from SSL. - bytesRead = readSSL(buf, timeout); - } - - // Keep track of the total number of bytes read. - totalBytesRead += bytesRead; - } - - METHOD_RET("OpenSSL::ClientConnection::read(Buffer&,int)"); - - return totalBytesRead; -} - -int -IceSecurity::Ssl::OpenSSL::ClientConnection::write(Buffer& buf, int timeout) -{ - METHOD_INV("OpenSSL::ClientConnection::write(Buffer&,int)"); - - int totalBytesWritten = 0; - int bytesWritten = 0; - - int packetSize = buf.b.end() - buf.i; - -#ifdef WIN32 - // - // Limit packet size to avoid performance problems on WIN32. - // (blatantly ripped off from Marc Laukien) - // - if (packetSize > 64 * 1024) - { - packetSize = 64 * 1024; - } -#endif - - // We keep reading until we're done - while (buf.i != buf.b.end()) - { - // Ensure we're initialized. - if (init(timeout)) - { - // Perform a select on the socket. - if (!writeSelect(timeout)) - { - // We're done here. - break; - } - - bytesWritten = sslWrite((char *)buf.i, packetSize); - - switch (getLastError()) - { - case SSL_ERROR_NONE: - { - if (bytesWritten > 0) - { - ostringstream s; - - s << "sent " << bytesWritten << " of " << packetSize; - s << " bytes via SSL\n" << fdToString(SSL_get_fd(_sslConnection)); - - PROTOCOL(s.str()); - - totalBytesWritten += bytesWritten; - - buf.i += bytesWritten; - - if (packetSize > buf.b.end() - buf.i) - { - packetSize = buf.b.end() - buf.i; - } - } - else - { - // TODO: The client application performs a cleanup at this point, - // not even shutting down SSL - it just frees the SSL - // structure. I'm ignoring this, at the moment, as I'm sure - // the demo is handling it in an artificial manner. - - PROTOCOL("Error SSL_ERROR_NONE: Repeating as per protocol."); - } - continue; - } - - case SSL_ERROR_WANT_WRITE: - { - // Repeat with the same arguments! (as in the OpenSSL documentation) - // Whatever happened, the last write didn't actually write anything - // for us. This is effectively a retry. - - PROTOCOL("Error SSL_ERROR_WANT_WRITE: Repeating as per protocol."); - - continue; - } - - case SSL_ERROR_WANT_READ: - { - // If we get this error here, it HAS to be because - // the protocol wants to do something handshake related. - // In the case that we might actually get some application data, - // we will use the base SSL read method, using the _inBuffer. - - PROTOCOL("Error SSL_ERROR_WANT_READ."); - - readSSL(_inBuffer, timeout); - - continue; - } - - case SSL_ERROR_WANT_X509_LOOKUP: - { - // Perform another read. The read should take care of this. - - PROTOCOL("Error SSL_ERROR_WANT_X509_LOOKUP: Repeating as per protocol."); - - continue; - } - - case SSL_ERROR_SYSCALL: - { - // NOTE: The demo client only throws an exception if there were actually bytes - // written. This is considered to be an error status requiring shutdown. - // If nothing was written, the demo client stops writing - we continue. - // This is potentially something wierd to watch out for. - if (bytesWritten != 0) - { - string errorString = "SSL_ERROR_SYSCALL"; - - EXCEPTION(errorString); - - throw ShutdownException(errorString.c_str(), __FILE__, __LINE__); - } - else - { - // Didn't write anything, continue, should be fine. - - PROTOCOL("Error SSL_ERROR_SYSCALL: Repeating as per protocol."); - - continue; - } - } - - case SSL_ERROR_SSL: - { - string errorString = "SSL_ERROR_SSL"; - - EXCEPTION(errorString); - - throw ShutdownException(errorString.c_str(), __FILE__, __LINE__); - } - - case SSL_ERROR_ZERO_RETURN: - { - string errorString = "SSL_ERROR_ZERO_RETURN"; - - EXCEPTION(errorString); - - throw ShutdownException(errorString.c_str(), __FILE__, __LINE__); - } - } - } - } - - METHOD_RET("OpenSSL::ClientConnection::write(Buffer&,int)"); - - return totalBytesWritten; -} - -// -// Protected Methods -// - -// This code blatantly stolen from OpenSSL demos, slightly repackaged, and completely ugly... -void -IceSecurity::Ssl::OpenSSL::ClientConnection::showConnectionInfo() -{ - METHOD_INV("OpenSSL::ClientConnection::showConnectionInfo()"); - - // Only in extreme cases do we enable this, partially because it doesn't use the Logger. - if (SECURITY_LEVEL_PROTOCOL_DEBUG) - { - PROTOCOL_DEBUG("Begin Connection Information"); - - BIO* bio = BIO_new_fp(stdout, BIO_NOCLOSE); - - showCertificateChain(bio); - - showPeerCertificate(bio,"Client"); - - // Something extra for the client - showClientCAList(bio, "Client"); - - showSharedCiphers(bio); - - showSelectedCipherInfo(bio); - - showHandshakeStats(bio); - - showSessionInfo(bio); - - PROTOCOL_DEBUG("End of Connection Information"); - - if (bio != 0) - { - BIO_free(bio); - bio = 0; - } - } - - METHOD_RET("OpenSSL::ClientConnection::showConnectionInfo()"); -} +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <string>
+#include <sstream>
+#include <Ice/Network.h>
+#include <Ice/Security.h>
+#include <Ice/SslException.h>
+#include <Ice/SslConnectionOpenSSLClient.h>
+
+using IceSecurity::Ssl::ShutdownException;
+using namespace IceInternal;
+using namespace std;
+
+////////////////////////////////////////////////
+////////// SslConnectionOpenSSLClient //////////
+////////////////////////////////////////////////
+
+//
+// Public Methods
+//
+
+IceSecurity::Ssl::OpenSSL::ClientConnection::ClientConnection(SSL* connection, string& systemID) :
+ Connection(connection, systemID)
+{
+}
+
+IceSecurity::Ssl::OpenSSL::ClientConnection::~ClientConnection()
+{
+ ICE_METHOD_INV("OpenSSL::ClientConnection::~ClientConnection()");
+
+ shutdown();
+
+ ICE_METHOD_RET("OpenSSL::ClientConnection::~ClientConnection()");
+}
+
+void
+IceSecurity::Ssl::OpenSSL::ClientConnection::shutdown()
+{
+ ICE_METHOD_INV("OpenSSL::ClientConnection::shutdown()");
+
+ if (_sslConnection != 0)
+ {
+ int shutdown = 0;
+ int retries = 100;
+
+ do
+ {
+ shutdown = SSL_shutdown(_sslConnection);
+ retries--;
+ }
+ while ((shutdown == 0) && (retries > 0));
+
+ if (shutdown <= 0)
+ {
+ ostringstream s;
+ s << "SSL shutdown failure encountered: code[" << shutdown << "] retries[";
+ s << retries << "]\n" << fdToString(SSL_get_fd(_sslConnection));
+ ICE_PROTOCOL_DEBUG(s.str());
+ }
+ }
+
+ Connection::shutdown();
+
+ ICE_METHOD_RET("OpenSSL::ClientConnection::shutdown()");
+}
+
+int
+IceSecurity::Ssl::OpenSSL::ClientConnection::init(int timeout)
+{
+ JTCSyncT<JTCMutex> sync(_initMutex);
+
+ int retCode = 0;
+
+ ICE_METHOD_INV("OpenSSL::ClientConnection::init()");
+
+ if (!SSL_is_init_finished(_sslConnection))
+ {
+ int i = 0;
+
+ if (initWantRead)
+ {
+ i = readSelect(timeout);
+ }
+ else if (initWantWrite)
+ {
+ i = writeSelect(timeout);
+ }
+
+ if (initWantRead && i == 0)
+ {
+ return 0;
+ }
+
+ if (initWantWrite && i == 0)
+ {
+ return 0;
+ }
+
+ initWantRead = 0;
+ initWantWrite = 0;
+
+ int result = connect();
+
+ // Find out what the error was (if any).
+ int code = getLastError();
+
+ printGetError(code);
+
+ switch (code)
+ {
+ case SSL_ERROR_WANT_READ:
+ {
+ initWantRead = 1;
+ break;
+ }
+
+ case SSL_ERROR_WANT_WRITE:
+ {
+ initWantWrite = 1;
+ break;
+ }
+
+
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ {
+ // Retry connect.
+ break;
+ }
+
+ case SSL_ERROR_SYSCALL:
+ {
+ // This is a SOCKET_ERROR, but we don't use
+ // this define here as OpenSSL doesn't refer
+ // to it as a SOCKET_ERROR (but that's what it is
+ // if you look at their code).
+ if(result == -1)
+ {
+ // IO Error in underlying BIO
+
+ if (interrupted())
+ {
+ break;
+ }
+
+ if (wouldBlock())
+ {
+ readSelect(timeout);
+ break;
+ }
+
+ if (connectionLost())
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+ else // result == 0
+ {
+ // Protocol Error: Unexpected EOF
+ string errorString = "Encountered an EOF during handshake that violates the SSL Protocol.\n";
+
+ ICE_SSLERRORS(errorString);
+ ICE_EXCEPTION(errorString);
+
+ throw ProtocolException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+
+ case SSL_ERROR_SSL:
+ {
+ string errorString = "Encountered a violation the SSL Protocol during handshake.\n";
+
+ ICE_SSLERRORS(errorString);
+ ICE_EXCEPTION(errorString);
+
+ throw ProtocolException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+
+ retCode = SSL_is_init_finished(_sslConnection);
+
+ if (retCode > 0)
+ {
+ // Init finished, look at the connection information.
+ showConnectionInfo();
+ }
+ }
+ else
+ {
+ retCode = 1;
+ }
+
+ ICE_METHOD_RET("OpenSSL::ClientConnection::init()");
+
+ return retCode;
+}
+
+int
+IceSecurity::Ssl::OpenSSL::ClientConnection::read(Buffer& buf, int timeout)
+{
+ ICE_METHOD_INV("OpenSSL::ClientConnection::read(Buffer&,int)");
+
+ int totalBytesRead = 0;
+
+ // Initialization to 1 is a cheap trick to ensure we enter the loop.
+ int bytesRead = 1;
+
+ // We keep reading until we're done.
+ while ((buf.i != buf.b.end()) && bytesRead)
+ {
+ // Copy over bytes from _inBuffer to buf.
+ bytesRead = readInBuffer(buf);
+
+ // Nothing in the _inBuffer?
+ if (!bytesRead)
+ {
+ // Read from SSL.
+ bytesRead = readSSL(buf, timeout);
+ }
+
+ // Keep track of the total number of bytes read.
+ totalBytesRead += bytesRead;
+ }
+
+ ICE_METHOD_RET("OpenSSL::ClientConnection::read(Buffer&,int)");
+
+ return totalBytesRead;
+}
+
+int
+IceSecurity::Ssl::OpenSSL::ClientConnection::write(Buffer& buf, int timeout)
+{
+ ICE_METHOD_INV("OpenSSL::ClientConnection::write(Buffer&,int)");
+
+ int totalBytesWritten = 0;
+ int bytesWritten = 0;
+
+ int packetSize = buf.b.end() - buf.i;
+
+#ifdef WIN32
+ //
+ // Limit packet size to avoid performance problems on WIN32.
+ // (blatantly ripped off from Marc Laukien)
+ //
+ if (packetSize > 64 * 1024)
+ {
+ packetSize = 64 * 1024;
+ }
+#endif
+
+ // We keep reading until we're done
+ while (buf.i != buf.b.end())
+ {
+ // Ensure we're initialized.
+ if (init(timeout))
+ {
+ // Perform a select on the socket.
+ if (!writeSelect(timeout))
+ {
+ // We're done here.
+ break;
+ }
+
+ bytesWritten = sslWrite((char *)buf.i, packetSize);
+
+ switch (getLastError())
+ {
+ case SSL_ERROR_NONE:
+ {
+ if (bytesWritten > 0)
+ {
+ ostringstream s;
+
+ s << "sent " << bytesWritten << " of " << packetSize;
+ s << " bytes via SSL\n" << fdToString(SSL_get_fd(_sslConnection));
+
+ ICE_PROTOCOL(s.str());
+
+ totalBytesWritten += bytesWritten;
+
+ buf.i += bytesWritten;
+
+ if (packetSize > buf.b.end() - buf.i)
+ {
+ packetSize = buf.b.end() - buf.i;
+ }
+ }
+ else
+ {
+ // TODO: The client application performs a cleanup at this point,
+ // not even shutting down SSL - it just frees the SSL
+ // structure. I'm ignoring this, at the moment, as I'm sure
+ // the demo is handling it in an artificial manner.
+
+ ICE_PROTOCOL("Error SSL_ERROR_NONE: Repeating as per protocol.");
+ }
+ continue;
+ }
+
+ case SSL_ERROR_WANT_WRITE:
+ {
+ // Repeat with the same arguments! (as in the OpenSSL documentation)
+ // Whatever happened, the last write didn't actually write anything
+ // for us. This is effectively a retry.
+
+ ICE_PROTOCOL("Error SSL_ERROR_WANT_WRITE: Repeating as per protocol.");
+
+ continue;
+ }
+
+ case SSL_ERROR_WANT_READ:
+ {
+ // If we get this error here, it HAS to be because
+ // the protocol wants to do something handshake related.
+ // In the case that we might actually get some application data,
+ // we will use the base SSL read method, using the _inBuffer.
+
+ ICE_PROTOCOL("Error SSL_ERROR_WANT_READ.");
+
+ readSSL(_inBuffer, timeout);
+
+ continue;
+ }
+
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ {
+ // Perform another read. The read should take care of this.
+
+ ICE_PROTOCOL("Error SSL_ERROR_WANT_X509_LOOKUP: Repeating as per protocol.");
+
+ continue;
+ }
+
+ case SSL_ERROR_SYSCALL:
+ {
+ // NOTE: The demo client only throws an exception if there were actually bytes
+ // written. This is considered to be an error status requiring shutdown.
+ // If nothing was written, the demo client stops writing - we continue.
+ // This is potentially something wierd to watch out for.
+ if (bytesWritten == -1)
+ {
+ // IO Error in underlying BIO
+
+ if (interrupted())
+ {
+ break;
+ }
+
+ if (wouldBlock())
+ {
+ break;
+ }
+
+ if (connectionLost())
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+ else if (bytesWritten > 0)
+ {
+ // Protocol Error: Unexpected EOF
+ string errorString = "Encountered an EOF that violates the SSL Protocol.\n";
+
+ ICE_SSLERRORS(errorString);
+ ICE_EXCEPTION(errorString);
+
+ throw ProtocolException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ else // bytesWritten == 0
+ {
+ // Didn't write anything, continue, should be fine.
+
+ ICE_PROTOCOL("Error SSL_ERROR_SYSCALL: Repeating as per protocol.");
+
+ break;
+ }
+ }
+
+ case SSL_ERROR_SSL:
+ {
+ string errorString = "Encountered a violation the SSL Protocol.\n";
+
+ ICE_SSLERRORS(errorString);
+ ICE_EXCEPTION(errorString);
+
+ throw ProtocolException(errorString.c_str(), __FILE__, __LINE__);
+ }
+
+ case SSL_ERROR_ZERO_RETURN:
+ {
+ ICE_EXCEPTION("SSL_ERROR_ZERO_RETURN");
+
+ if (connectionLost())
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+ }
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::ClientConnection::write(Buffer&,int)");
+
+ return totalBytesWritten;
+}
+
+//
+// Protected Methods
+//
+
+// This code blatantly stolen from OpenSSL demos, slightly repackaged, and completely ugly...
+void
+IceSecurity::Ssl::OpenSSL::ClientConnection::showConnectionInfo()
+{
+ ICE_METHOD_INV("OpenSSL::ClientConnection::showConnectionInfo()");
+
+ // Only in extreme cases do we enable this, partially because it doesn't use the Logger.
+ if (ICE_SECURITY_LEVEL_PROTOCOL_DEBUG)
+ {
+ ICE_PROTOCOL_DEBUG("Begin Connection Information");
+
+ BIO* bio = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+ showCertificateChain(bio);
+
+ showPeerCertificate(bio,"Client");
+
+ // Something extra for the client
+ showClientCAList(bio, "Client");
+
+ showSharedCiphers(bio);
+
+ showSelectedCipherInfo(bio);
+
+ showHandshakeStats(bio);
+
+ showSessionInfo(bio);
+
+ ICE_PROTOCOL_DEBUG("End of Connection Information");
+
+ if (bio != 0)
+ {
+ BIO_free(bio);
+ bio = 0;
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::ClientConnection::showConnectionInfo()");
+}
diff --git a/cpp/src/Ice/SslConnectionOpenSSLClient.h b/cpp/src/Ice/SslConnectionOpenSSLClient.h index 48e9b2725e6..cf2d36ee36c 100644 --- a/cpp/src/Ice/SslConnectionOpenSSLClient.h +++ b/cpp/src/Ice/SslConnectionOpenSSLClient.h @@ -1,52 +1,52 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_SSL_CONNECTION_OPENSSL_CLIENT_H -#define ICE_SSL_CONNECTION_OPENSSL_CLIENT_H - -#include <openssl/ssl.h> -#include <Ice/Buffer.h> -#include <Ice/SslConnectionOpenSSL.h> - -namespace IceSecurity -{ - -namespace Ssl -{ - -namespace OpenSSL -{ - -using namespace Ice; - -class ClientConnection : public Connection -{ - -public: - ClientConnection(SSL*, string&); - virtual ~ClientConnection(); - virtual void shutdown(); - virtual int init(int timeout = 0); - - virtual int read(Buffer&, int); - virtual int write(Buffer&, int); - -protected: - - virtual void showConnectionInfo(); -}; - -} - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_CONNECTION_OPENSSL_CLIENT_H
+#define ICE_SSL_CONNECTION_OPENSSL_CLIENT_H
+
+#include <openssl/ssl.h>
+#include <Ice/Buffer.h>
+#include <Ice/SslConnectionOpenSSL.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+namespace OpenSSL
+{
+
+using namespace Ice;
+
+class ClientConnection : public Connection
+{
+
+public:
+ ClientConnection(SSL*, string&);
+ virtual ~ClientConnection();
+ virtual void shutdown();
+ virtual int init(int timeout = 0);
+
+ virtual int read(Buffer&, int);
+ virtual int write(Buffer&, int);
+
+protected:
+
+ virtual void showConnectionInfo();
+};
+
+}
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslConnectionOpenSSLServer.cpp b/cpp/src/Ice/SslConnectionOpenSSLServer.cpp index 0306d5780ab..b39aa0952a6 100644 --- a/cpp/src/Ice/SslConnectionOpenSSLServer.cpp +++ b/cpp/src/Ice/SslConnectionOpenSSLServer.cpp @@ -1,429 +1,463 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include <string> -#include <sstream> -#include <Ice/Network.h> -#include <Ice/Security.h> -#include <Ice/SslException.h> -#include <Ice/SslConnectionOpenSSLServer.h> - -using IceSecurity::Ssl::ReInitException; -using IceSecurity::Ssl::ShutdownException; -using IceSecurity::Ssl::InitException; -using namespace IceInternal; -using namespace std; - -////////////////////////////////////// -////////// ServerConnection ////////// -////////////////////////////////////// - -// -// Public Methods -// - -IceSecurity::Ssl::OpenSSL::ServerConnection::ServerConnection(SSL* connection, string& systemID) : - Connection(connection, systemID) -{ -} - -IceSecurity::Ssl::OpenSSL::ServerConnection::~ServerConnection() -{ - METHOD_INV("OpenSSL::ServerConnection::~ServerConnection()"); - - shutdown(); - - METHOD_RET("OpenSSL::ServerConnection::~ServerConnection()"); -} - -void -IceSecurity::Ssl::OpenSSL::ServerConnection::shutdown() -{ - METHOD_INV("OpenSSL::ServerConnection::shutdown()"); - - if (_sslConnection != 0) - { - // NOTE: This call is how the server application shuts down, but they are - // also using SSL_CTX_set_quiet_shutdown(). - // SSL_set_shutdown(_sslConnection,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); - - int shutdown = 0; - int retries = 100; - - do - { - shutdown = SSL_shutdown(_sslConnection); - retries--; - } - while ((shutdown == 0) && (retries > 0)); - - if (shutdown <= 0) - { - ostringstream s; - s << "SSL shutdown failure encountered: code[" << shutdown << "] retries["; - s << retries << "]\n" << fdToString(SSL_get_fd(_sslConnection)); - PROTOCOL_DEBUG(s.str()); - } - } - - Connection::shutdown(); - - METHOD_RET("OpenSSL::ServerConnection::shutdown()"); -} - -int -IceSecurity::Ssl::OpenSSL::ServerConnection::init(int timeout) -{ - JTCSyncT<JTCMutex> sync(_initMutex); - - int retCode = 0; - - METHOD_INV("OpenSSL::ServerConnection::init()"); - - if (!SSL_is_init_finished(_sslConnection)) - { - int i = 0; - - if (initWantRead) - { - i = readSelect(timeout); - } - else if (initWantWrite) - { - i = writeSelect(timeout); - } - - if (initWantRead && i == 0) - { - return 0; - } - - if (initWantWrite && i == 0) - { - return 0; - } - - initWantRead = 0; - initWantWrite = 0; - - int result = accept(); - - // Find out what the error was (if any). - int code = getLastError(); - - // We're doing an Accept and we don't get a retry on the socket. - if ((result <= 0) && (BIO_sock_should_retry(result) == 0)) - { - // Socket can't retry - bad scene, find out why. - long verify_error = SSL_get_verify_result(_sslConnection); - - if (verify_error != X509_V_OK) - { - // SSL Protocol Error - Shutdown the Connection. - string errorString = "SSL certificate verification error."; - - EXCEPTION(errorString); - - throw ShutdownException(errorString.c_str(), __FILE__, __LINE__); - } - else - { - // SSL Protocol Error - Shutdown the Connection. - string errorString = "SSL Protocol Error."; - - EXCEPTION(errorString); - - throw ShutdownException(errorString.c_str(), __FILE__, __LINE__); - } - } - - switch (code) - { - case SSL_ERROR_WANT_READ: - { - initWantRead = 1; - break; - } - - case SSL_ERROR_WANT_WRITE: - { - initWantWrite = 1; - break; - } - - - case SSL_ERROR_NONE: - case SSL_ERROR_WANT_X509_LOOKUP: - { - // Do nothing, life is good! - break; - } - - case SSL_ERROR_SYSCALL: - { - // This is a SOCKET_ERROR, but we don't use - // this define here as OpenSSL doesn't refer - // to it as a SOCKET_ERROR (but that's what it is - // if you look at their code). - if(result == -1) - { - if (interrupted()) - { - break; - } - - if (wouldBlock()) - { - readSelect(timeout); - break; - } - - if (connectionLost()) - { - ConnectionLostException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - else - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - } - else - { - string errorString = "SSL_ERROR_SYSCALL: During init()."; - - EXCEPTION(errorString); - - throw InitException(errorString.c_str(), __FILE__, __LINE__); - } - } - - case SSL_ERROR_SSL: - { - string errorString = "SSL_ERROR_SSL: During init()."; - - EXCEPTION(errorString); - - throw InitException(errorString.c_str(), __FILE__, __LINE__); - } - } - - retCode = SSL_is_init_finished(_sslConnection); - - if (retCode > 0) - { - // Init finished, look at the connection information. - showConnectionInfo(); - } - } - else - { - retCode = 1; - } - - METHOD_RET("OpenSSL::ServerConnection::init()"); - - return retCode; -} - -int -IceSecurity::Ssl::OpenSSL::ServerConnection::read(Buffer& buf, int timeout) -{ - METHOD_INV("OpenSSL::ServerConnection::read(Buffer&, int)"); - - int bytesRead = 1; - int totalBytesRead = 0; - - // We keep reading until we're done. - while ((buf.i != buf.b.end()) && bytesRead) - { - // Copy over bytes from _inBuffer to buf. - bytesRead = readInBuffer(buf); - - // Nothing in the _inBuffer? - if (!bytesRead) - { - // Read from SSL. - bytesRead = readSSL(buf, timeout); - } - - // Keep track of the total bytes read. - totalBytesRead += bytesRead; - } - - METHOD_RET("OpenSSL::ServerConnection::read(Buffer&, int)"); - - return totalBytesRead; -} - -int -IceSecurity::Ssl::OpenSSL::ServerConnection::write(Buffer& buf, int timeout) -{ - METHOD_INV("OpenSSL::ServerConnection::write(Buffer&, int)"); - - int totalBytesWritten = 0; - int bytesWritten = 0; - - int packetSize = buf.b.end() - buf.i; - -#ifdef WIN32 - // - // Limit packet size to avoid performance problems on WIN32. - // - if (packetSize > 64 * 1024) - { - packetSize = 64 * 1024; - } -#endif - - // We keep writing until we're done. - while (buf.i != buf.b.end()) - { - // Ensure we're initialized. - if (init(timeout)) - { - // Perform a select on the socket. - if (!writeSelect(timeout)) - { - // We're done here. - break; - } - - bytesWritten = sslWrite((char *)buf.i, packetSize); - - switch (getLastError()) - { - case SSL_ERROR_NONE: - { - ostringstream s; - - s << "sent " << bytesWritten << " of " << packetSize; - s << " bytes via SSL\n" << fdToString(SSL_get_fd(_sslConnection)); - - PROTOCOL(s.str()); - - totalBytesWritten += bytesWritten; - - buf.i += bytesWritten; - - if (packetSize > buf.b.end() - buf.i) - { - packetSize = buf.b.end() - buf.i; - } - continue; - } - - case SSL_ERROR_WANT_WRITE: // Retry... - { - PROTOCOL("Error SSL_ERROR_WANT_WRITE: Repeating as per protocol."); - - continue; - } - - case SSL_ERROR_WANT_READ: // The demo server ignores this error. - { - PROTOCOL("Error SSL_ERROR_WANT_READ: Ignoring as per protocol."); - - continue; - } - - case SSL_ERROR_WANT_X509_LOOKUP: // The demo server ignores this error. - { - PROTOCOL("Error SSL_ERROR_WANT_X509_LOOKUP: Repeating as per protocol."); - - continue; - } - - case SSL_ERROR_SYSCALL: - { - if (bytesWritten == -1) - { - SocketException ex(__FILE__, __LINE__); - ex.error = getSocketErrno(); - throw ex; - } - else - { - string errorString = "SSL_ERROR_SYSCALL"; - - EXCEPTION(errorString); - - throw ShutdownException(errorString.c_str(), __FILE__, __LINE__); - } - } - - case SSL_ERROR_SSL: - { - string errorString = "SSL_ERROR_SSL"; - - EXCEPTION(errorString); - - throw ShutdownException(errorString.c_str(), __FILE__, __LINE__); - } - - case SSL_ERROR_ZERO_RETURN: - { - string errorString = "SSL_ERROR_ZERO_RETURN"; - - EXCEPTION(errorString); - - throw ShutdownException(errorString.c_str(), __FILE__, __LINE__); - } - } - } - } - - METHOD_RET("OpenSSL::ServerConnection::write(Buffer&, int)"); - - return totalBytesWritten; -} - -// -// Protected Methods -// - -void -IceSecurity::Ssl::OpenSSL::ServerConnection::showConnectionInfo() -{ - METHOD_INV("OpenSSL::ServerConnection::showConnectionInfo()"); - - // Only in extreme cases do we enable this, partially because it doesn't use the Logger. - if (_traceLevels->security >= SECURITY_PROTOCOL_DEBUG) - { - PROTOCOL_DEBUG("Begin Connection Information"); - - BIO* bio = BIO_new_fp(stdout, BIO_NOCLOSE); - - showCertificateChain(bio); - - showPeerCertificate(bio,"Server"); - - showSharedCiphers(bio); - - showSelectedCipherInfo(bio); - - showHandshakeStats(bio); - - showSessionInfo(bio); - - PROTOCOL_DEBUG("End of Connection Information"); - - if (bio != 0) - { - BIO_free(bio); - bio = 0; - } - } - - METHOD_RET("OpenSSL::ServerConnection::showConnectionInfo()"); -} +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <string>
+#include <sstream>
+#include <Ice/Network.h>
+#include <Ice/Security.h>
+#include <Ice/SslException.h>
+#include <Ice/SslConnectionOpenSSLServer.h>
+
+using IceSecurity::Ssl::CertificateException;
+using IceSecurity::Ssl::ProtocolException;
+using namespace IceInternal;
+using namespace std;
+
+//////////////////////////////////////
+////////// ServerConnection //////////
+//////////////////////////////////////
+
+//
+// Public Methods
+//
+
+IceSecurity::Ssl::OpenSSL::ServerConnection::ServerConnection(SSL* connection, string& systemID) :
+ Connection(connection, systemID)
+{
+}
+
+IceSecurity::Ssl::OpenSSL::ServerConnection::~ServerConnection()
+{
+ ICE_METHOD_INV("OpenSSL::ServerConnection::~ServerConnection()");
+
+ shutdown();
+
+ ICE_METHOD_RET("OpenSSL::ServerConnection::~ServerConnection()");
+}
+
+void
+IceSecurity::Ssl::OpenSSL::ServerConnection::shutdown()
+{
+ ICE_METHOD_INV("OpenSSL::ServerConnection::shutdown()");
+
+ if (_sslConnection != 0)
+ {
+ // NOTE: This call is how the server application shuts down, but they are
+ // also using SSL_CTX_set_quiet_shutdown().
+ // SSL_set_shutdown(_sslConnection,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+
+ int shutdown = 0;
+ int retries = 100;
+
+ do
+ {
+ shutdown = SSL_shutdown(_sslConnection);
+ retries--;
+ }
+ while ((shutdown == 0) && (retries > 0));
+
+ if (shutdown <= 0)
+ {
+ ostringstream s;
+ s << "SSL shutdown failure encountered: code[" << shutdown << "] retries[";
+ s << retries << "]\n" << fdToString(SSL_get_fd(_sslConnection));
+ ICE_PROTOCOL_DEBUG(s.str());
+ }
+ }
+
+ Connection::shutdown();
+
+ ICE_METHOD_RET("OpenSSL::ServerConnection::shutdown()");
+}
+
+int
+IceSecurity::Ssl::OpenSSL::ServerConnection::init(int timeout)
+{
+ JTCSyncT<JTCMutex> sync(_initMutex);
+
+ int retCode = 0;
+
+ ICE_METHOD_INV("OpenSSL::ServerConnection::init()");
+
+ if (!SSL_is_init_finished(_sslConnection))
+ {
+ int i = 0;
+
+ if (initWantRead)
+ {
+ i = readSelect(timeout);
+ }
+ else if (initWantWrite)
+ {
+ i = writeSelect(timeout);
+ }
+
+ if (initWantRead && i == 0)
+ {
+ return 0;
+ }
+
+ if (initWantWrite && i == 0)
+ {
+ return 0;
+ }
+
+ initWantRead = 0;
+ initWantWrite = 0;
+
+ int result = accept();
+
+ // Find out what the error was (if any).
+ int code = getLastError();
+
+ // We're doing an Accept and we don't get a retry on the socket.
+ if ((result <= 0) && (BIO_sock_should_retry(result) == 0))
+ {
+ // Socket can't retry - bad scene, find out why.
+ long verify_error = SSL_get_verify_result(_sslConnection);
+
+ if (verify_error != X509_V_OK)
+ {
+ string errorString = "SSL certificate verification error.";
+
+ ICE_EXCEPTION(errorString);
+
+ throw CertificateException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ else
+ {
+ string errorString = "Encountered an SSL Protocol violation during handshake.";
+
+ ICE_SSLERRORS(errorString);
+ ICE_EXCEPTION(errorString);
+
+ throw ProtocolException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+
+ switch (code)
+ {
+ case SSL_ERROR_WANT_READ:
+ {
+ initWantRead = 1;
+ break;
+ }
+
+ case SSL_ERROR_WANT_WRITE:
+ {
+ initWantWrite = 1;
+ break;
+ }
+
+
+ case SSL_ERROR_NONE:
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ {
+ // Do nothing, life is good!
+ break;
+ }
+
+ case SSL_ERROR_SYSCALL:
+ {
+ // This is a SOCKET_ERROR, but we don't use
+ // this define here as OpenSSL doesn't refer
+ // to it as a SOCKET_ERROR (but that's what it is
+ // if you look at their code).
+ if(result == -1)
+ {
+ if (interrupted())
+ {
+ break;
+ }
+
+ if (wouldBlock())
+ {
+ readSelect(timeout);
+ break;
+ }
+
+ if (connectionLost())
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+ else
+ {
+ // Protocol Error: Unexpected EOF
+ string errorString = "Encountered an EOF during handshake that violates the SSL Protocol.\n";
+
+ ICE_SSLERRORS(errorString);
+ ICE_EXCEPTION(errorString);
+
+ throw ProtocolException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+
+ case SSL_ERROR_SSL:
+ {
+ string errorString = "Encountered a violation the SSL Protocol during handshake.\n";
+
+ ICE_SSLERRORS(errorString);
+ ICE_EXCEPTION(errorString);
+
+ throw ProtocolException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+
+ retCode = SSL_is_init_finished(_sslConnection);
+
+ if (retCode > 0)
+ {
+ // Init finished, look at the connection information.
+ showConnectionInfo();
+ }
+ }
+ else
+ {
+ retCode = 1;
+ }
+
+ ICE_METHOD_RET("OpenSSL::ServerConnection::init()");
+
+ return retCode;
+}
+
+int
+IceSecurity::Ssl::OpenSSL::ServerConnection::read(Buffer& buf, int timeout)
+{
+ ICE_METHOD_INV("OpenSSL::ServerConnection::read(Buffer&, int)");
+
+ int bytesRead = 1;
+ int totalBytesRead = 0;
+
+ // We keep reading until we're done.
+ while ((buf.i != buf.b.end()) && bytesRead)
+ {
+ // Copy over bytes from _inBuffer to buf.
+ bytesRead = readInBuffer(buf);
+
+ // Nothing in the _inBuffer?
+ if (!bytesRead)
+ {
+ // Read from SSL.
+ bytesRead = readSSL(buf, timeout);
+ }
+
+ // Keep track of the total bytes read.
+ totalBytesRead += bytesRead;
+ }
+
+ ICE_METHOD_RET("OpenSSL::ServerConnection::read(Buffer&, int)");
+
+ return totalBytesRead;
+}
+
+int
+IceSecurity::Ssl::OpenSSL::ServerConnection::write(Buffer& buf, int timeout)
+{
+ ICE_METHOD_INV("OpenSSL::ServerConnection::write(Buffer&, int)");
+
+ int totalBytesWritten = 0;
+ int bytesWritten = 0;
+
+ int packetSize = buf.b.end() - buf.i;
+
+#ifdef WIN32
+ //
+ // Limit packet size to avoid performance problems on WIN32.
+ //
+ if (packetSize > 64 * 1024)
+ {
+ packetSize = 64 * 1024;
+ }
+#endif
+
+ // We keep writing until we're done.
+ while (buf.i != buf.b.end())
+ {
+ // Ensure we're initialized.
+ if (init(timeout))
+ {
+ // Perform a select on the socket.
+ if (!writeSelect(timeout))
+ {
+ // We're done here.
+ break;
+ }
+
+ bytesWritten = sslWrite((char *)buf.i, packetSize);
+
+ switch (getLastError())
+ {
+ case SSL_ERROR_NONE:
+ {
+ ostringstream s;
+
+ s << "sent " << bytesWritten << " of " << packetSize;
+ s << " bytes via SSL\n" << fdToString(SSL_get_fd(_sslConnection));
+
+ ICE_PROTOCOL(s.str());
+
+ totalBytesWritten += bytesWritten;
+
+ buf.i += bytesWritten;
+
+ if (packetSize > buf.b.end() - buf.i)
+ {
+ packetSize = buf.b.end() - buf.i;
+ }
+ continue;
+ }
+
+ case SSL_ERROR_WANT_WRITE: // Retry...
+ {
+ ICE_PROTOCOL("Error SSL_ERROR_WANT_WRITE: Repeating as per protocol.");
+
+ continue;
+ }
+
+ case SSL_ERROR_WANT_READ: // The demo server ignores this error.
+ {
+ ICE_PROTOCOL("Error SSL_ERROR_WANT_READ: Ignoring as per protocol.");
+
+ continue;
+ }
+
+ case SSL_ERROR_WANT_X509_LOOKUP: // The demo server ignores this error.
+ {
+ ICE_PROTOCOL("Error SSL_ERROR_WANT_X509_LOOKUP: Repeating as per protocol.");
+
+ continue;
+ }
+
+ case SSL_ERROR_SYSCALL:
+ {
+ if (bytesWritten == -1)
+ {
+ // IO Error in underlying BIO
+
+ if (interrupted())
+ {
+ break;
+ }
+
+ if (wouldBlock())
+ {
+ break;
+ }
+
+ if (connectionLost())
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+ else
+ {
+ // Protocol Error: Unexpected EOF
+ string errorString = "Encountered an EOF that violates the SSL Protocol.\n";
+
+ ICE_SSLERRORS(errorString);
+ ICE_EXCEPTION(errorString);
+
+ throw ProtocolException(errorString.c_str(), __FILE__, __LINE__);
+ }
+ }
+
+ case SSL_ERROR_SSL:
+ {
+ string errorString = "Encountered a violation the SSL Protocol.\n";
+
+ ICE_SSLERRORS(errorString);
+ ICE_EXCEPTION(errorString);
+
+ throw ProtocolException(errorString.c_str(), __FILE__, __LINE__);
+ }
+
+ case SSL_ERROR_ZERO_RETURN:
+ {
+ ICE_EXCEPTION("SSL_ERROR_ZERO_RETURN");
+
+ if (connectionLost())
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ }
+ }
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::ServerConnection::write(Buffer&, int)");
+
+ return totalBytesWritten;
+}
+
+//
+// Protected Methods
+//
+
+void
+IceSecurity::Ssl::OpenSSL::ServerConnection::showConnectionInfo()
+{
+ ICE_METHOD_INV("OpenSSL::ServerConnection::showConnectionInfo()");
+
+ // Only in extreme cases do we enable this, partially because it doesn't use the Logger.
+ if (ICE_SECURITY_LEVEL_PROTOCOL_DEBUG)
+ {
+ ICE_PROTOCOL_DEBUG("Begin Connection Information");
+
+ BIO* bio = BIO_new_fp(stdout, BIO_NOCLOSE);
+
+ showCertificateChain(bio);
+
+ showPeerCertificate(bio,"Server");
+
+ showSharedCiphers(bio);
+
+ showSelectedCipherInfo(bio);
+
+ showHandshakeStats(bio);
+
+ showSessionInfo(bio);
+
+ ICE_PROTOCOL_DEBUG("End of Connection Information");
+
+ if (bio != 0)
+ {
+ BIO_free(bio);
+ bio = 0;
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::ServerConnection::showConnectionInfo()");
+}
diff --git a/cpp/src/Ice/SslConnectionOpenSSLServer.h b/cpp/src/Ice/SslConnectionOpenSSLServer.h index 4ee9d4ecb95..183b3cb3a90 100644 --- a/cpp/src/Ice/SslConnectionOpenSSLServer.h +++ b/cpp/src/Ice/SslConnectionOpenSSLServer.h @@ -1,52 +1,52 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_SSL_CONNECTION_OPENSSL_SERVER_H -#define ICE_SSL_CONNECTION_OPENSSL_SERVER_H - -#include <openssl/ssl.h> -#include <Ice/Buffer.h> -#include <Ice/SslConnectionOpenSSL.h> - -namespace IceSecurity -{ - -namespace Ssl -{ - -namespace OpenSSL -{ - -using namespace Ice; - -class ServerConnection : public Connection -{ - -public: - ServerConnection(SSL*, string&); - virtual ~ServerConnection(); - virtual void shutdown(); - virtual int init(int timeout = 0); - - virtual int read(Buffer&, int); - virtual int write(Buffer&, int); - -protected: - - virtual void showConnectionInfo(); -}; - -} - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_CONNECTION_OPENSSL_SERVER_H
+#define ICE_SSL_CONNECTION_OPENSSL_SERVER_H
+
+#include <openssl/ssl.h>
+#include <Ice/Buffer.h>
+#include <Ice/SslConnectionOpenSSL.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+namespace OpenSSL
+{
+
+using namespace Ice;
+
+class ServerConnection : public Connection
+{
+
+public:
+ ServerConnection(SSL*, string&);
+ virtual ~ServerConnection();
+ virtual void shutdown();
+ virtual int init(int timeout = 0);
+
+ virtual int read(Buffer&, int);
+ virtual int write(Buffer&, int);
+
+protected:
+
+ virtual void showConnectionInfo();
+};
+
+}
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslConnector.cpp b/cpp/src/Ice/SslConnector.cpp index a3824ecdca2..470aa69abc1 100644 --- a/cpp/src/Ice/SslConnector.cpp +++ b/cpp/src/Ice/SslConnector.cpp @@ -6,35 +6,34 @@ // // All Rights Reserved // -// ********************************************************************** -#ifdef WIN32 -#pragma warning(disable:4786) -#endif +// **********************************************************************
+#ifdef WIN32
+#pragma warning(disable:4786)
+#endif
-#include <Ice/SslFactory.h> -#include <Ice/SslSystem.h> +#include <Ice/SslFactory.h>
+#include <Ice/SslSystem.h>
#include <Ice/SslConnector.h> #include <Ice/SslTransceiver.h> #include <Ice/Instance.h> #include <Ice/TraceLevels.h> #include <Ice/Logger.h> #include <Ice/Network.h> -#include <Ice/Properties.h> +#include <Ice/Properties.h>
#include <Ice/Exception.h> -#include <Ice/SslException.h> -#include <sstream> +#include <Ice/SslException.h>
+#include <sstream>
using namespace std; using namespace Ice; using namespace IceInternal; -using std::ostringstream; -using std::string; -using IceSecurity::Ssl::Connection; -using IceSecurity::Ssl::Factory; -using IceSecurity::Ssl::System; -using IceSecurity::Ssl::ShutdownException; - +using std::ostringstream;
+using std::string;
+using IceSecurity::Ssl::Connection;
+using IceSecurity::Ssl::Factory;
+using IceSecurity::Ssl::System;
+
TransceiverPtr IceInternal::SslConnector::connect(int timeout) { @@ -55,50 +54,57 @@ IceInternal::SslConnector::connect(int timeout) _logger->trace(_traceLevels->networkCat, s.str()); } - // This is the Ice SSL Configuration File on which we will base - // all connections in this communicator. - string configFile = _instance->properties()->getProperty("Ice.Ssl.Config"); - - // Get an instance of the SslOpenSSL singleton. - System* sslSystem = Factory::getSystem(configFile); - - if (!sslSystem->isTraceSet()) - { - sslSystem->setTrace(_traceLevels); - } - - if (!sslSystem->isLoggerSet()) - { - sslSystem->setLogger(_logger); - } - - // Initialize the server (if needed) - if (!sslSystem->isConfigLoaded()) - { - sslSystem->loadConfig(); - } - - Connection* sslConnection = 0; - - try - { - sslConnection = sslSystem->createClientConnection(fd); - } - catch (...) - { - Factory::releaseSystem(sslSystem); - sslSystem = 0; - - // Shutdown the connection. - throw; - } - - TransceiverPtr transPtr = new SslTransceiver(_instance, fd, sslConnection); - - Factory::releaseSystem(sslSystem); - sslSystem = 0; - - return transPtr; + PropertiesPtr properties = _instance->properties();
+
+ // This is the Ice SSL Configuration File on which we will base
+ // all connections in this communicator.
+ string configFile = properties->getProperty("Ice.Ssl.Config");
+
+ // Get an instance of the SslOpenSSL singleton.
+ System* sslSystem = Factory::getSystem(configFile);
+
+ if (!sslSystem->isTraceSet())
+ {
+ sslSystem->setTrace(_traceLevels);
+ }
+
+ if (!sslSystem->isLoggerSet())
+ {
+ sslSystem->setLogger(_logger);
+ }
+
+ if (!sslSystem->isPropertiesSet())
+ {
+ sslSystem->setProperties(properties);
+ }
+
+ // Initialize the server (if needed)
+ if (!sslSystem->isConfigLoaded())
+ {
+ sslSystem->loadConfig();
+ }
+ + Connection* sslConnection = 0;
+
+ try
+ {
+ sslConnection = sslSystem->createClientConnection(fd);
+ }
+ catch (...)
+ {
+ Factory::releaseSystem(sslSystem);
+ sslSystem = 0;
+
+ // Shutdown the connection.
+ throw;
+ }
+
+ TransceiverPtr transPtr = new SslTransceiver(_instance, fd, sslConnection);
+
+ Factory::releaseSystem(sslSystem);
+ sslSystem = 0;
+ + return transPtr;
} string diff --git a/cpp/src/Ice/SslException.cpp b/cpp/src/Ice/SslException.cpp index 91cea56a22a..9b7c7dfb16f 100644 --- a/cpp/src/Ice/SslException.cpp +++ b/cpp/src/Ice/SslException.cpp @@ -1,291 +1,341 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** -#ifdef WIN32 -#pragma warning(disable:4786) -#endif - -#include <Ice/SslException.h> - -using Ice::SocketException; -using Ice::Exception; - -using std::ostream; -using std::string; - -////////////////////////////////// -////////// SecurityException ///// -////////////////////////////////// - -// -// Public Methods -// - -IceSecurity::SecurityException::SecurityException(const char* errMessage, const char* file, int line) : - LocalException(file, line), - _message(errMessage) -{ -} - -IceSecurity::SecurityException::SecurityException(const SecurityException& ex) : - LocalException(ex) -{ -} - -IceSecurity::SecurityException& -IceSecurity::SecurityException::operator=(const SecurityException& ex) -{ - LocalException::operator=(ex); - return *this; -} - -string -IceSecurity::SecurityException::toString() const -{ - string s = ice_name(); - - if (_message == "") - { - s += ": unspecified exception"; - } - else - { - s += ": "; - s += _message; - } - - return s; -} - -string -IceSecurity::SecurityException::ice_name() const -{ - return "IceSecurity::SecurityException"; -} - -void -IceSecurity::SecurityException::ice_print(ostream& out) const -{ - Exception::ice_print(out); - out << ":\nunknown security exception"; -} - -Ice::Exception* -IceSecurity::SecurityException::ice_clone() const -{ - return new SecurityException(*this); -} - -void -IceSecurity::SecurityException::ice_throw() const -{ - throw *this; -} - -/////////////////////////////////// -////////// InitException ////////// -/////////////////////////////////// - -// -// Public Methods -// - -IceSecurity::Ssl::InitException::InitException(const char* errMessage, const char* file, int line) : - SecurityException(errMessage, file, line) -{ -} - -IceSecurity::Ssl::InitException::InitException(const InitException& ex) : - SecurityException(ex) -{ -} - -IceSecurity::Ssl::InitException& -IceSecurity::Ssl::InitException::operator=(const InitException& ex) -{ - SecurityException::operator=(ex); - return *this; -} - -string -IceSecurity::Ssl::InitException::ice_name() const -{ - return "IceSecurity::InitException"; -} - -void -IceSecurity::Ssl::InitException::ice_print(ostream& out) const -{ - Exception::ice_print(out); - out << ":\nsecurity system initialization exception"; -} - -Ice::Exception* -IceSecurity::Ssl::InitException::ice_clone() const -{ - return new InitException(*this); -} - -void -IceSecurity::Ssl::InitException::ice_throw() const -{ - throw *this; -} - -///////////////////////////////////// -////////// ReInitException ////////// -///////////////////////////////////// - -// -// Public Methods -// - -IceSecurity::Ssl::ReInitException::ReInitException(const char* errMessage, const char* file, int line) : - SecurityException(errMessage, file, line) -{ -} - -IceSecurity::Ssl::ReInitException::ReInitException(const ReInitException& ex) : - SecurityException(ex) -{ -} - -IceSecurity::Ssl::ReInitException& -IceSecurity::Ssl::ReInitException::operator=(const ReInitException& ex) -{ - SecurityException::operator=(ex); - return *this; -} - -string -IceSecurity::Ssl::ReInitException::ice_name() const -{ - return "IceSecurity::ReInitException"; -} - -void -IceSecurity::Ssl::ReInitException::ice_print(ostream& out) const -{ - Exception::ice_print(out); - out << ":\nsecurity system re-initialization exception"; -} - -Ice::Exception* -IceSecurity::Ssl::ReInitException::ice_clone() const -{ - return new ReInitException(*this); -} - -void -IceSecurity::Ssl::ReInitException::ice_throw() const -{ - throw *this; -} - -/////////////////////////////////////// -////////// ShutdownException ////////// -/////////////////////////////////////// - -// -// Public Methods -// - -IceSecurity::Ssl::ShutdownException::ShutdownException(const char* errMessage, const char* file, int line) : - SecurityException(errMessage, file, line) -{ -} - -IceSecurity::Ssl::ShutdownException::ShutdownException(const ShutdownException& ex) : - SecurityException(ex) -{ -} - -IceSecurity::Ssl::ShutdownException& -IceSecurity::Ssl::ShutdownException::operator=(const ShutdownException& ex) -{ - SecurityException::operator=(ex); - return *this; -} - -string -IceSecurity::Ssl::ShutdownException::ice_name() const -{ - return "IceSecurity::ShutdownException"; -} - -void -IceSecurity::Ssl::ShutdownException::ice_print(ostream& out) const -{ - Exception::ice_print(out); - out << ":\nsecurity system shutdown exception"; -} - -Ice::Exception* -IceSecurity::Ssl::ShutdownException::ice_clone() const -{ - return new ShutdownException(*this); -} - -void -IceSecurity::Ssl::ShutdownException::ice_throw() const -{ - throw *this; -} - -////////////////////////////////////// -////////// ContextException ////////// -////////////////////////////////////// - -// -// Public Methods -// - -IceSecurity::Ssl::OpenSSL::ContextException::ContextException(const char* errMessage, const char* file, int line) : - InitException(errMessage, file, line) -{ -} - -IceSecurity::Ssl::OpenSSL::ContextException::ContextException(const ContextException& ex) : - InitException(ex) -{ -} - -IceSecurity::Ssl::OpenSSL::ContextException& -IceSecurity::Ssl::OpenSSL::ContextException::operator=(const ContextException& ex) -{ - InitException::operator=(ex); - return *this; -} - -string -IceSecurity::Ssl::OpenSSL::ContextException::ice_name() const -{ - return "IceSecurity::ContextException"; -} - -void -IceSecurity::Ssl::OpenSSL::ContextException::ice_print(ostream& out) const -{ - Exception::ice_print(out); - out << ":\nSSL System context exception"; -} - -Ice::Exception* -IceSecurity::Ssl::OpenSSL::ContextException::ice_clone() const -{ - return new ContextException(*this); -} - -void -IceSecurity::Ssl::OpenSSL::ContextException::ice_throw() const -{ - throw *this; -} - - +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+#ifdef WIN32
+#pragma warning(disable:4786)
+#endif
+
+#include <Ice/SslException.h>
+
+using Ice::SocketException;
+using Ice::Exception;
+
+using std::ostream;
+using std::string;
+
+//////////////////////////////////
+////////// SecurityException /////
+//////////////////////////////////
+
+//
+// Public Methods
+//
+
+IceSecurity::SecurityException::SecurityException(const char* errMessage, const char* file, int line) :
+ LocalException(file, line),
+ _message(errMessage)
+{
+}
+
+IceSecurity::SecurityException::SecurityException(const SecurityException& ex) :
+ LocalException(ex)
+{
+}
+
+IceSecurity::SecurityException&
+IceSecurity::SecurityException::operator=(const SecurityException& ex)
+{
+ LocalException::operator=(ex);
+ return *this;
+}
+
+string
+IceSecurity::SecurityException::toString() const
+{
+ string s = ice_name();
+
+ if (_message == "")
+ {
+ s += ": unspecified exception";
+ }
+ else
+ {
+ s += ": ";
+ s += _message;
+ }
+
+ return s;
+}
+
+string
+IceSecurity::SecurityException::ice_name() const
+{
+ return "IceSecurity::SecurityException";
+}
+
+void
+IceSecurity::SecurityException::ice_print(ostream& out) const
+{
+ Exception::ice_print(out);
+ out << ":\nunknown security exception";
+}
+
+Ice::Exception*
+IceSecurity::SecurityException::ice_clone() const
+{
+ return new SecurityException(*this);
+}
+
+void
+IceSecurity::SecurityException::ice_throw() const
+{
+ throw *this;
+}
+
+///////////////////////////////////////
+//////// ConfigParseException /////////
+///////////////////////////////////////
+
+//
+// Public Methods
+//
+
+IceSecurity::Ssl::ConfigParseException::ConfigParseException(const char* errMessage, const char* file, int line) :
+ SecurityException(errMessage, file, line)
+{
+}
+
+IceSecurity::Ssl::ConfigParseException::ConfigParseException(const ConfigParseException& ex) :
+ SecurityException(ex)
+{
+}
+
+IceSecurity::Ssl::ConfigParseException&
+IceSecurity::Ssl::ConfigParseException::operator=(const ConfigParseException& ex)
+{
+ SecurityException::operator=(ex);
+ return *this;
+}
+
+string
+IceSecurity::Ssl::ConfigParseException::ice_name() const
+{
+ return "IceSecurity::ConfigParseException";
+}
+
+void
+IceSecurity::Ssl::ConfigParseException::ice_print(ostream& out) const
+{
+ Exception::ice_print(out);
+ out << ":\nsecurity system shutdown exception";
+}
+
+Ice::Exception*
+IceSecurity::Ssl::ConfigParseException::ice_clone() const
+{
+ return new ConfigParseException(*this);
+}
+
+void
+IceSecurity::Ssl::ConfigParseException::ice_throw() const
+{
+ throw *this;
+}
+
+///////////////////////////////////////
+////////// ShutdownException //////////
+///////////////////////////////////////
+
+//
+// Public Methods
+//
+
+IceSecurity::Ssl::ShutdownException::ShutdownException(const char* errMessage, const char* file, int line) :
+ SecurityException(errMessage, file, line)
+{
+}
+
+IceSecurity::Ssl::ShutdownException::ShutdownException(const ShutdownException& ex) :
+ SecurityException(ex)
+{
+}
+
+IceSecurity::Ssl::ShutdownException&
+IceSecurity::Ssl::ShutdownException::operator=(const ShutdownException& ex)
+{
+ SecurityException::operator=(ex);
+ return *this;
+}
+
+string
+IceSecurity::Ssl::ShutdownException::ice_name() const
+{
+ return "IceSecurity::Ssl::ShutdownException";
+}
+
+void
+IceSecurity::Ssl::ShutdownException::ice_print(ostream& out) const
+{
+ Exception::ice_print(out);
+ out << ":\nsecurity system shutdown exception";
+}
+
+Ice::Exception*
+IceSecurity::Ssl::ShutdownException::ice_clone() const
+{
+ return new ShutdownException(*this);
+}
+
+void
+IceSecurity::Ssl::ShutdownException::ice_throw() const
+{
+ throw *this;
+}
+
+/////////////////////////////////////
+///////// ProtocolException /////////
+/////////////////////////////////////
+
+//
+// Public Methods
+//
+
+IceSecurity::Ssl::ProtocolException::ProtocolException(const char* errMessage, const char* file, int line) :
+ ShutdownException(errMessage, file, line)
+{
+}
+
+IceSecurity::Ssl::ProtocolException::ProtocolException(const ProtocolException& ex) :
+ ShutdownException(ex)
+{
+}
+
+IceSecurity::Ssl::ProtocolException&
+IceSecurity::Ssl::ProtocolException::operator=(const ProtocolException& ex)
+{
+ ShutdownException::operator=(ex);
+ return *this;
+}
+
+string
+IceSecurity::Ssl::ProtocolException::ice_name() const
+{
+ return "IceSecurity::Ssl::ProtocolException";
+}
+
+void
+IceSecurity::Ssl::ProtocolException::ice_print(ostream& out) const
+{
+ Exception::ice_print(out);
+ out << ":\nsecurity system re-initialization exception";
+}
+
+Ice::Exception*
+IceSecurity::Ssl::ProtocolException::ice_clone() const
+{
+ return new ProtocolException(*this);
+}
+
+void
+IceSecurity::Ssl::ProtocolException::ice_throw() const
+{
+ throw *this;
+}
+
+///////////////////////////////////
+////// CertificateException ///////
+///////////////////////////////////
+
+//
+// Public Methods
+//
+
+IceSecurity::Ssl::CertificateException::CertificateException(const char* errMessage, const char* file, int line) :
+ ShutdownException(errMessage, file, line)
+{
+}
+
+IceSecurity::Ssl::CertificateException::CertificateException(const CertificateException& ex) :
+ ShutdownException(ex)
+{
+}
+
+IceSecurity::Ssl::CertificateException&
+IceSecurity::Ssl::CertificateException::operator=(const CertificateException& ex)
+{
+ ShutdownException::operator=(ex);
+ return *this;
+}
+
+string
+IceSecurity::Ssl::CertificateException::ice_name() const
+{
+ return "IceSecurity::CertificateException";
+}
+
+void
+IceSecurity::Ssl::CertificateException::ice_print(ostream& out) const
+{
+ Exception::ice_print(out);
+ out << ":\nsecurity system initialization exception";
+}
+
+Ice::Exception*
+IceSecurity::Ssl::CertificateException::ice_clone() const
+{
+ return new CertificateException(*this);
+}
+
+void
+IceSecurity::Ssl::CertificateException::ice_throw() const
+{
+ throw *this;
+}
+
+//////////////////////////////////////
+////////// ContextException //////////
+//////////////////////////////////////
+
+//
+// Public Methods
+//
+
+IceSecurity::Ssl::OpenSSL::ContextException::ContextException(const char* errMessage, const char* file, int line) :
+ SecurityException(errMessage, file, line)
+{
+}
+
+IceSecurity::Ssl::OpenSSL::ContextException::ContextException(const ContextException& ex) :
+ SecurityException(ex)
+{
+}
+
+IceSecurity::Ssl::OpenSSL::ContextException&
+IceSecurity::Ssl::OpenSSL::ContextException::operator=(const ContextException& ex)
+{
+ SecurityException::operator=(ex);
+ return *this;
+}
+
+string
+IceSecurity::Ssl::OpenSSL::ContextException::ice_name() const
+{
+ return "IceSecurity::Ssl::OpenSSL::ContextException";
+}
+
+void
+IceSecurity::Ssl::OpenSSL::ContextException::ice_print(ostream& out) const
+{
+ Exception::ice_print(out);
+ out << ":\nSSL System context exception";
+}
+
+Ice::Exception*
+IceSecurity::Ssl::OpenSSL::ContextException::ice_clone() const
+{
+ return new ContextException(*this);
+}
+
+void
+IceSecurity::Ssl::OpenSSL::ContextException::ice_throw() const
+{
+ throw *this;
+}
+
+
diff --git a/cpp/src/Ice/SslException.h b/cpp/src/Ice/SslException.h index 651a2330605..0a7e4fd6b0c 100644 --- a/cpp/src/Ice/SslException.h +++ b/cpp/src/Ice/SslException.h @@ -1,138 +1,142 @@ -////********************************************************************* -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -////********************************************************************* - -#ifndef ICE_SSL_EXCEPTION_H -#define ICE_SSL_EXCEPTION_H - -#include <Ice/LocalException.h> -#include <string> -#include <ostream> - -namespace IceSecurity -{ - -using std::string; -using std::ostream; -using Ice::Exception; -using Ice::LocalException; - -// SecurityException -// -// This exception serves as the base for all SSL related exceptions. It should probably -// not be constructed directly, but can be used in this manner if desired. -// -class ICE_API SecurityException : public LocalException // public SocketException -{ -public: - - SecurityException(const char*, const char*, int); - SecurityException(const SecurityException&); - SecurityException& operator=(const SecurityException&); - virtual string toString() const; - virtual string ice_name() const; - virtual void ice_print(std::ostream&) const; - virtual Exception* ice_clone() const; - virtual void ice_throw() const; - -private: - - string _message; -}; - -namespace Ssl -{ - -// InitException -// -// This exception indicates a problem during SSL connection setup, most likely due to -// problems with the SSL handshake. This is primarily a client-side exception. -// -class ICE_API InitException : public SecurityException -{ -public: - - InitException(const char*, const char*, int); - InitException(const InitException&); - InitException& operator=(const InitException&); - virtual string ice_name() const; - virtual void ice_print(std::ostream&) const; - virtual Exception* ice_clone() const; - virtual void ice_throw() const; - -}; - -// ReInitException -// -// This exception indicates that the SSL connection should be re-initialized. -// This is primarily a server-side exception. -// -class ICE_API ReInitException : public SecurityException -{ -public: - - ReInitException(const char*, const char*, int); - ReInitException(const ReInitException&); - ReInitException& operator=(const ReInitException&); - virtual string ice_name() const; - virtual void ice_print(std::ostream&) const; - virtual Exception* ice_clone() const; - virtual void ice_throw() const; - -}; - -// ShutdownException -// -// This exception indicates that there has been a fatal SSL connection problem -// that requires the shutdown of the connection and closing of the underlying -// transport. -// -class ICE_API ShutdownException : public SecurityException -{ -public: - - ShutdownException(const char*, const char*, int); - ShutdownException(const ShutdownException&); - ShutdownException& operator=(const ShutdownException&); - virtual string ice_name() const; - virtual void ice_print(std::ostream&) const; - virtual Exception* ice_clone() const; - virtual void ice_throw() const; - -}; - -namespace OpenSSL -{ - -// ContextException -// -// This exception indicates that a problem occurred while setting up the -// SSL context structure (SSL_CTX). -// -class ICE_API ContextException : public InitException -{ -public: - - ContextException(const char*, const char*, int); - ContextException(const ContextException&); - ContextException& operator=(const ContextException&); - virtual string ice_name() const; - virtual void ice_print(std::ostream&) const; - virtual Exception* ice_clone() const; - virtual void ice_throw() const; - -}; - -} - -} - -} - -#endif +////*********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+////*********************************************************************
+
+#ifndef ICE_SSL_EXCEPTION_H
+#define ICE_SSL_EXCEPTION_H
+
+#include <Ice/LocalException.h>
+#include <string>
+#include <ostream>
+
+namespace IceSecurity
+{
+
+using std::string;
+using std::ostream;
+using Ice::Exception;
+using Ice::LocalException;
+
+// SecurityException
+//
+// This exception serves as the base for all SSL related exceptions. It should probably
+// not be constructed directly, but can be used in this manner if desired.
+//
+class ICE_API SecurityException : public LocalException
+{
+public:
+
+ SecurityException(const char*, const char*, int);
+ SecurityException(const SecurityException&);
+ SecurityException& operator=(const SecurityException&);
+ virtual string toString() const;
+ virtual string ice_name() const;
+ virtual void ice_print(std::ostream&) const;
+ virtual Exception* ice_clone() const;
+ virtual void ice_throw() const;
+
+private:
+
+ string _message;
+};
+
+namespace Ssl
+{
+
+class ICE_API ConfigParseException : public SecurityException
+{
+public:
+
+ ConfigParseException(const char*, const char*, int);
+ ConfigParseException(const ConfigParseException&);
+ ConfigParseException& operator=(const ConfigParseException&);
+ virtual string ice_name() const;
+ virtual void ice_print(std::ostream&) const;
+ virtual Exception* ice_clone() const;
+ virtual void ice_throw() const;
+
+};
+
+// ShutdownException
+//
+// This exception indicates that there has been a fatal SSL connection problem
+// that requires the shutdown of the connection and closing of the underlying
+// transport.
+//
+class ICE_API ShutdownException : public SecurityException
+{
+public:
+
+ ShutdownException(const char*, const char*, int);
+ ShutdownException(const ShutdownException&);
+ ShutdownException& operator=(const ShutdownException&);
+ virtual string ice_name() const;
+ virtual void ice_print(std::ostream&) const;
+ virtual Exception* ice_clone() const;
+ virtual void ice_throw() const;
+
+};
+
+class ICE_API ProtocolException : public ShutdownException
+{
+public:
+
+ ProtocolException(const char*, const char*, int);
+ ProtocolException(const ProtocolException&);
+ ProtocolException& operator=(const ProtocolException&);
+ virtual string ice_name() const;
+ virtual void ice_print(std::ostream&) const;
+ virtual Exception* ice_clone() const;
+ virtual void ice_throw() const;
+
+};
+
+class ICE_API CertificateException : public ShutdownException
+{
+public:
+
+ CertificateException(const char*, const char*, int);
+ CertificateException(const CertificateException&);
+ CertificateException& operator=(const CertificateException&);
+ virtual string ice_name() const;
+ virtual void ice_print(std::ostream&) const;
+ virtual Exception* ice_clone() const;
+ virtual void ice_throw() const;
+
+};
+
+namespace OpenSSL
+{
+
+// ContextException
+//
+// This exception indicates that a problem occurred while setting up the
+// SSL context structure (SSL_CTX).
+//
+class ICE_API ContextException : public SecurityException
+{
+public:
+
+ ContextException(const char*, const char*, int);
+ ContextException(const ContextException&);
+ ContextException& operator=(const ContextException&);
+ virtual string ice_name() const;
+ virtual void ice_print(std::ostream&) const;
+ virtual Exception* ice_clone() const;
+ virtual void ice_throw() const;
+
+};
+
+}
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslFactory.cpp b/cpp/src/Ice/SslFactory.cpp index 54e0af0a8fc..d565fee8728 100644 --- a/cpp/src/Ice/SslFactory.cpp +++ b/cpp/src/Ice/SslFactory.cpp @@ -1,119 +1,119 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** -#ifdef WIN32 -#pragma warning(disable:4786) -#endif - -#include <Ice/SslFactory.h> -#include <Ice/SslSystemOpenSSL.h> - -namespace IceSecurity -{ - -namespace Ssl -{ - -// Static member instantiations. -JTCMutex Factory::_systemRepositoryMutex; -SystemMap Factory::_systemRepository; -SslHandleSystemMap Factory::_sslHandleSystemRepository; - -} - -} - -IceSecurity::Ssl::System* -IceSecurity::Ssl::Factory::getSystem(string& systemIdentifier) -{ - JTCSyncT<JTCMutex> sync(_systemRepositoryMutex); - - System* _system = _systemRepository[systemIdentifier]; - - // Don't have that System. - if (_system == 0) - { - // In our case, the systemIdentifier happens to be the - // SSL Configuration file. - - // This line would change based on the flavor of System that we're - // creating for the caller. - _system = new OpenSSL::System(systemIdentifier); - - if (_system != 0) - { - _systemRepository[systemIdentifier] = _system; - } - } - - assert(_system); - - _system->incRef(); - - return _system; -} - -void -IceSecurity::Ssl::Factory::releaseSystem(System* system) -{ - JTCSyncT<JTCMutex> sync(_systemRepositoryMutex); - - assert(system); - - // If the reference count is now at zero. - if (!system->decRef()) - { - _systemRepository.erase(system->getSystemID()); - - delete system; - } -} - -void -IceSecurity::Ssl::Factory::addSystemHandle(void* sslHandle, System* system) -{ - assert(sslHandle); - assert(system); - _sslHandleSystemRepository[sslHandle] = system; -} - -IceSecurity::Ssl::System* -IceSecurity::Ssl::Factory::getSystemFromHandle(void* sslHandle) -{ - JTCSyncT<JTCMutex> sync(_systemRepositoryMutex); - - assert(sslHandle); - - System* _system = _sslHandleSystemRepository[sslHandle]; - - assert(_system); - - _system->incRef(); - - return _system; -} - -void -IceSecurity::Ssl::Factory::releaseSystemFromHandle(void* sslHandle, System* system) -{ - JTCSyncT<JTCMutex> sync(_systemRepositoryMutex); - - assert(sslHandle); - assert(system); - - // If the reference count is now at zero. - if (!system->decRef()) - { - _sslHandleSystemRepository.erase(sslHandle); - _systemRepository.erase(system->getSystemID()); - - delete system; - } -} - +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+#ifdef WIN32
+#pragma warning(disable:4786)
+#endif
+
+#include <Ice/SslFactory.h>
+#include <Ice/SslSystemOpenSSL.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+// Static member instantiations.
+JTCMutex Factory::_systemRepositoryMutex;
+SystemMap Factory::_systemRepository;
+SslHandleSystemMap Factory::_sslHandleSystemRepository;
+
+}
+
+}
+
+IceSecurity::Ssl::System*
+IceSecurity::Ssl::Factory::getSystem(string& systemIdentifier)
+{
+ JTCSyncT<JTCMutex> sync(_systemRepositoryMutex);
+
+ System* _system = _systemRepository[systemIdentifier];
+
+ // Don't have that System.
+ if (_system == 0)
+ {
+ // In our case, the systemIdentifier happens to be the
+ // SSL Configuration file.
+
+ // This line would change based on the flavor of System that we're
+ // creating for the caller.
+ _system = new OpenSSL::System(systemIdentifier);
+
+ if (_system != 0)
+ {
+ _systemRepository[systemIdentifier] = _system;
+ }
+ }
+
+ assert(_system);
+
+ _system->incRef();
+
+ return _system;
+}
+
+void
+IceSecurity::Ssl::Factory::releaseSystem(System* system)
+{
+ JTCSyncT<JTCMutex> sync(_systemRepositoryMutex);
+
+ assert(system);
+
+ // If the reference count is now at zero.
+ if (!system->decRef())
+ {
+ _systemRepository.erase(system->getSystemID());
+
+ delete system;
+ }
+}
+
+void
+IceSecurity::Ssl::Factory::addSystemHandle(void* sslHandle, System* system)
+{
+ assert(sslHandle);
+ assert(system);
+ _sslHandleSystemRepository[sslHandle] = system;
+}
+
+IceSecurity::Ssl::System*
+IceSecurity::Ssl::Factory::getSystemFromHandle(void* sslHandle)
+{
+ JTCSyncT<JTCMutex> sync(_systemRepositoryMutex);
+
+ assert(sslHandle);
+
+ System* _system = _sslHandleSystemRepository[sslHandle];
+
+ assert(_system);
+
+ _system->incRef();
+
+ return _system;
+}
+
+void
+IceSecurity::Ssl::Factory::releaseSystemFromHandle(void* sslHandle, System* system)
+{
+ JTCSyncT<JTCMutex> sync(_systemRepositoryMutex);
+
+ assert(sslHandle);
+ assert(system);
+
+ // If the reference count is now at zero.
+ if (!system->decRef())
+ {
+ _sslHandleSystemRepository.erase(sslHandle);
+ _systemRepository.erase(system->getSystemID());
+
+ delete system;
+ }
+}
+
diff --git a/cpp/src/Ice/SslFactory.h b/cpp/src/Ice/SslFactory.h index 44b02f49a4b..bb226619d6d 100644 --- a/cpp/src/Ice/SslFactory.h +++ b/cpp/src/Ice/SslFactory.h @@ -1,58 +1,58 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_SSL_FACTORY_H -#define ICE_SSL_FACTORY_H - -#include <string> -#include <map> -#include <JTC/JTC.h> -#include <Ice/SslSystem.h> - -namespace IceSecurity -{ - -namespace Ssl -{ - -using std::string; -using std::map; - -typedef map<string,System*> SystemMap; -typedef map<void*,System*> SslHandleSystemMap; - -// This is defined as a class so as to ensure encapsulation. We don't -// want just anybody creating System instances - when all this is moved -// out to a DLL/SO, we want to ensure that this vanilla interface is used -// to get whatever flavor of System the DLL/SO is designed to hand out. As -// a result, different flavors of the Security Extension DLL/SO will have -// different definitions for getSystem(). -class Factory -{ - -public: - static System* getSystem(string&); - static void releaseSystem(System*); - - static void addSystemHandle(void*, System*); - static System* getSystemFromHandle(void*); - static void releaseSystemFromHandle(void*, System*); - -private: - static SslHandleSystemMap _sslHandleSystemRepository; - static SystemMap _systemRepository; - static JTCMutex _systemRepositoryMutex; -}; - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_FACTORY_H
+#define ICE_SSL_FACTORY_H
+
+#include <string>
+#include <map>
+#include <JTC/JTC.h>
+#include <Ice/SslSystem.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+using std::string;
+using std::map;
+
+typedef map<string,System*> SystemMap;
+typedef map<void*,System*> SslHandleSystemMap;
+
+// This is defined as a class so as to ensure encapsulation. We don't
+// want just anybody creating System instances - when all this is moved
+// out to a DLL/SO, we want to ensure that this vanilla interface is used
+// to get whatever flavor of System the DLL/SO is designed to hand out. As
+// a result, different flavors of the Security Extension DLL/SO will have
+// different definitions for getSystem().
+class Factory
+{
+
+public:
+ static System* getSystem(string&);
+ static void releaseSystem(System*);
+
+ static void addSystemHandle(void*, System*);
+ static System* getSystemFromHandle(void*);
+ static void releaseSystemFromHandle(void*, System*);
+
+private:
+ static SslHandleSystemMap _sslHandleSystemRepository;
+ static SystemMap _systemRepository;
+ static JTCMutex _systemRepositoryMutex;
+};
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslGeneralConfig.cpp b/cpp/src/Ice/SslGeneralConfig.cpp index 5d32a43c9d9..6c804c1027f 100644 --- a/cpp/src/Ice/SslGeneralConfig.cpp +++ b/cpp/src/Ice/SslGeneralConfig.cpp @@ -1,146 +1,146 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** -#ifdef WIN32 -#pragma warning(disable:4786) -#endif - -#include <string> -#include <algorithm> - -#include <openssl/ssl.h> -#include <Ice/SslGeneralConfig.h> - -using namespace std; - -IceSecurity::Ssl::GeneralConfig::GeneralConfig() -{ - _sslVersion = SSL_V23; - - _verifyMode = SSL_VERIFY_NONE; - _verifyDepth = 10; - - _context = ""; - _cipherList = ""; - _randomBytesFiles = ""; -} - -void -IceSecurity::Ssl::GeneralConfig::set(string& name, string& value) -{ - if (name.compare("version") == 0) - { - parseVersion(value); - } - else if (name.compare("cipherlist") == 0) - { - _cipherList = value; - } - else if (name.compare("context") == 0) - { - _context = value; - } - else if (name.compare("verifymode") == 0) - { - parseVerifyMode(value); - } - else if (name.compare("verifydepth") == 0) - { - _verifyDepth = atoi(value.c_str()); - } - else if (name.compare("randombytes") == 0) - { - _randomBytesFiles = value; - } - return; -} - -// -// Protected Methods -// - -void -IceSecurity::Ssl::GeneralConfig::parseVersion(string& value) -{ - if (value.compare("SSLv2") == 0) - { - _sslVersion = SSL_V2; - } - else if (value.compare("SSLv23") == 0) - { - _sslVersion = SSL_V23; - } - else if (value.compare("SSLv3") == 0) - { - _sslVersion = SSL_V3; - } - else if (value.compare("TLSv1") == 0) - { - _sslVersion = TLS_V1; - } - - return; -} - -void -IceSecurity::Ssl::GeneralConfig::parseVerifyMode(string& value) -{ - const string delim = " |\t\n\r"; - - string s(value); - transform(s.begin(), s.end(), s.begin(), tolower); - - string::size_type beg; - string::size_type end = 0; - - while (true) - { - beg = s.find_first_not_of(delim, end); - - if (beg == string::npos) - { - break; - } - - end = s.find_first_of(delim, beg); - - if (end == string::npos) - { - end = s.length(); - } - - string option = s.substr(beg, end - beg); - - if (option.compare("none") == 0) - { - _verifyMode |= SSL_VERIFY_NONE; - } - else if (option.compare("peer") == 0) - { - _verifyMode |= SSL_VERIFY_PEER; - } - else if (option.compare("fail_no_cert") == 0) - { - _verifyMode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - } - else if (option.compare("client_once") == 0) - { - _verifyMode |= SSL_VERIFY_CLIENT_ONCE; - } - } - - // Both SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE require - // that SSL_VERIFY_PEER be set, otherwise it's an error. - if ((_verifyMode != SSL_VERIFY_NONE) && !(_verifyMode & SSL_VERIFY_PEER)) - { - _verifyMode = SSL_VERIFY_NONE; - } - - return; -} +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+#ifdef WIN32
+#pragma warning(disable:4786)
+#endif
+
+#include <string>
+#include <algorithm>
+
+#include <openssl/ssl.h>
+#include <Ice/SslGeneralConfig.h>
+
+using namespace std;
+
+IceSecurity::Ssl::GeneralConfig::GeneralConfig()
+{
+ _sslVersion = SSL_V23;
+
+ _verifyMode = SSL_VERIFY_NONE;
+ _verifyDepth = 10;
+
+ _context = "";
+ _cipherList = "";
+ _randomBytesFiles = "";
+}
+
+void
+IceSecurity::Ssl::GeneralConfig::set(string& name, string& value)
+{
+ if (name.compare("version") == 0)
+ {
+ parseVersion(value);
+ }
+ else if (name.compare("cipherlist") == 0)
+ {
+ _cipherList = value;
+ }
+ else if (name.compare("context") == 0)
+ {
+ _context = value;
+ }
+ else if (name.compare("verifymode") == 0)
+ {
+ parseVerifyMode(value);
+ }
+ else if (name.compare("verifydepth") == 0)
+ {
+ _verifyDepth = atoi(value.c_str());
+ }
+ else if (name.compare("randombytes") == 0)
+ {
+ _randomBytesFiles = value;
+ }
+ return;
+}
+
+//
+// Protected Methods
+//
+
+void
+IceSecurity::Ssl::GeneralConfig::parseVersion(string& value)
+{
+ if (value.compare("SSLv2") == 0)
+ {
+ _sslVersion = SSL_V2;
+ }
+ else if (value.compare("SSLv23") == 0)
+ {
+ _sslVersion = SSL_V23;
+ }
+ else if (value.compare("SSLv3") == 0)
+ {
+ _sslVersion = SSL_V3;
+ }
+ else if (value.compare("TLSv1") == 0)
+ {
+ _sslVersion = TLS_V1;
+ }
+
+ return;
+}
+
+void
+IceSecurity::Ssl::GeneralConfig::parseVerifyMode(string& value)
+{
+ const string delim = " |\t\n\r";
+
+ string s(value);
+ transform(s.begin(), s.end(), s.begin(), tolower);
+
+ string::size_type beg;
+ string::size_type end = 0;
+
+ while (true)
+ {
+ beg = s.find_first_not_of(delim, end);
+
+ if (beg == string::npos)
+ {
+ break;
+ }
+
+ end = s.find_first_of(delim, beg);
+
+ if (end == string::npos)
+ {
+ end = s.length();
+ }
+
+ string option = s.substr(beg, end - beg);
+
+ if (option.compare("none") == 0)
+ {
+ _verifyMode |= SSL_VERIFY_NONE;
+ }
+ else if (option.compare("peer") == 0)
+ {
+ _verifyMode |= SSL_VERIFY_PEER;
+ }
+ else if (option.compare("fail_no_cert") == 0)
+ {
+ _verifyMode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+ }
+ else if (option.compare("client_once") == 0)
+ {
+ _verifyMode |= SSL_VERIFY_CLIENT_ONCE;
+ }
+ }
+
+ // Both SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE require
+ // that SSL_VERIFY_PEER be set, otherwise it's an error.
+ if ((_verifyMode != SSL_VERIFY_NONE) && !(_verifyMode & SSL_VERIFY_PEER))
+ {
+ _verifyMode = SSL_VERIFY_NONE;
+ }
+
+ return;
+}
diff --git a/cpp/src/Ice/SslGeneralConfig.h b/cpp/src/Ice/SslGeneralConfig.h index f8f06f8443d..024b14a6461 100644 --- a/cpp/src/Ice/SslGeneralConfig.h +++ b/cpp/src/Ice/SslGeneralConfig.h @@ -1,75 +1,75 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_SSL_GENERAL_CONFIG_H -#define ICE_SSL_GENERAL_CONFIG_H - -#include <Ice/SslSystemOpenSSL.h> -#include <string> - -namespace IceSecurity -{ - -namespace Ssl -{ - -using std::string; -using std::ostream; - -class GeneralConfig -{ - -public: - GeneralConfig(); - - inline SslProtocol getProtocol() const { return _sslVersion; }; - inline int getVerifyMode() const { return _verifyMode; }; - inline int getVerifyDepth() const { return _verifyDepth; }; - - inline string getContext() const { return _context; }; - inline string getCipherList() const { return _cipherList; }; - inline string getRandomBytesFiles() const { return _randomBytesFiles; }; - - // General method - it will figure out how to properly parse the data. - void set(string&, string&); - -protected: - - SslProtocol _sslVersion; - - int _verifyMode; - int _verifyDepth; - - string _context; - string _cipherList; - string _randomBytesFiles; - - void parseVersion(string&); - void parseVerifyMode(string&); -}; - -template<class Stream> inline -Stream& operator << (Stream& target, const GeneralConfig& generalConfig) -{ - target << "Protocol: " << generalConfig.getProtocol() << endl; - target << "Verify Mode: " << generalConfig.getVerifyMode() << endl; - target << "Verify Depth: " << generalConfig.getVerifyDepth() << endl; - target << "Context: " << generalConfig.getContext() << endl; - target << "Cipher List: " << generalConfig.getCipherList() << endl; - target << "Random Bytes: " << generalConfig.getRandomBytesFiles() << endl; - - return target; -} - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_GENERAL_CONFIG_H
+#define ICE_SSL_GENERAL_CONFIG_H
+
+#include <Ice/SslSystemOpenSSL.h>
+#include <string>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+using std::string;
+using std::ostream;
+
+class GeneralConfig
+{
+
+public:
+ GeneralConfig();
+
+ inline SslProtocol getProtocol() const { return _sslVersion; };
+ inline int getVerifyMode() const { return _verifyMode; };
+ inline int getVerifyDepth() const { return _verifyDepth; };
+
+ inline string getContext() const { return _context; };
+ inline string getCipherList() const { return _cipherList; };
+ inline string getRandomBytesFiles() const { return _randomBytesFiles; };
+
+ // General method - it will figure out how to properly parse the data.
+ void set(string&, string&);
+
+protected:
+
+ SslProtocol _sslVersion;
+
+ int _verifyMode;
+ int _verifyDepth;
+
+ string _context;
+ string _cipherList;
+ string _randomBytesFiles;
+
+ void parseVersion(string&);
+ void parseVerifyMode(string&);
+};
+
+template<class Stream> inline
+Stream& operator << (Stream& target, const GeneralConfig& generalConfig)
+{
+ target << "Protocol: " << generalConfig.getProtocol() << endl;
+ target << "Verify Mode: " << generalConfig.getVerifyMode() << endl;
+ target << "Verify Depth: " << generalConfig.getVerifyDepth() << endl;
+ target << "Context: " << generalConfig.getContext() << endl;
+ target << "Cipher List: " << generalConfig.getCipherList() << endl;
+ target << "Random Bytes: " << generalConfig.getRandomBytesFiles() << endl;
+
+ return target;
+}
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslSystem.cpp b/cpp/src/Ice/SslSystem.cpp index 947bf48f556..04a8059676d 100644 --- a/cpp/src/Ice/SslSystem.cpp +++ b/cpp/src/Ice/SslSystem.cpp @@ -1,28 +1,28 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include <string> -#include <Ice/SslSystem.h> - -using namespace std; - -// -// Protected Methods -// - -IceSecurity::Ssl::System::System(string& systemID) : - _systemID(systemID), - _refCount(0) -{ -} - -IceSecurity::Ssl::System::~System() -{ -} +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <string>
+#include <Ice/SslSystem.h>
+
+using namespace std;
+
+//
+// Protected Methods
+//
+
+IceSecurity::Ssl::System::System(string& systemID) :
+ _systemID(systemID),
+ _refCount(0)
+{
+}
+
+IceSecurity::Ssl::System::~System()
+{
+}
diff --git a/cpp/src/Ice/SslSystem.h b/cpp/src/Ice/SslSystem.h index c3376bfa7ab..9fd62fa01ff 100644 --- a/cpp/src/Ice/SslSystem.h +++ b/cpp/src/Ice/SslSystem.h @@ -1,72 +1,79 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - - -#ifndef ICE_SSL_SYSTEM_H -#define ICE_SSL_SYSTEM_H - -#include <string> -#include <Ice/SslConnection.h> - -namespace IceSecurity -{ - -namespace Ssl -{ - -using std::string; - -class Factory; - -// TODO: Can we derive this from Shared? How hard would that be? - -class System -{ - -public: - inline string getSystemID() const { return _systemID; }; - - virtual bool isConfigLoaded() = 0; - virtual void loadConfig() = 0; - virtual void shutdown() = 0; - - virtual Connection* createServerConnection(int) = 0; - virtual Connection* createClientConnection(int) = 0; - - void setTrace(TraceLevelsPtr traceLevels) { _traceLevels = traceLevels; }; - bool isTraceSet() const { return (_traceLevels == 0 ? false : true); }; - - void setLogger(Ice::LoggerPtr traceLevels) { _logger = traceLevels; }; - bool isLoggerSet() const { return (_logger == 0 ? false : true); }; - -protected: - - System(string&); - virtual ~System(); - - // Reference counting. - inline void incRef() { _refCount++; }; - inline bool decRef() { return (--_refCount ? true : false); }; - - string _systemID; - int _refCount; - - TraceLevelsPtr _traceLevels; - Ice::LoggerPtr _logger; - -friend class Factory; - -}; - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+
+#ifndef ICE_SSL_SYSTEM_H
+#define ICE_SSL_SYSTEM_H
+
+#include <string>
+#include <Ice/SslConnection.h>
+#include <Ice/Properties.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+using std::string;
+using Ice::LoggerPtr;
+using Ice::PropertiesPtr;
+
+class Factory;
+
+// TODO: Can we derive this from Shared? How hard would that be?
+
+class System
+{
+
+public:
+ inline string getSystemID() const { return _systemID; };
+
+ virtual bool isConfigLoaded() = 0;
+ virtual void loadConfig() = 0;
+ virtual void shutdown() = 0;
+
+ virtual Connection* createServerConnection(int) = 0;
+ virtual Connection* createClientConnection(int) = 0;
+
+ void setTrace(TraceLevelsPtr traceLevels) { _traceLevels = traceLevels; };
+ bool isTraceSet() const { return (_traceLevels == 0 ? false : true); };
+
+ void setLogger(LoggerPtr traceLevels) { _logger = traceLevels; };
+ bool isLoggerSet() const { return (_logger == 0 ? false : true); };
+
+ void setProperties(PropertiesPtr properties) { _properties = properties; };
+ bool isPropertiesSet() const { return (_properties == 0 ? false : true); };
+
+protected:
+
+ System(string&);
+ virtual ~System();
+
+ // Reference counting.
+ inline void incRef() { _refCount++; };
+ inline bool decRef() { return (--_refCount ? true : false); };
+
+ string _systemID;
+ int _refCount;
+
+ TraceLevelsPtr _traceLevels;
+ LoggerPtr _logger;
+ PropertiesPtr _properties;
+
+friend class Factory;
+
+};
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslSystemOpenSSL.cpp b/cpp/src/Ice/SslSystemOpenSSL.cpp index 9ed157eaae7..ec404c78c1a 100644 --- a/cpp/src/Ice/SslSystemOpenSSL.cpp +++ b/cpp/src/Ice/SslSystemOpenSSL.cpp @@ -1,1546 +1,1577 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** -#ifdef WIN32 -#pragma warning(disable:4786) -#endif - -#include <sstream> -#include <openssl/err.h> -#include <openssl/e_os.h> -#include <openssl/rand.h> -#include <Ice/Security.h> -#include <Ice/SslSystem.h> -#include <Ice/SslException.h> -#include <Ice/SslConnectionOpenSSLClient.h> -#include <Ice/SslConnectionOpenSSLServer.h> -#include <Ice/SslConfig.h> - -using namespace std; - -namespace IceSecurity -{ - -namespace Ssl -{ - -namespace OpenSSL -{ - -// -// TODO: These Diffie-Hellman params have been blatantly stolen from -// OpenSSL's demo programs. We SHOULD define our own here, but -// these will suffice for testing purposes. Please note, these -// are not keys themselves, simply a DH Group that allows OpenSSL -// to create Diffie-Hellman keys. -// - -// Instantiation of temporary Diffie-Hellman 512bit key. -unsigned char System::_tempDiffieHellman512p[] = -{ - 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, - 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, - 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, - 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, - 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, - 0x47,0x74,0xE8,0x33, -}; - -unsigned char System::_tempDiffieHellman512g[] = -{ - 0x02, -}; - -// TODO: Very possibly a problem later if we have mutliple loggers going on simultaneously. -// This is a horrible necessity in order to make the trace levels -// and logger available to the bio_dump_cb() callback function. -// Otherwise, we would have to jump through hoops, creating a mapping -// from BIO pointers to the relevent System object. The system object -// will initialize these. NOTE: If we SHOULD have multiple loggers -// going on simultaneously, this will definitely cause a problem. -TraceLevelsPtr System::_globalTraceLevels = 0; -Ice::LoggerPtr System::_globalLogger = 0; - -} - -} - -} - -using IceSecurity::Ssl::OpenSSL::ContextException; - -// -// NOTE: The following (mon, getGeneralizedTime, getUTCTime and getASN1time are routines that -// have been abducted from the OpenSSL X509 library, and modified to work with the STL -// basic_string template. - -static const char *mon[12]= -{ - "Jan","Feb","Mar","Apr","May","Jun", - "Jul","Aug","Sep","Oct","Nov","Dec" -}; - -string -getGeneralizedTime(ASN1_GENERALIZEDTIME *tm) -{ - char buf[30]; - char *v; - int gmt=0; - int i; - int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; - - i = tm->length; - v = (char *) tm->data; - - if (i < 12) - { - goto err; - } - - if (v[i-1] == 'Z') - { - gmt=1; - } - - for (i=0; i<12; i++) - { - if ((v[i] > '9') || (v[i] < '0')) - { - goto err; - } - } - - y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 + (v[2] - '0') * 10 + (v[3] - '0'); - M = (v[4] - '0') * 10 + (v[5] - '0'); - - if ((M > 12) || (M < 1)) - { - goto err; - } - - d = (v[6] - '0') * 10 + (v[7] - '0'); - h = (v[8] - '0') * 10 + (v[9] - '0'); - m = (v[10] - '0') * 10 + (v[11] - '0'); - - if ((v[12] >= '0') && (v[12] <= '9') && - (v[13] >= '0') && (v[13] <= '9')) - { - s = (v[12] - '0') * 10 + (v[13] - '0'); - } - - sprintf(buf, "%s %2d %02d:%02d:%02d %d%s", mon[M-1], d, h, m, s, y, (gmt)?" GMT":""); - return string(buf); - -err: - return string("Bad time value"); -} - -string -getUTCTime(ASN1_UTCTIME *tm) -{ - char buf[30]; - char *v; - int gmt=0; - int i; - int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; - - i = tm->length; - v = (char *) tm->data; - - if (i < 10) - { - goto err; - } - - if (v[i-1] == 'Z') - { - gmt=1; - } - - for (i = 0; i < 10; i++) - { - if ((v[i] > '9') || (v[i] < '0')) - { - goto err; - } - } - - y = (v[0] - '0') * 10 + (v[1] - '0'); - - if (y < 50) - { - y+=100; - } - - M = (v[2] - '0') * 10 + (v[3] - '0'); - - if ((M > 12) || (M < 1)) - { - goto err; - } - - d = (v[4] - '0') * 10 + (v[5] - '0'); - h = (v[6] - '0') * 10 + (v[7] - '0'); - m = (v[8] - '0') * 10 + (v[9] - '0'); - - if ((v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9')) - { - s = (v[10] - '0') * 10 + (v[11] - '0'); - } - - sprintf(buf, "%s %2d %02d:%02d:%02d %d%s", mon[M-1], d, h, m, s, y+1900, (gmt)?" GMT":""); - return string(buf); - -err: - return string("Bad time value"); -} - -string -getASN1time(ASN1_TIME *tm) -{ - string theTime; - - switch (tm->type) - { - case V_ASN1_UTCTIME : - { - theTime = getUTCTime(tm); - } - - case V_ASN1_GENERALIZEDTIME : - { - theTime = getGeneralizedTime(tm); - } - - default : - { - theTime = "Bad time value"; - } - } - - return theTime; -} - -extern "C" -{ - -RSA* -tmpRSACallback(SSL *s, int isExport, int keyLength) -{ - IceSecurity::Ssl::System* sslSystem = IceSecurity::Ssl::Factory::getSystemFromHandle(s); - - IceSecurity::Ssl::OpenSSL::System* openSslSystem = dynamic_cast<IceSecurity::Ssl::OpenSSL::System*>(sslSystem); - - RSA* rsaKey = openSslSystem->getRSAKey(s, isExport, keyLength); - - IceSecurity::Ssl::Factory::releaseSystemFromHandle(s, sslSystem); - - return rsaKey; -} - -DH* -tmpDHCallback(SSL *s, int isExport, int keyLength) -{ - IceSecurity::Ssl::System* sslSystem = IceSecurity::Ssl::Factory::getSystemFromHandle(s); - - IceSecurity::Ssl::OpenSSL::System* openSslSystem = dynamic_cast<IceSecurity::Ssl::OpenSSL::System*>(sslSystem); - - DH* dh = openSslSystem->getDHParams(s, isExport, keyLength); - - IceSecurity::Ssl::Factory::releaseSystemFromHandle(s, sslSystem); - - return dh; -} - -// verifyCallback - Certificate Verification callback function. -int -verifyCallback(int ok, X509_STORE_CTX *ctx) -{ - X509* err_cert = X509_STORE_CTX_get_current_cert(ctx); - int verifyError = X509_STORE_CTX_get_error(ctx); - int depth = X509_STORE_CTX_get_error_depth(ctx); - - // If we have no errors so far, and the certificate chain is too long - if ((verifyError != X509_V_OK) && (10 < depth)) - { - verifyError = X509_V_ERR_CERT_CHAIN_TOO_LONG; - } - - if (verifyError != X509_V_OK) - { - // If we have ANY errors, we bail out. - ok = 0; - } - - // Only if PROTOCOL level logging is on do we worry about this. - if (IceSecurity::Ssl::OpenSSL::System::_globalTraceLevels->security >= IceSecurity::SECURITY_PROTOCOL) - { - char buf[256]; - - X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf)); - - ostringstream outStringStream; - - outStringStream << "depth = " << depth << ":" << buf << endl; - - if (!ok) - { - 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(ctx->current_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(ctx->current_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(ctx->current_cert)) << endl; - break; - } - } - - outStringStream << "verify return = " << ok << endl; - - IceSecurity::Ssl::OpenSSL::System::_globalLogger->trace(IceSecurity::Ssl::OpenSSL::System::_globalTraceLevels->securityCat, outStringStream.str()); - } - - return ok; -} - -// This code duplicates functionality that existed in the BIO library of -// OpenSSL, but outputs to a Logger compatible source (ostringstream). -void -dump(ostringstream& outStringStream, const char* s, int len) -{ - unsigned char ch; - char hexStr[8]; - - int trunc = 0; - - // Calculate how much white space we're truncating. - for(; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--) - { - trunc++; - } - - int dump_width = 12; - - int rows = len / dump_width; - - if ((rows * dump_width) < len) - { - rows++; - } - - if (rows > 0) - { - outStringStream << endl; - } - - for(int i = 0; i < rows; i++) - { - // Would like to have not used sprintf(), but - // I could not find an appropriate STL methodology - // for preserving the field width. - sprintf(hexStr,"%04x",(i * dump_width)); - outStringStream << hexStr << " - "; - - int j; - - // Hex Dump - for(j = 0; j < dump_width; j++) - { - if (((i * dump_width) + j) >= len) - { - outStringStream << " "; - } - else - { - char sep = (j == 7 ? '-' : ' '); - - // Get a character from the dump we've been handed. - ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; - - // Would like to have not used sprintf(), but - // I could not find an appropriate STL methodology - // for preserving the field width. - sprintf(hexStr,"%02x",ch); - outStringStream << hexStr << sep; - } - } - - outStringStream << " "; - - // Printable characters dump. - for(j = 0; j < dump_width; j++) - { - if (((i * dump_width) + j) >= len) - { - break; - } - - ch = ((unsigned char) * (s + i * dump_width + j)) & 0xff; - - // Print printables only. - ch = ((ch >= ' ') && (ch <= '~')) ? ch : '.'; - - outStringStream << ch; - } - - outStringStream << endl; - } - - if (trunc > 0) - { - outStringStream << hex << (len + trunc) << " - " << "<SPACES/NULS>" << endl; - } -} - -long -bio_dump_cb(BIO *bio, int cmd, const char *argp, int argi, long argl, long ret) -{ - if (IceSecurity::Ssl::OpenSSL::System::_globalTraceLevels->security >= IceSecurity::SECURITY_PROTOCOL) - { - ostringstream outStringStream; - - if (cmd == (BIO_CB_READ|BIO_CB_RETURN)) - { - outStringStream << "PTC "; - outStringStream << "read from " << hex << (void *)bio << " [" << hex << (void *)argp; - outStringStream << "] (" << dec << argi << " bytes => " << ret << " (0x"; - outStringStream << hex << ret << "))"; - dump(outStringStream, argp,(int)ret); - } - else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) - { - outStringStream << "PTC "; - outStringStream << "write to " << hex << (void *)bio << " [" << hex << (void *)argp; - outStringStream << "] (" << dec << argi << " bytes => " << ret << " (0x"; - outStringStream << hex << ret << "))"; - dump(outStringStream, argp,(int)ret); - } - - if (cmd == (BIO_CB_READ|BIO_CB_RETURN) || cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) - { - IceSecurity::Ssl::OpenSSL::System::_globalLogger->trace(IceSecurity::Ssl::OpenSSL::System::_globalTraceLevels->securityCat, outStringStream.str()); - } - } - - return ret; -} - -} - -void -IceSecurity::Ssl::OpenSSL::System::printContextInfo(SSL_CTX* context) -{ - if (SECURITY_LEVEL_PROTOCOL) - { - ostringstream s; - - s << endl; - s << "SSL_CTX Structure" << endl; - s << "=================" << endl; - s << "options: 0x" << hex << context->options << endl; - s << "mode: 0x" << hex << context->mode << endl; - - s << "session_cache_size: " << context->session_cache_size << endl; - s << "session_cache_mode: 0x" << hex << context->session_cache_mode << endl; - s << "session_timeout: " << Int(context->session_timeout) << endl << endl; - - s << "Stats" << endl; - s << "Connect: " << context->stats.sess_connect << " (New Connect Started)" << endl; - s << "Renegotiate: " << context->stats.sess_connect_renegotiate << " (Renegotiation Requested)" << endl; - s << "Connect Good: " << context->stats.sess_connect_good << " (Connect/Renegotiation finished)"; - s << endl << endl; - - s << "Accept: " << context->stats.sess_accept << " (New Accept Started)" << endl; - s << "Renegotiate: " << context->stats.sess_accept_renegotiate << " (Renegotiation Requested)" << endl; - s << "Accept Good: " << context->stats.sess_accept_good << " (Accept/Renegotiation finished)"; - s << endl << endl; - - s << "Miss: " << context->stats.sess_miss << " (Session Lookup Misses)" << endl; - s << "Timeout: " << context->stats.sess_timeout << " (Reuse attempt on Timeouted Session)" << endl; - s << "Cache Full: " << context->stats.sess_cache_full << " (Session Removed due to full cache)" << endl; - s << "Hit: " << context->stats.sess_hit << " (Session Reuse actually done.)" << endl; - s << "CB Hit: " << context->stats.sess_cb_hit << " (Session ID supplied by Callback)" << endl; - - s << "read_ahead: " << context->read_ahead << endl; - s << "verify_mode: 0x" << hex << context->verify_mode << endl; - s << "verify_depth: " << Int(context->verify_depth) << endl; - - PROTOCOL(s.str()); - } -} - -IceSecurity::Ssl::Connection* -IceSecurity::Ssl::OpenSSL::System::createServerConnection(int socket) -{ - METHOD_INV("OpenSSL::System::createServerConnection()"); - - SSL* sslConnection = createConnection(_sslServerContext, socket); - - // Set the Accept Connection state for this connection. - SSL_set_accept_state(sslConnection); - - Connection* connection = new ServerConnection(sslConnection, _systemID); - - connection->setTrace(_traceLevels); - connection->setLogger(_logger); - - continueInit: - try - { - while (!connection->init()) { } - } - catch (const TimeoutException&) - { - // Ignore, this might happen a lot during handshake. - goto continueInit; - } - catch (...) - { - if (connection != 0) - { - delete connection; - connection = 0; - } - - throw; - } - - METHOD_RET("OpenSSL::System::createServerConnection()"); - - return connection; -} - -IceSecurity::Ssl::Connection* -IceSecurity::Ssl::OpenSSL::System::createClientConnection(int socket) -{ - METHOD_INV("OpenSSL::System::createClientConnection()"); - - SSL* sslConnection = createConnection(_sslClientContext, socket); - - // Set the Connect Connection state for this connection. - SSL_set_connect_state(sslConnection); - - Connection* connection = new ClientConnection(sslConnection, _systemID); - - connection->setTrace(_traceLevels); - connection->setLogger(_logger); - - continueInit: - try - { - while (!connection->init()) { } - } - catch (const TimeoutException&) - { - // Ignore, this might happen a lot during handshake. - goto continueInit; - } - catch (...) - { - if (connection != 0) - { - delete connection; - connection = 0; - } - - throw; - } - - METHOD_RET("OpenSSL::System::createClientConnection()"); - - return connection; -} - -void -IceSecurity::Ssl::OpenSSL::System::shutdown() -{ - METHOD_INV("OpenSSL::System::shutdown()"); - - if (_sslServerContext != 0) - { - SSL_CTX_free(_sslServerContext); - - _sslServerContext = 0; - } - - if (_sslClientContext != 0) - { - SSL_CTX_free(_sslClientContext); - - _sslClientContext = 0; - } - - // Free our temporary RSA keys. - RSAMap::iterator iRSA = _tempRSAKeys.begin(); - RSAMap::iterator eRSA = _tempRSAKeys.end(); - - while (iRSA != eRSA) - { - RSA_free((*iRSA).second); - iRSA++; - } - - // Free our temporary DH params. - DHMap::iterator iDH = _tempDHKeys.begin(); - DHMap::iterator eDH = _tempDHKeys.end(); - - while (iDH != eDH) - { - DH_free((*iDH).second); - iDH++; - } - - METHOD_RET("OpenSSL::System::shutdown()"); -} - -bool -IceSecurity::Ssl::OpenSSL::System::isConfigLoaded() -{ - METHOD_INS("OpenSSL::System::isConfigLoaded()"); - - return _configLoaded; -} - -void -IceSecurity::Ssl::OpenSSL::System::loadConfig() -{ - METHOD_INV("OpenSSL::System::loadConfig()"); - - // This step is required in order to supply callback functions - // with access to the TraceLevels and Logger. - if (_globalTraceLevels == 0) - { - _globalTraceLevels = _traceLevels; - _globalLogger = _logger; - } - - const string& systemID = getSystemID(); - Parser sslConfig(systemID); - - sslConfig.setTrace(_traceLevels); - sslConfig.setLogger(_logger); - - // Actually parse the file now. - sslConfig.process(); - - GeneralConfig clientGeneral; - CertificateAuthority clientCertAuth; - BaseCertificates clientBaseCerts; - - // Walk the parse tree, get the Client configuration. - if (sslConfig.loadClientConfig(clientGeneral, clientCertAuth, clientBaseCerts)) - { - if (SECURITY_LEVEL_PROTOCOL) - { - ostringstream s; - - s << endl; - s << "General Configuration - Client" << endl; - s << "------------------------------" << endl; - s << clientGeneral << endl << endl; - - s << "Base Certificates - Client" << endl; - s << "--------------------------" << endl; - s << clientBaseCerts << endl; - - PROTOCOL(s.str()); - } - - initClient(clientGeneral, clientCertAuth, clientBaseCerts); - } - - GeneralConfig serverGeneral; - CertificateAuthority serverCertAuth; - BaseCertificates serverBaseCerts; - TempCertificates serverTempCerts; - - // Walk the parse tree, get the Server configuration. - if (sslConfig.loadServerConfig(serverGeneral, serverCertAuth, serverBaseCerts, serverTempCerts)) - { - if (SECURITY_LEVEL_PROTOCOL) - { - ostringstream s; - - s << endl; - s << "General Configuration - Server" << endl; - s << "------------------------------" << endl; - s << serverGeneral << endl << endl; - - s << "Base Certificates - Server" << endl; - s << "--------------------------" << endl; - s << serverBaseCerts << endl << endl; - - s << "Temp Certificates - Server" << endl; - s << "--------------------------" << endl; - s << serverTempCerts << endl; - - PROTOCOL(s.str()); - } - - initServer(serverGeneral, serverCertAuth, serverBaseCerts, serverTempCerts); - } - - METHOD_RET("OpenSSL::System::loadConfig()"); -} - -RSA* -IceSecurity::Ssl::OpenSSL::System::getRSAKey(SSL *s, int isExport, int keyLength) -{ - METHOD_INV("OpenSSL::System::getRSAKey()"); - - JTCSyncT<JTCMutex> sync(_tempRSAKeysMutex); - - RSA* rsa_tmp = 0; - - RSAMap::iterator retVal = _tempRSAKeys.find(keyLength); - - // Does the key already exist? - if (retVal != _tempRSAKeys.end()) - { - // Yes! Use it. - rsa_tmp = (*retVal).second; - } - else - { - const RSACertMap::iterator& it = _tempRSAFileMap.find(keyLength); - - if (it != _tempRSAFileMap.end()) - { - CertificateDesc& rsaKeyCert = (*it).second; - - const string& privKeyFile = rsaKeyCert.getPrivate().getFileName(); - const string& pubCertFile = rsaKeyCert.getPublic().getFileName(); - - RSA* rsaCert = 0; - RSA* rsaKey = 0; - BIO* bio = 0; - - if ((bio = BIO_new_file(pubCertFile.c_str(), "r")) != 0) - { - rsaCert = PEM_read_bio_RSAPublicKey(bio, 0, 0, 0); - - BIO_free(bio); - bio = 0; - } - - if (rsaCert != 0) - { - if ((bio = BIO_new_file(privKeyFile.c_str(), "r")) != 0) - { - rsaKey = PEM_read_bio_RSAPrivateKey(bio, &rsaCert, 0, 0); - - BIO_free(bio); - bio = 0; - } - } - - // Now, if all was well, the Certificate and Key should both be loaded into - // rsaCert. We check to ensure that both are not 0, because if either are, - // one of the reads failed. - - if ((rsaCert != 0) && (rsaKey != 0)) - { - rsa_tmp = rsaCert; - } - else - { - RSA_free(rsaCert); - rsaCert = 0; - } - } - - // Last ditch effort - generate a key on the fly. - if (rsa_tmp == 0) - { - rsa_tmp = RSA_generate_key(keyLength, RSA_F4, 0, 0); - } - - // Save in our temporary key cache. - if (rsa_tmp == 0) - { - _tempRSAKeys[keyLength] = rsa_tmp; - } - } - - METHOD_RET("OpenSSL::System::getRSAKey()"); - - return rsa_tmp; -} - -DH* -IceSecurity::Ssl::OpenSSL::System::getDHParams(SSL *s, int isExport, int keyLength) -{ - METHOD_INV("OpenSSL::System::getDHParams()"); - - JTCSyncT<JTCMutex> sync(_tempDHKeysMutex); - - DH *dh_tmp = 0; - - const DHMap::iterator& retVal = _tempDHKeys.find(keyLength); - - // Does the key already exist? - if (retVal != _tempDHKeys.end()) - { - // Yes! Use it. - dh_tmp = (*retVal).second; - } - else - { - const DHParamsMap::iterator& it = _tempDHParamsFileMap.find(keyLength); - - if (it != _tempDHParamsFileMap.end()) - { - DiffieHellmanParamsFile& dhParamsFile = (*it).second; - - string dhFile = dhParamsFile.getFileName(); - - dh_tmp = loadDHParam(dhFile.c_str()); - - if (dh_tmp != 0) - { - _tempDHKeys[keyLength] = dh_tmp; - } - } - } - - METHOD_RET("OpenSSL::System::getDHParams()"); - - return dh_tmp; -} - -// -// Protected -// - -IceSecurity::Ssl::OpenSSL::System::System(string& systemID) : - IceSecurity::Ssl::System(systemID) -{ - _configLoaded = false; - - _sessionContext = "iceServer"; - - _sslServerContext = 0; - _sslClientContext = 0; - - SSL_load_error_strings(); - - OpenSSL_add_ssl_algorithms(); -} - -IceSecurity::Ssl::OpenSSL::System::~System() -{ - METHOD_INV("OpenSSL::~System()"); - - shutdown(); - - METHOD_RET("OpenSSL::~System()"); -} - -// -// Private -// - -void -IceSecurity::Ssl::OpenSSL::System::initClient(GeneralConfig& general, - CertificateAuthority& certAuth, - BaseCertificates& baseCerts) -{ - METHOD_INV("OpenSSL::System::initClient()"); - - // Init the Random Number System. - initRandSystem(general.getRandomBytesFiles()); - - // Create an SSL Context based on the context params. - _sslClientContext = createContext(general.getProtocol()); - - // Begin setting up the SSL Context. - if (_sslClientContext != 0) - { - // Get the cipherlist and set it in the context. - setCipherList(_sslClientContext, general.getCipherList()); - - // Set the certificate verification mode. - SSL_CTX_set_verify(_sslClientContext, general.getVerifyMode(), verifyCallback); - - // Set the certificate verify depth to 10 deep. - SSL_CTX_set_verify_depth(_sslClientContext, general.getVerifyDepth()); - - // Process the RSA Certificate (if present). - if (baseCerts.getRSACert().getKeySize() != 0) - { - processCertificate(_sslClientContext, baseCerts.getRSACert()); - } - - // Process the DSA Certificate (if present). - if (baseCerts.getDSACert().getKeySize() != 0) - { - processCertificate(_sslClientContext, baseCerts.getDSACert()); - } - - // Set the DH key agreement parameters. - if (baseCerts.getDHParams().getKeySize() != 0) - { - setDHParams(_sslClientContext, baseCerts); - } - - // Load the Certificate Authority files, and check them. - loadCAFiles(_sslClientContext, certAuth); - } - - METHOD_RET("OpenSSL::System::initClient()"); -} - -void -IceSecurity::Ssl::OpenSSL::System::initServer(GeneralConfig& general, - CertificateAuthority& certAuth, - BaseCertificates& baseCerts, - TempCertificates& tempCerts) -{ - METHOD_INV("OpenSSL::System::initServer()"); - - // Init the Random Number System. - initRandSystem(general.getRandomBytesFiles()); - - // Create an SSL Context based on the context params. - _sslServerContext = createContext(general.getProtocol()); - - // Begin setting up the SSL Context. - if (_sslServerContext != 0) - { - // On servers, Attempt to use non-export (strong) encryption - // first. This option does not always work, and in the OpenSSL - // documentation is declared as 'broken'. - // SSL_CTX_set_options(_sslServerContext,SSL_OP_NON_EXPORT_FIRST); - - // Always use a new DH key when using Diffie-Hellman key agreement. - SSL_CTX_set_options(_sslServerContext, SSL_OP_SINGLE_DH_USE); - - loadTempCerts(tempCerts); - - // Load the Certificate Authority files, and check them. - loadAndCheckCAFiles(_sslServerContext, certAuth); - - // Process the RSA Certificate (if present). - if (baseCerts.getRSACert().getKeySize() != 0) - { - processCertificate(_sslServerContext, baseCerts.getRSACert()); - } - - // Process the DSA Certificate (if present). - if (baseCerts.getDSACert().getKeySize() != 0) - { - processCertificate(_sslServerContext, baseCerts.getDSACert()); - } - - // Set the DH key agreement parameters. - if (baseCerts.getDHParams().getKeySize() != 0) - { - setDHParams(_sslServerContext, baseCerts); - } - - // Set the RSA Callback routine in case we need to build a temporary RSA key. - SSL_CTX_set_tmp_rsa_callback(_sslServerContext, tmpRSACallback); - - // Set the DH Callback routine in case we need a temporary DH key. - SSL_CTX_set_tmp_dh_callback(_sslServerContext, tmpDHCallback); - - // Get the cipherlist and set it in the context. - setCipherList(_sslServerContext, general.getCipherList()); - - // Set the certificate verification mode. - SSL_CTX_set_verify(_sslServerContext, general.getVerifyMode(), verifyCallback); - - // Set the certificate verify depth - SSL_CTX_set_verify_depth(_sslServerContext, general.getVerifyDepth()); - - // Set the default context for the SSL system (can be overridden if needed) [SERVER ONLY]. - SSL_CTX_set_session_id_context(_sslServerContext, - reinterpret_cast<const unsigned char *>(_sessionContext.c_str()), - _sessionContext.size()); - } - - printContextInfo(_sslServerContext); - - METHOD_RET("OpenSSL::System::initServer()"); -} - -SSL_METHOD* -IceSecurity::Ssl::OpenSSL::System::getSslMethod(SslProtocol sslVersion) -{ - METHOD_INV("OpenSSL::System::getSslMethod()"); - - SSL_METHOD* sslMethod = 0; - - switch (sslVersion) - { - case SSL_V2 : - { - sslMethod = SSLv2_method(); - break; - } - - case SSL_V23 : - { - sslMethod = SSLv23_method(); - break; - } - - case SSL_V3 : - { - sslMethod = SSLv3_method(); - break; - } - - case TLS_V1 : - { - sslMethod = TLSv1_method(); - break; - } - - default : - { - string errorString; - - errorString = "SSL Version "; - errorString += sslVersion; - errorString += " not supported."; - - EXCEPTION(errorString); - - throw ContextException(errorString.c_str(), __FILE__, __LINE__); - } - } - - METHOD_RET("OpenSSL::System::getSslMethod()"); - - return sslMethod; -} - -void -IceSecurity::Ssl::OpenSSL::System::processCertificate(SSL_CTX* sslContext, const CertificateDesc& certificateDesc) -{ - METHOD_INV("OpenSSL::System::processCertificate()"); - - const CertificateFile& publicCert = certificateDesc.getPublic(); - const CertificateFile& privateKey = certificateDesc.getPrivate(); - - addKeyCert(sslContext, publicCert, privateKey); - - METHOD_RET("OpenSSL::System::processCertificate()"); -} - -void -IceSecurity::Ssl::OpenSSL::System::addKeyCert(SSL_CTX* sslContext, - const CertificateFile& publicCert, - const CertificateFile& privateKey) -{ - METHOD_INV("OpenSSL::System::addKeyCert()"); - - if (!publicCert.getFileName().empty()) - { - string publicCertFile = publicCert.getFileName(); - const char* publicFile = publicCertFile.c_str(); - int publicEncoding = publicCert.getEncoding(); - - string privCertFile = privateKey.getFileName(); - const char* privKeyFile = privCertFile.c_str(); - int privKeyFileType = privateKey.getEncoding(); - - // Set which Public Key file to use. - if (SSL_CTX_use_certificate_file(sslContext, publicFile, publicEncoding) <= 0) - { - string errorString; - - errorString = "Unable to get certificate from '"; - errorString += publicFile; - errorString += "'\n"; - errorString += sslGetErrors(); - - EXCEPTION(errorString); - - throw ContextException(errorString.c_str(), __FILE__, __LINE__); - } - - if (privateKey.getFileName().empty()) - { - WARNING("No Private Key specified - using the certificate."); - - privKeyFile = publicFile; - privKeyFileType = publicEncoding; - } - - // Set which Private Key file to use. - if (SSL_CTX_use_PrivateKey_file(sslContext, privKeyFile, privKeyFileType) <= 0) - { - string errorString; - - errorString = "unable to get private key from '"; - errorString += privKeyFile; - errorString += "'\n"; - errorString += sslGetErrors(); - - EXCEPTION(errorString); - - throw ContextException(errorString.c_str(), __FILE__, __LINE__); - } - - // Check to see if the Private and Public keys that have been - // set against the SSL context match up. - if (!SSL_CTX_check_private_key(sslContext)) - { - string errorString = "Private key does not match the certificate public key"; - - EXCEPTION(errorString); - - throw ContextException(errorString.c_str(), __FILE__, __LINE__); - } - - } - - METHOD_RET("OpenSSL::System::addKeyCert()"); -} - - -SSL_CTX* -IceSecurity::Ssl::OpenSSL::System::createContext(SslProtocol sslProtocol) -{ - METHOD_INV("OpenSSL::System::createContext()"); - - SSL_CTX* context = SSL_CTX_new(getSslMethod(sslProtocol)); - - if (context == 0) - { - string errorString = "Unable to create SSL Context."; - - EXCEPTION(errorString); - - throw ContextException(errorString.c_str(), __FILE__, __LINE__); - } - - METHOD_RET("OpenSSL::System::createContext()"); - - return context; -} - - -// -// TODO: Clean this up. This routine is pretty much ripped off from the OpenSSL -// routine ERR_print_errors_fp(), except we got rid of the file pointer. -// -string -IceSecurity::Ssl::OpenSSL::System::sslGetErrors() -{ - METHOD_INV("OpenSSL::System::sslGetErrors()"); - - string errorMessage; - char buf[200], bigBuffer[1024]; - const char* file; - const char* data = 0; - int line, flags; - - unsigned long es = CRYPTO_thread_id(); - - while ((line = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) - { - // Request an error from the OpenSSL library - ERR_error_string_n(line, buf, sizeof(buf)); - - sprintf(bigBuffer,"%lu:%s:%s:%d:%s\n",es,buf,file,line,(flags&ERR_TXT_STRING)?data:""); - - errorMessage += bigBuffer; - } - - METHOD_RET("OpenSSL::System::sslGetErrors()"); - - return errorMessage; -} - -SSL* -IceSecurity::Ssl::OpenSSL::System::createConnection(SSL_CTX* sslContext, int socket) -{ - METHOD_INV("OpenSSL::System::createConnection()"); - - SSL *sslConnection = 0; - - sslConnection = SSL_new(sslContext); - - SSL_clear(sslConnection); - - SSL_set_fd(sslConnection, socket); - - if (SECURITY_LEVEL_PROTOCOL_DEBUG) - { - sslConnection->debug = 1; - BIO_set_callback(SSL_get_rbio(sslConnection), bio_dump_cb); - BIO_set_callback_arg(SSL_get_rbio(sslConnection), 0); - BIO_set_callback(SSL_get_wbio(sslConnection), bio_dump_cb); - BIO_set_callback_arg(SSL_get_rbio(sslConnection), 0); - } - - // Map the SSL Connection to this SslSystem - // This is required for the OpenSSL callbacks - // to work properly. - Factory::addSystemHandle(sslConnection, this); - - METHOD_RET("OpenSSL::System::createConnection()"); - - return sslConnection; -} - -void -IceSecurity::Ssl::OpenSSL::System::loadCAFiles(SSL_CTX* sslContext, CertificateAuthority& certAuth) -{ - METHOD_INV("OpenSSL::System::loadCAFiles()"); - - string caFile = certAuth.getCAFileName(); - string caPath = certAuth.getCAPath(); - - loadCAFiles(sslContext, caFile.c_str(), caPath.c_str()); - - METHOD_RET("OpenSSL::System::loadCAFiles()"); -} - -void -IceSecurity::Ssl::OpenSSL::System::loadCAFiles(SSL_CTX* sslContext, const char* caFile, const char* caPath) -{ - METHOD_INV("OpenSSL::System::loadCAFiles()"); - - if (sslContext != 0) - { - // The following checks are required to send the expected values to the OpenSSL library. - // It does not like receiving "", but prefers NULLs. - if ((caFile != 0) && (strlen(caFile) == 0)) - { - caFile = 0; - } - - if ((caPath != 0) && (strlen(caPath) == 0)) - { - caPath = 0; - } - - // Check the Certificate Authority file(s). - if ((!SSL_CTX_load_verify_locations(sslContext, caFile, caPath)) || - (!SSL_CTX_set_default_verify_paths(sslContext))) - { - // Non Fatal. - WARNING("Unable to load/verify Certificate Authorities."); - } - } - - METHOD_RET("OpenSSL::System::loadCAFiles()"); -} - -void -IceSecurity::Ssl::OpenSSL::System::loadAndCheckCAFiles(SSL_CTX* sslContext, CertificateAuthority& certAuth) -{ - METHOD_INV("OpenSSL::System::loadAndCheckCAFiles()"); - - if (sslContext != 0) - { - string caFile = certAuth.getCAFileName(); - string caPath = certAuth.getCAPath(); - - // Check the Certificate Authority file(s). - loadCAFiles(sslContext, caFile.c_str(), caPath.c_str()); - - if (!caPath.empty()) - { - STACK_OF(X509_NAME)* certNames = SSL_load_client_CA_file(caFile.c_str()); - - if (certNames != 0) - { - SSL_CTX_set_client_CA_list(sslContext, certNames); - } - else - { - WARNING("Unable to set SSL context Certificate Authorities."); - } - } - } - - METHOD_RET("OpenSSL::System::loadAndCheckCAFiles()"); -} - -DH* -IceSecurity::Ssl::OpenSSL::System::loadDHParam(const char* dhfile) -{ - METHOD_INV(string("OpenSSL::System::loadDHParam(") + dhfile + string(")")); - - DH* ret = 0; - BIO* bio; - - if ((bio = BIO_new_file(dhfile,"r")) != 0) - { - ret = PEM_read_bio_DHparams(bio, 0, 0, 0); - } - - if (bio != 0) - { - BIO_free(bio); - } - - METHOD_RET(string("OpenSSL::System::loadDHParam(") + dhfile + string(")")); - - return ret; -} - -DH* -IceSecurity::Ssl::OpenSSL::System::getTempDH(unsigned char* p, int plen, unsigned char* g, int glen) -{ - METHOD_INV("OpenSSL::System::getTempDH()"); - - DH* dh = 0; - - if ((dh = DH_new()) != 0) - { - dh->p = BN_bin2bn(p, plen, 0); - - dh->g = BN_bin2bn(g, glen, 0); - - if ((dh->p == 0) || (dh->g == 0)) - { - DH_free(dh); - dh = 0; - } - } - - METHOD_RET("OpenSSL::System::getTempDH()"); - - return dh; -} - -DH* -IceSecurity::Ssl::OpenSSL::System::getTempDH512() -{ - METHOD_INV("OpenSSL::System::getTempDH512()"); - - DH* dh = getTempDH(_tempDiffieHellman512p, sizeof(_tempDiffieHellman512p), - _tempDiffieHellman512g, sizeof(_tempDiffieHellman512g)); - - METHOD_RET("OpenSSL::System::getTempDH512()"); - - return dh; -} - -void -IceSecurity::Ssl::OpenSSL::System::setDHParams(SSL_CTX* sslContext, BaseCertificates& baseCerts) -{ - METHOD_INV("OpenSSL::System::setDHParams()"); - - string dhFile; - int encoding = 0; - - if (baseCerts.getDHParams().getKeySize() != 0) - { - dhFile = baseCerts.getDHParams().getFileName(); - encoding = baseCerts.getDHParams().getEncoding(); - } - else if (baseCerts.getRSACert().getKeySize() != 0) - { - dhFile = baseCerts.getRSACert().getPublic().getFileName(); - encoding = baseCerts.getRSACert().getPublic().getEncoding(); - } - - DH* dh = 0; - - // File type must be PEM - that's the only way we can load - // DH Params, apparently. - if ((!dhFile.empty()) && (encoding == SSL_FILETYPE_PEM)) - { - dh = loadDHParam(dhFile.c_str()); - } - - if (dh == 0) - { - WARNING("Could not load Diffie-Hellman params, generating a temporary 512bit key."); - - dh = getTempDH512(); - } - - if (dh != 0) - { - SSL_CTX_set_tmp_dh(sslContext, dh); - - DH_free(dh); - } - - METHOD_RET("OpenSSL::System::setDHParams()"); -} - -void -IceSecurity::Ssl::OpenSSL::System::setCipherList(SSL_CTX* sslContext, const string& cipherList) -{ - METHOD_INV("OpenSSL::System::setCipherList()"); - - if (!cipherList.empty() && (!SSL_CTX_set_cipher_list(sslContext, cipherList.c_str()))) - { - string errorString = "Error setting cipher list."; - - EXCEPTION(errorString); - - throw ContextException(errorString.c_str(), __FILE__, __LINE__); - } - - METHOD_RET("OpenSSL::System::setCipherList()"); -} - -int -IceSecurity::Ssl::OpenSSL::System::seedRand() -{ - METHOD_INV("OpenSSL::System::seedRand()"); - - int retCode = 1; - char buffer[1024]; - -#ifdef WINDOWS - RAND_screen(); -#endif - - const char* file = RAND_file_name(buffer, sizeof(buffer)); - - if (file == 0 || !RAND_load_file(file, -1)) - { - retCode = 0; - } - else - { - _randSeeded = 1; - } - - METHOD_RET("OpenSSL::System::seedRand()"); - - return retCode; -} - -long -IceSecurity::Ssl::OpenSSL::System::loadRandFiles(const string& names) -{ - METHOD_INV("OpenSSL::System::loadRandFiles(" + names + ")"); - - long tot = 0; - - if (!names.empty()) - { - int egd; - - // Make a modifiable copy of the string. - char* namesString = new char[names.length() + 1]; - strcpy(namesString, names.c_str()); - - char seps[5]; - - sprintf(seps, "%c", LIST_SEPARATOR_CHAR); - - char* token = strtok(namesString, seps); - - while (token != 0) - { - egd = RAND_egd(token); - - if (egd > 0) - { - tot += egd; - } - else - { - tot += RAND_load_file(token, -1); - } - - token = strtok(0, seps); - } - - if (tot > 512) - { - _randSeeded = 1; - } - - delete []namesString; - } - - METHOD_RET("OpenSSL::System::loadRandFiles(" + names + ")"); - - return tot; -} - -void -IceSecurity::Ssl::OpenSSL::System::initRandSystem(const string& randBytesFiles) -{ - METHOD_INV("OpenSSL::System::initRandSystem(" + randBytesFiles + ")"); - - if (!_randSeeded) - { - long randBytesLoaded = 0; - - if (!seedRand() && randBytesFiles.empty() && !RAND_status()) - { - WARNING("There is a lack of random data, consider specifying a random data file."); - } - - if (!randBytesFiles.empty()) - { - randBytesLoaded = loadRandFiles(randBytesFiles); - } - } - - METHOD_RET("OpenSSL::System::initRandSystem(" + randBytesFiles + ")"); -} - -void -IceSecurity::Ssl::OpenSSL::System::loadTempCerts(TempCertificates& tempCerts) -{ - METHOD_INV("OpenSSL::System::loadTempCerts()"); - - RSAVector::iterator iRSA = tempCerts.getRSACerts().begin(); - RSAVector::iterator eRSA = tempCerts.getRSACerts().end(); - - while (iRSA != eRSA) - { - _tempRSAFileMap[(*iRSA).getKeySize()] = *iRSA; - iRSA++; - } - - DSAVector::iterator iDSA = tempCerts.getDSACerts().begin(); - DSAVector::iterator eDSA = tempCerts.getDSACerts().end(); - - while (iDSA != eDSA) - { - _tempDSAFileMap[(*iDSA).getKeySize()] = *iDSA; - iDSA++; - } - - DHVector::iterator iDHP = tempCerts.getDHParams().begin(); - DHVector::iterator eDHP = tempCerts.getDHParams().end(); - - while (iDHP != eDHP) - { - _tempDHParamsFileMap[(*iDHP).getKeySize()] = *iDHP; - iDHP++; - } - - METHOD_RET("OpenSSL::System::loadTempCerts()"); -} +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+#ifdef WIN32
+#pragma warning(disable:4786)
+#endif
+
+#include <sstream>
+#include <openssl/err.h>
+#include <openssl/e_os.h>
+#include <openssl/rand.h>
+#include <Ice/Security.h>
+#include <Ice/SslSystem.h>
+#include <Ice/SslException.h>
+#include <Ice/SslConnectionOpenSSLClient.h>
+#include <Ice/SslConnectionOpenSSLServer.h>
+#include <Ice/SslConfig.h>
+
+using namespace std;
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+namespace OpenSSL
+{
+
+//
+// TODO: These Diffie-Hellman params have been blatantly stolen from
+// OpenSSL's demo programs. We SHOULD define our own here, but
+// these will suffice for testing purposes. Please note, these
+// are not keys themselves, simply a DH Group that allows OpenSSL
+// to create Diffie-Hellman keys.
+//
+
+// Instantiation of temporary Diffie-Hellman 512bit key.
+unsigned char System::_tempDiffieHellman512p[] =
+{
+ 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
+ 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
+ 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
+ 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
+ 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
+ 0x47,0x74,0xE8,0x33,
+};
+
+unsigned char System::_tempDiffieHellman512g[] =
+{
+ 0x02,
+};
+
+// TODO: Very possibly a problem later if we have mutliple loggers going on simultaneously.
+// This is a horrible necessity in order to make the trace levels
+// and logger available to the bio_dump_cb() callback function.
+// Otherwise, we would have to jump through hoops, creating a mapping
+// from BIO pointers to the relevent System object. The system object
+// will initialize these. NOTE: If we SHOULD have multiple loggers
+// going on simultaneously, this will definitely cause a problem.
+TraceLevelsPtr System::_globalTraceLevels = 0;
+Ice::LoggerPtr System::_globalLogger = 0;
+
+}
+
+}
+
+}
+
+using IceSecurity::Ssl::OpenSSL::ContextException;
+
+//
+// NOTE: The following (mon, getGeneralizedTime, getUTCTime and getASN1time are routines that
+// have been abducted from the OpenSSL X509 library, and modified to work with the STL
+// basic_string template.
+
+static const char *mon[12]=
+{
+ "Jan","Feb","Mar","Apr","May","Jun",
+ "Jul","Aug","Sep","Oct","Nov","Dec"
+};
+
+string
+getGeneralizedTime(ASN1_GENERALIZEDTIME *tm)
+{
+ char buf[30];
+ char *v;
+ int gmt=0;
+ int i;
+ int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+
+ i = tm->length;
+ v = (char *) tm->data;
+
+ if (i < 12)
+ {
+ goto err;
+ }
+
+ if (v[i-1] == 'Z')
+ {
+ gmt=1;
+ }
+
+ for (i=0; i<12; i++)
+ {
+ if ((v[i] > '9') || (v[i] < '0'))
+ {
+ goto err;
+ }
+ }
+
+ y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 + (v[2] - '0') * 10 + (v[3] - '0');
+ M = (v[4] - '0') * 10 + (v[5] - '0');
+
+ if ((M > 12) || (M < 1))
+ {
+ goto err;
+ }
+
+ d = (v[6] - '0') * 10 + (v[7] - '0');
+ h = (v[8] - '0') * 10 + (v[9] - '0');
+ m = (v[10] - '0') * 10 + (v[11] - '0');
+
+ if ((v[12] >= '0') && (v[12] <= '9') &&
+ (v[13] >= '0') && (v[13] <= '9'))
+ {
+ s = (v[12] - '0') * 10 + (v[13] - '0');
+ }
+
+ sprintf(buf, "%s %2d %02d:%02d:%02d %d%s", mon[M-1], d, h, m, s, y, (gmt)?" GMT":"");
+ return string(buf);
+
+err:
+ return string("Bad time value");
+}
+
+string
+getUTCTime(ASN1_UTCTIME *tm)
+{
+ char buf[30];
+ char *v;
+ int gmt=0;
+ int i;
+ int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+
+ i = tm->length;
+ v = (char *) tm->data;
+
+ if (i < 10)
+ {
+ goto err;
+ }
+
+ if (v[i-1] == 'Z')
+ {
+ gmt=1;
+ }
+
+ for (i = 0; i < 10; i++)
+ {
+ if ((v[i] > '9') || (v[i] < '0'))
+ {
+ goto err;
+ }
+ }
+
+ y = (v[0] - '0') * 10 + (v[1] - '0');
+
+ if (y < 50)
+ {
+ y+=100;
+ }
+
+ M = (v[2] - '0') * 10 + (v[3] - '0');
+
+ if ((M > 12) || (M < 1))
+ {
+ goto err;
+ }
+
+ d = (v[4] - '0') * 10 + (v[5] - '0');
+ h = (v[6] - '0') * 10 + (v[7] - '0');
+ m = (v[8] - '0') * 10 + (v[9] - '0');
+
+ if ((v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9'))
+ {
+ s = (v[10] - '0') * 10 + (v[11] - '0');
+ }
+
+ sprintf(buf, "%s %2d %02d:%02d:%02d %d%s", mon[M-1], d, h, m, s, y+1900, (gmt)?" GMT":"");
+ return string(buf);
+
+err:
+ return string("Bad time value");
+}
+
+string
+getASN1time(ASN1_TIME *tm)
+{
+ string theTime;
+
+ switch (tm->type)
+ {
+ case V_ASN1_UTCTIME :
+ {
+ theTime = getUTCTime(tm);
+ }
+
+ case V_ASN1_GENERALIZEDTIME :
+ {
+ theTime = getGeneralizedTime(tm);
+ }
+
+ default :
+ {
+ theTime = "Bad time value";
+ }
+ }
+
+ return theTime;
+}
+
+extern "C"
+{
+
+RSA*
+tmpRSACallback(SSL *s, int isExport, int keyLength)
+{
+ IceSecurity::Ssl::System* sslSystem = IceSecurity::Ssl::Factory::getSystemFromHandle(s);
+
+ IceSecurity::Ssl::OpenSSL::System* openSslSystem = dynamic_cast<IceSecurity::Ssl::OpenSSL::System*>(sslSystem);
+
+ RSA* rsaKey = openSslSystem->getRSAKey(s, isExport, keyLength);
+
+ IceSecurity::Ssl::Factory::releaseSystemFromHandle(s, sslSystem);
+
+ return rsaKey;
+}
+
+DH*
+tmpDHCallback(SSL *s, int isExport, int keyLength)
+{
+ IceSecurity::Ssl::System* sslSystem = IceSecurity::Ssl::Factory::getSystemFromHandle(s);
+
+ IceSecurity::Ssl::OpenSSL::System* openSslSystem = dynamic_cast<IceSecurity::Ssl::OpenSSL::System*>(sslSystem);
+
+ DH* dh = openSslSystem->getDHParams(s, isExport, keyLength);
+
+ IceSecurity::Ssl::Factory::releaseSystemFromHandle(s, sslSystem);
+
+ return dh;
+}
+
+// verifyCallback - Certificate Verification callback function.
+int
+verifyCallback(int ok, X509_STORE_CTX *ctx)
+{
+ X509* err_cert = X509_STORE_CTX_get_current_cert(ctx);
+ int verifyError = X509_STORE_CTX_get_error(ctx);
+ int depth = X509_STORE_CTX_get_error_depth(ctx);
+
+ // If we have no errors so far, and the certificate chain is too long
+ if ((verifyError != X509_V_OK) && (10 < depth))
+ {
+ verifyError = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+ }
+
+ if (verifyError != X509_V_OK)
+ {
+ // If we have ANY errors, we bail out.
+ ok = 0;
+ }
+
+ // Only if ICE_PROTOCOL level logging is on do we worry about this.
+// if (IceSecurity::Ssl::OpenSSL::System::_globalTraceLevels->security >= IceSecurity::SECURITY_PROTOCOL)
+ if (ICE_SECURITY_LEVEL_PROTOCOL_GLOBAL)
+ {
+ char buf[256];
+
+ X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
+
+ ostringstream outStringStream;
+
+ outStringStream << "depth = " << depth << ":" << buf << endl;
+
+ if (!ok)
+ {
+ 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(ctx->current_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(ctx->current_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(ctx->current_cert)) << endl;
+ break;
+ }
+ }
+
+ outStringStream << "verify return = " << ok << endl;
+
+ IceSecurity::Ssl::OpenSSL::System::_globalLogger->trace(IceSecurity::Ssl::OpenSSL::System::_globalTraceLevels->securityCat, outStringStream.str());
+ }
+
+ return ok;
+}
+
+// This code duplicates functionality that existed in the BIO library of
+// OpenSSL, but outputs to a Logger compatible source (ostringstream).
+void
+dump(ostringstream& outStringStream, const char* s, int len)
+{
+ unsigned char ch;
+ char hexStr[8];
+
+ int trunc = 0;
+
+ // Calculate how much white space we're truncating.
+ for(; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
+ {
+ trunc++;
+ }
+
+ int dump_width = 12;
+
+ int rows = len / dump_width;
+
+ if ((rows * dump_width) < len)
+ {
+ rows++;
+ }
+
+ if (rows > 0)
+ {
+ outStringStream << endl;
+ }
+
+ for(int i = 0; i < rows; i++)
+ {
+ // Would like to have not used sprintf(), but
+ // I could not find an appropriate STL methodology
+ // for preserving the field width.
+ sprintf(hexStr,"%04x",(i * dump_width));
+ outStringStream << hexStr << " - ";
+
+ int j;
+
+ // Hex Dump
+ for(j = 0; j < dump_width; j++)
+ {
+ if (((i * dump_width) + j) >= len)
+ {
+ outStringStream << " ";
+ }
+ else
+ {
+ char sep = (j == 7 ? '-' : ' ');
+
+ // Get a character from the dump we've been handed.
+ ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
+
+ // Would like to have not used sprintf(), but
+ // I could not find an appropriate STL methodology
+ // for preserving the field width.
+ sprintf(hexStr,"%02x",ch);
+ outStringStream << hexStr << sep;
+ }
+ }
+
+ outStringStream << " ";
+
+ // Printable characters dump.
+ for(j = 0; j < dump_width; j++)
+ {
+ if (((i * dump_width) + j) >= len)
+ {
+ break;
+ }
+
+ ch = ((unsigned char) * (s + i * dump_width + j)) & 0xff;
+
+ // Print printables only.
+ ch = ((ch >= ' ') && (ch <= '~')) ? ch : '.';
+
+ outStringStream << ch;
+ }
+
+ outStringStream << endl;
+ }
+
+ if (trunc > 0)
+ {
+ outStringStream << hex << (len + trunc) << " - " << "<SPACES/NULS>" << endl;
+ }
+}
+
+long
+bio_dump_cb(BIO *bio, int cmd, const char *argp, int argi, long argl, long ret)
+{
+ if (IceSecurity::Ssl::OpenSSL::System::_globalTraceLevels->security >= IceSecurity::SECURITY_PROTOCOL)
+ {
+ ostringstream outStringStream;
+
+ if (cmd == (BIO_CB_READ|BIO_CB_RETURN))
+ {
+ outStringStream << "PTC ";
+ outStringStream << "read from " << hex << (void *)bio << " [" << hex << (void *)argp;
+ outStringStream << "] (" << dec << argi << " bytes => " << ret << " (0x";
+ outStringStream << hex << ret << "))";
+ dump(outStringStream, argp,(int)ret);
+ }
+ else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
+ {
+ outStringStream << "PTC ";
+ outStringStream << "write to " << hex << (void *)bio << " [" << hex << (void *)argp;
+ outStringStream << "] (" << dec << argi << " bytes => " << ret << " (0x";
+ outStringStream << hex << ret << "))";
+ dump(outStringStream, argp,(int)ret);
+ }
+
+ if (cmd == (BIO_CB_READ|BIO_CB_RETURN) || cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
+ {
+ IceSecurity::Ssl::OpenSSL::System::_globalLogger->trace(IceSecurity::Ssl::OpenSSL::System::_globalTraceLevels->securityCat, outStringStream.str());
+ }
+ }
+
+ return ret;
+}
+
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::printContextInfo(SSL_CTX* context)
+{
+ if (ICE_SECURITY_LEVEL_PROTOCOL)
+ {
+ ostringstream s;
+
+ s << endl;
+ s << "SSL_CTX Structure" << endl;
+ s << "=================" << endl;
+ s << "options: 0x" << hex << context->options << endl;
+ s << "mode: 0x" << hex << context->mode << endl;
+
+ s << "session_cache_size: " << context->session_cache_size << endl;
+ s << "session_cache_mode: 0x" << hex << context->session_cache_mode << endl;
+ s << "session_timeout: " << Int(context->session_timeout) << endl << endl;
+
+ s << "Stats" << endl;
+ s << "Connect: " << context->stats.sess_connect << " (New Connect Started)" << endl;
+ s << "Renegotiate: " << context->stats.sess_connect_renegotiate << " (Renegotiation Requested)" << endl;
+ s << "Connect Good: " << context->stats.sess_connect_good << " (Connect/Renegotiation finished)";
+ s << endl << endl;
+
+ s << "Accept: " << context->stats.sess_accept << " (New Accept Started)" << endl;
+ s << "Renegotiate: " << context->stats.sess_accept_renegotiate << " (Renegotiation Requested)" << endl;
+ s << "Accept Good: " << context->stats.sess_accept_good << " (Accept/Renegotiation finished)";
+ s << endl << endl;
+
+ s << "Miss: " << context->stats.sess_miss << " (Session Lookup Misses)" << endl;
+ s << "Timeout: " << context->stats.sess_timeout << " (Reuse attempt on Timeouted Session)" << endl;
+ s << "Cache Full: " << context->stats.sess_cache_full << " (Session Removed due to full cache)" << endl;
+ s << "Hit: " << context->stats.sess_hit << " (Session Reuse actually done.)" << endl;
+ s << "CB Hit: " << context->stats.sess_cb_hit << " (Session ID supplied by Callback)" << endl;
+
+ s << "read_ahead: " << context->read_ahead << endl;
+ s << "verify_mode: 0x" << hex << context->verify_mode << endl;
+ s << "verify_depth: " << Int(context->verify_depth) << endl;
+
+ ICE_PROTOCOL(s.str());
+ }
+}
+
+IceSecurity::Ssl::Connection*
+IceSecurity::Ssl::OpenSSL::System::createServerConnection(int socket)
+{
+ ICE_METHOD_INV("OpenSSL::System::createServerConnection()");
+
+ SSL* sslConnection = createConnection(_sslServerContext, socket);
+
+ // Set the Accept Connection state for this connection.
+ SSL_set_accept_state(sslConnection);
+
+ Connection* connection = new ServerConnection(sslConnection, _systemID);
+
+ connection->setTrace(_traceLevels);
+ connection->setLogger(_logger);
+
+ continueInit:
+ try
+ {
+ while (!connection->init()) { }
+ }
+ catch (const TimeoutException&)
+ {
+ // Ignore, this might happen a lot during handshake.
+ goto continueInit;
+ }
+ catch (...)
+ {
+ if (connection != 0)
+ {
+ delete connection;
+ connection = 0;
+ }
+
+ throw;
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::createServerConnection()");
+
+ return connection;
+}
+
+IceSecurity::Ssl::Connection*
+IceSecurity::Ssl::OpenSSL::System::createClientConnection(int socket)
+{
+ ICE_METHOD_INV("OpenSSL::System::createClientConnection()");
+
+ SSL* sslConnection = createConnection(_sslClientContext, socket);
+
+ // Set the Connect Connection state for this connection.
+ SSL_set_connect_state(sslConnection);
+
+ Connection* connection = new ClientConnection(sslConnection, _systemID);
+
+ connection->setTrace(_traceLevels);
+ connection->setLogger(_logger);
+
+ continueInit:
+ try
+ {
+ while (!connection->init()) { }
+ }
+ catch (const TimeoutException&)
+ {
+ // Ignore, this might happen a lot during handshake.
+ goto continueInit;
+ }
+ catch (...)
+ {
+ if (connection != 0)
+ {
+ delete connection;
+ connection = 0;
+ }
+
+ throw;
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::createClientConnection()");
+
+ return connection;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::shutdown()
+{
+ ICE_METHOD_INV("OpenSSL::System::shutdown()");
+
+ if (_sslServerContext != 0)
+ {
+ SSL_CTX_free(_sslServerContext);
+
+ _sslServerContext = 0;
+ }
+
+ if (_sslClientContext != 0)
+ {
+ SSL_CTX_free(_sslClientContext);
+
+ _sslClientContext = 0;
+ }
+
+ // Free our temporary RSA keys.
+ RSAMap::iterator iRSA = _tempRSAKeys.begin();
+ RSAMap::iterator eRSA = _tempRSAKeys.end();
+
+ while (iRSA != eRSA)
+ {
+ RSA_free((*iRSA).second);
+ iRSA++;
+ }
+
+ // Free our temporary DH params.
+ DHMap::iterator iDH = _tempDHKeys.begin();
+ DHMap::iterator eDH = _tempDHKeys.end();
+
+ while (iDH != eDH)
+ {
+ DH_free((*iDH).second);
+ iDH++;
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::shutdown()");
+}
+
+bool
+IceSecurity::Ssl::OpenSSL::System::isConfigLoaded()
+{
+ ICE_METHOD_INS("OpenSSL::System::isConfigLoaded()");
+
+ return _configLoaded;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::loadConfig()
+{
+ ICE_METHOD_INV("OpenSSL::System::loadConfig()");
+
+ // This step is required in order to supply callback functions
+ // with access to the TraceLevels and Logger.
+ if (_globalTraceLevels == 0)
+ {
+ _globalTraceLevels = _traceLevels;
+ _globalLogger = _logger;
+ }
+
+ // TODO: Get the Path and File properly here.
+ string configFile = _properties->getProperty("Ice.Ssl.Config");
+ string certificatePath = _properties->getProperty("Ice.Ssl.CertPath");
+ Parser sslConfig(configFile, certificatePath);
+
+ // const string& systemID = getSystemID();
+ // Parser sslConfig(systemID);
+
+ sslConfig.setTrace(_traceLevels);
+ sslConfig.setLogger(_logger);
+
+ // Actually parse the file now.
+ sslConfig.process();
+
+ GeneralConfig clientGeneral;
+ CertificateAuthority clientCertAuth;
+ BaseCertificates clientBaseCerts;
+
+ // Walk the parse tree, get the Client configuration.
+ if (sslConfig.loadClientConfig(clientGeneral, clientCertAuth, clientBaseCerts))
+ {
+ if (ICE_SECURITY_LEVEL_PROTOCOL)
+ {
+ ostringstream s;
+
+ s << endl;
+ s << "General Configuration - Client" << endl;
+ s << "------------------------------" << endl;
+ s << clientGeneral << endl << endl;
+
+ s << "Base Certificates - Client" << endl;
+ s << "--------------------------" << endl;
+ s << clientBaseCerts << endl;
+
+ ICE_PROTOCOL(s.str());
+ }
+
+ initClient(clientGeneral, clientCertAuth, clientBaseCerts);
+ }
+
+ GeneralConfig serverGeneral;
+ CertificateAuthority serverCertAuth;
+ BaseCertificates serverBaseCerts;
+ TempCertificates serverTempCerts;
+
+ // Walk the parse tree, get the Server configuration.
+ if (sslConfig.loadServerConfig(serverGeneral, serverCertAuth, serverBaseCerts, serverTempCerts))
+ {
+ if (ICE_SECURITY_LEVEL_PROTOCOL)
+ {
+ ostringstream s;
+
+ s << endl;
+ s << "General Configuration - Server" << endl;
+ s << "------------------------------" << endl;
+ s << serverGeneral << endl << endl;
+
+ s << "Base Certificates - Server" << endl;
+ s << "--------------------------" << endl;
+ s << serverBaseCerts << endl << endl;
+
+ s << "Temp Certificates - Server" << endl;
+ s << "--------------------------" << endl;
+ s << serverTempCerts << endl;
+
+ ICE_PROTOCOL(s.str());
+ }
+
+ initServer(serverGeneral, serverCertAuth, serverBaseCerts, serverTempCerts);
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::loadConfig()");
+}
+
+RSA*
+IceSecurity::Ssl::OpenSSL::System::getRSAKey(SSL *s, int isExport, int keyLength)
+{
+ ICE_METHOD_INV("OpenSSL::System::getRSAKey()");
+
+ JTCSyncT<JTCMutex> sync(_tempRSAKeysMutex);
+
+ RSA* rsa_tmp = 0;
+
+ RSAMap::iterator retVal = _tempRSAKeys.find(keyLength);
+
+ // Does the key already exist?
+ if (retVal != _tempRSAKeys.end())
+ {
+ // Yes! Use it.
+ rsa_tmp = (*retVal).second;
+ }
+ else
+ {
+ const RSACertMap::iterator& it = _tempRSAFileMap.find(keyLength);
+
+ if (it != _tempRSAFileMap.end())
+ {
+ CertificateDesc& rsaKeyCert = (*it).second;
+
+ const string& privKeyFile = rsaKeyCert.getPrivate().getFileName();
+ const string& pubCertFile = rsaKeyCert.getPublic().getFileName();
+
+ RSA* rsaCert = 0;
+ RSA* rsaKey = 0;
+ BIO* bio = 0;
+
+ if ((bio = BIO_new_file(pubCertFile.c_str(), "r")) != 0)
+ {
+ rsaCert = PEM_read_bio_RSAPublicKey(bio, 0, 0, 0);
+
+ BIO_free(bio);
+ bio = 0;
+ }
+
+ if (rsaCert != 0)
+ {
+ if ((bio = BIO_new_file(privKeyFile.c_str(), "r")) != 0)
+ {
+ rsaKey = PEM_read_bio_RSAPrivateKey(bio, &rsaCert, 0, 0);
+
+ BIO_free(bio);
+ bio = 0;
+ }
+ }
+
+ // Now, if all was well, the Certificate and Key should both be loaded into
+ // rsaCert. We check to ensure that both are not 0, because if either are,
+ // one of the reads failed.
+
+ if ((rsaCert != 0) && (rsaKey != 0))
+ {
+ rsa_tmp = rsaCert;
+ }
+ else
+ {
+ RSA_free(rsaCert);
+ rsaCert = 0;
+ }
+ }
+
+ // Last ditch effort - generate a key on the fly.
+ if (rsa_tmp == 0)
+ {
+ rsa_tmp = RSA_generate_key(keyLength, RSA_F4, 0, 0);
+ }
+
+ // Save in our temporary key cache.
+ if (rsa_tmp == 0)
+ {
+ _tempRSAKeys[keyLength] = rsa_tmp;
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::getRSAKey()");
+
+ return rsa_tmp;
+}
+
+DH*
+IceSecurity::Ssl::OpenSSL::System::getDHParams(SSL *s, int isExport, int keyLength)
+{
+ ICE_METHOD_INV("OpenSSL::System::getDHParams()");
+
+ JTCSyncT<JTCMutex> sync(_tempDHKeysMutex);
+
+ DH *dh_tmp = 0;
+
+ const DHMap::iterator& retVal = _tempDHKeys.find(keyLength);
+
+ // Does the key already exist?
+ if (retVal != _tempDHKeys.end())
+ {
+ // Yes! Use it.
+ dh_tmp = (*retVal).second;
+ }
+ else
+ {
+ const DHParamsMap::iterator& it = _tempDHParamsFileMap.find(keyLength);
+
+ if (it != _tempDHParamsFileMap.end())
+ {
+ DiffieHellmanParamsFile& dhParamsFile = (*it).second;
+
+ string dhFile = dhParamsFile.getFileName();
+
+ dh_tmp = loadDHParam(dhFile.c_str());
+
+ if (dh_tmp != 0)
+ {
+ _tempDHKeys[keyLength] = dh_tmp;
+ }
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::getDHParams()");
+
+ return dh_tmp;
+}
+
+//
+// Protected
+//
+
+IceSecurity::Ssl::OpenSSL::System::System(string& systemID) :
+ IceSecurity::Ssl::System(systemID)
+{
+ _configLoaded = false;
+
+ _sessionContext = "iceServer";
+
+ _sslServerContext = 0;
+ _sslClientContext = 0;
+
+ SSL_load_error_strings();
+
+ OpenSSL_add_ssl_algorithms();
+}
+
+IceSecurity::Ssl::OpenSSL::System::~System()
+{
+ ICE_METHOD_INV("OpenSSL::~System()");
+
+ shutdown();
+
+ ICE_METHOD_RET("OpenSSL::~System()");
+}
+
+//
+// Private
+//
+
+void
+IceSecurity::Ssl::OpenSSL::System::initClient(GeneralConfig& general,
+ CertificateAuthority& certAuth,
+ BaseCertificates& baseCerts)
+{
+ ICE_METHOD_INV("OpenSSL::System::initClient()");
+
+ // Init the Random Number System.
+ initRandSystem(general.getRandomBytesFiles());
+
+ // Create an SSL Context based on the context params.
+ _sslClientContext = createContext(general.getProtocol());
+
+ // Begin setting up the SSL Context.
+ if (_sslClientContext != 0)
+ {
+ // Get the cipherlist and set it in the context.
+ setCipherList(_sslClientContext, general.getCipherList());
+
+ // Set the certificate verification mode.
+ SSL_CTX_set_verify(_sslClientContext, general.getVerifyMode(), verifyCallback);
+
+ // Set the certificate verify depth to 10 deep.
+ SSL_CTX_set_verify_depth(_sslClientContext, general.getVerifyDepth());
+
+ // Process the RSA Certificate (if present).
+ if (baseCerts.getRSACert().getKeySize() != 0)
+ {
+ processCertificate(_sslClientContext, baseCerts.getRSACert());
+ }
+
+ // Process the DSA Certificate (if present).
+ if (baseCerts.getDSACert().getKeySize() != 0)
+ {
+ processCertificate(_sslClientContext, baseCerts.getDSACert());
+ }
+
+ // Set the DH key agreement parameters.
+ if (baseCerts.getDHParams().getKeySize() != 0)
+ {
+ setDHParams(_sslClientContext, baseCerts);
+ }
+
+ // Load the Certificate Authority files, and check them.
+ loadCAFiles(_sslClientContext, certAuth);
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::initClient()");
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::initServer(GeneralConfig& general,
+ CertificateAuthority& certAuth,
+ BaseCertificates& baseCerts,
+ TempCertificates& tempCerts)
+{
+ ICE_METHOD_INV("OpenSSL::System::initServer()");
+
+ // Init the Random Number System.
+ initRandSystem(general.getRandomBytesFiles());
+
+ // Create an SSL Context based on the context params.
+ _sslServerContext = createContext(general.getProtocol());
+
+ // Begin setting up the SSL Context.
+ if (_sslServerContext != 0)
+ {
+ // On servers, Attempt to use non-export (strong) encryption
+ // first. This option does not always work, and in the OpenSSL
+ // documentation is declared as 'broken'.
+ // SSL_CTX_set_options(_sslServerContext,SSL_OP_NON_EXPORT_FIRST);
+
+ // Always use a new DH key when using Diffie-Hellman key agreement.
+ SSL_CTX_set_options(_sslServerContext, SSL_OP_SINGLE_DH_USE);
+
+ loadTempCerts(tempCerts);
+
+ // Load the Certificate Authority files, and check them.
+ loadAndCheckCAFiles(_sslServerContext, certAuth);
+
+ // Process the RSA Certificate (if present).
+ if (baseCerts.getRSACert().getKeySize() != 0)
+ {
+ processCertificate(_sslServerContext, baseCerts.getRSACert());
+ }
+
+ // Process the DSA Certificate (if present).
+ if (baseCerts.getDSACert().getKeySize() != 0)
+ {
+ processCertificate(_sslServerContext, baseCerts.getDSACert());
+ }
+
+ // Set the DH key agreement parameters.
+ if (baseCerts.getDHParams().getKeySize() != 0)
+ {
+ setDHParams(_sslServerContext, baseCerts);
+ }
+
+ // Set the RSA Callback routine in case we need to build a temporary RSA key.
+ SSL_CTX_set_tmp_rsa_callback(_sslServerContext, tmpRSACallback);
+
+ // Set the DH Callback routine in case we need a temporary DH key.
+ SSL_CTX_set_tmp_dh_callback(_sslServerContext, tmpDHCallback);
+
+ // Get the cipherlist and set it in the context.
+ setCipherList(_sslServerContext, general.getCipherList());
+
+ // Set the certificate verification mode.
+ SSL_CTX_set_verify(_sslServerContext, general.getVerifyMode(), verifyCallback);
+
+ // Set the certificate verify depth
+ SSL_CTX_set_verify_depth(_sslServerContext, general.getVerifyDepth());
+
+ // Set the default context for the SSL system (can be overridden if needed) [SERVER ONLY].
+ SSL_CTX_set_session_id_context(_sslServerContext,
+ reinterpret_cast<const unsigned char *>(_sessionContext.c_str()),
+ _sessionContext.size());
+ }
+
+ printContextInfo(_sslServerContext);
+
+ ICE_METHOD_RET("OpenSSL::System::initServer()");
+}
+
+SSL_METHOD*
+IceSecurity::Ssl::OpenSSL::System::getSslMethod(SslProtocol sslVersion)
+{
+ ICE_METHOD_INV("OpenSSL::System::getSslMethod()");
+
+ SSL_METHOD* sslMethod = 0;
+
+ switch (sslVersion)
+ {
+ case SSL_V2 :
+ {
+ sslMethod = SSLv2_method();
+ break;
+ }
+
+ case SSL_V23 :
+ {
+ sslMethod = SSLv23_method();
+ break;
+ }
+
+ case SSL_V3 :
+ {
+ sslMethod = SSLv3_method();
+ break;
+ }
+
+ case TLS_V1 :
+ {
+ sslMethod = TLSv1_method();
+ break;
+ }
+
+ default :
+ {
+ string errorString;
+
+ errorString = "SSL Version ";
+ errorString += sslVersion;
+ errorString += " not supported - defaulting to SSL_V23.";
+
+ ICE_WARNING(errorString);
+
+ sslMethod = SSLv23_method();
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::getSslMethod()");
+
+ return sslMethod;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::processCertificate(SSL_CTX* sslContext, const CertificateDesc& certificateDesc)
+{
+ ICE_METHOD_INV("OpenSSL::System::processCertificate()");
+
+ const CertificateFile& publicCert = certificateDesc.getPublic();
+ const CertificateFile& privateKey = certificateDesc.getPrivate();
+
+ addKeyCert(sslContext, publicCert, privateKey);
+
+ ICE_METHOD_RET("OpenSSL::System::processCertificate()");
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::addKeyCert(SSL_CTX* sslContext,
+ const CertificateFile& publicCert,
+ const CertificateFile& privateKey)
+{
+ ICE_METHOD_INV("OpenSSL::System::addKeyCert()");
+
+ if (!publicCert.getFileName().empty())
+ {
+ string publicCertFile = publicCert.getFileName();
+ const char* publicFile = publicCertFile.c_str();
+ int publicEncoding = publicCert.getEncoding();
+
+ string privCertFile = privateKey.getFileName();
+ const char* privKeyFile = privCertFile.c_str();
+ int privKeyFileType = privateKey.getEncoding();
+
+ // Set which Public Key file to use.
+ if (SSL_CTX_use_certificate_file(sslContext, publicFile, publicEncoding) <= 0)
+ {
+ string errorString;
+
+ errorString = "Unable to get certificate from '";
+ errorString += publicFile;
+ errorString += "'\n";
+ errorString += sslGetErrors();
+
+ ICE_EXCEPTION(errorString);
+
+ throw ContextException(errorString.c_str(), __FILE__, __LINE__);
+ }
+
+ if (privateKey.getFileName().empty())
+ {
+ ICE_WARNING("No private key specified - using the certificate.");
+
+ privKeyFile = publicFile;
+ privKeyFileType = publicEncoding;
+ }
+
+ // Set which Private Key file to use.
+ if (SSL_CTX_use_PrivateKey_file(sslContext, privKeyFile, privKeyFileType) <= 0)
+ {
+ string errorString;
+
+ errorString = "Unable to get private key from '";
+ errorString += privKeyFile;
+ errorString += "'\n";
+ errorString += sslGetErrors();
+
+ ICE_EXCEPTION(errorString);
+
+ throw ContextException(errorString.c_str(), __FILE__, __LINE__);
+ }
+
+ // Check to see if the Private and Public keys that have been
+ // set against the SSL context match up.
+ if (!SSL_CTX_check_private_key(sslContext))
+ {
+ string errorString = "Private key does not match the certificate public key.";
+ string sslError = sslGetErrors();
+
+ if (!sslError.empty())
+ {
+ errorString += sslError;
+ }
+
+ ICE_EXCEPTION(errorString);
+
+ throw ContextException(errorString.c_str(), __FILE__, __LINE__);
+ }
+
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::addKeyCert()");
+}
+
+
+SSL_CTX*
+IceSecurity::Ssl::OpenSSL::System::createContext(SslProtocol sslProtocol)
+{
+ ICE_METHOD_INV("OpenSSL::System::createContext()");
+
+ SSL_CTX* context = SSL_CTX_new(getSslMethod(sslProtocol));
+
+ if (context == 0)
+ {
+ string errorString = "Unable to create SSL Context.\n" + sslGetErrors();
+
+ ICE_EXCEPTION(errorString);
+
+ throw ContextException(errorString.c_str(), __FILE__, __LINE__);
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::createContext()");
+
+ return context;
+}
+
+
+string
+IceSecurity::Ssl::OpenSSL::System::sslGetErrors()
+{
+ ICE_METHOD_INV("OpenSSL::System::sslGetErrors()");
+
+ string errorMessage;
+ char buf[200];
+ char bigBuffer[1024];
+ const char* file = 0;
+ const char* data = 0;
+ int line = 0;
+ int flags = 0;
+ unsigned errorCode = 0;
+ int errorNum = 1;
+
+ unsigned long es = CRYPTO_thread_id();
+
+ while ((errorCode = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0)
+ {
+ sprintf(bigBuffer,"%6d - Thread ID: %lu\n", errorNum, es);
+ errorMessage += bigBuffer;
+
+ sprintf(bigBuffer,"%6d - Error: %u\n", errorNum, errorCode);
+ errorMessage += bigBuffer;
+
+ // Request an error from the OpenSSL library
+ ERR_error_string_n(errorCode, buf, sizeof(buf));
+ sprintf(bigBuffer,"%6d - Message: %s\n", errorNum, buf);
+ errorMessage += bigBuffer;
+
+ sprintf(bigBuffer,"%6d - Location: %s, %d\n", errorNum, file, line);
+ errorMessage += bigBuffer;
+
+ if (flags & ERR_TXT_STRING)
+ {
+ sprintf(bigBuffer,"%6d - Data: %s\n", errorNum, data);
+ errorMessage += bigBuffer;
+ }
+
+ errorNum++;
+ }
+
+ ERR_clear_error();
+
+ ICE_METHOD_RET("OpenSSL::System::sslGetErrors()");
+
+ return errorMessage;
+}
+
+SSL*
+IceSecurity::Ssl::OpenSSL::System::createConnection(SSL_CTX* sslContext, int socket)
+{
+ ICE_METHOD_INV("OpenSSL::System::createConnection()");
+
+ SSL *sslConnection = 0;
+
+ sslConnection = SSL_new(sslContext);
+
+ SSL_clear(sslConnection);
+
+ SSL_set_fd(sslConnection, socket);
+
+ if (ICE_SECURITY_LEVEL_PROTOCOL_DEBUG)
+ {
+ sslConnection->debug = 1;
+ BIO_set_callback(SSL_get_rbio(sslConnection), bio_dump_cb);
+ BIO_set_callback_arg(SSL_get_rbio(sslConnection), 0);
+ BIO_set_callback(SSL_get_wbio(sslConnection), bio_dump_cb);
+ BIO_set_callback_arg(SSL_get_rbio(sslConnection), 0);
+ }
+
+ // Map the SSL Connection to this SslSystem
+ // This is required for the OpenSSL callbacks
+ // to work properly.
+ Factory::addSystemHandle(sslConnection, this);
+
+ ICE_METHOD_RET("OpenSSL::System::createConnection()");
+
+ return sslConnection;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::loadCAFiles(SSL_CTX* sslContext, CertificateAuthority& certAuth)
+{
+ ICE_METHOD_INV("OpenSSL::System::loadCAFiles()");
+
+ string caFile = certAuth.getCAFileName();
+ string caPath = certAuth.getCAPath();
+
+ loadCAFiles(sslContext, caFile.c_str(), caPath.c_str());
+
+ ICE_METHOD_RET("OpenSSL::System::loadCAFiles()");
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::loadCAFiles(SSL_CTX* sslContext, const char* caFile, const char* caPath)
+{
+ ICE_METHOD_INV("OpenSSL::System::loadCAFiles()");
+
+ if (sslContext != 0)
+ {
+ // The following checks are required to send the expected values to the OpenSSL library.
+ // It does not like receiving "", but prefers NULLs.
+ if ((caFile != 0) && (strlen(caFile) == 0))
+ {
+ caFile = 0;
+ }
+
+ if ((caPath != 0) && (strlen(caPath) == 0))
+ {
+ caPath = 0;
+ }
+
+ // Check the Certificate Authority file(s).
+ if ((!SSL_CTX_load_verify_locations(sslContext, caFile, caPath)) ||
+ (!SSL_CTX_set_default_verify_paths(sslContext)))
+ {
+ // Non Fatal.
+ ICE_WARNING("Unable to load/verify Certificate Authorities.");
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::loadCAFiles()");
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::loadAndCheckCAFiles(SSL_CTX* sslContext, CertificateAuthority& certAuth)
+{
+ ICE_METHOD_INV("OpenSSL::System::loadAndCheckCAFiles()");
+
+ if (sslContext != 0)
+ {
+ string caFile = certAuth.getCAFileName();
+ string caPath = certAuth.getCAPath();
+
+ // Check the Certificate Authority file(s).
+ loadCAFiles(sslContext, caFile.c_str(), caPath.c_str());
+
+ if (!caPath.empty())
+ {
+ STACK_OF(X509_NAME)* certNames = SSL_load_client_CA_file(caFile.c_str());
+
+ if (certNames == 0)
+ {
+ string errorString = "Unable to load Certificate Authorities certificate names from " + caFile + ".\n";
+ errorString += sslGetErrors();
+ ICE_WARNING(errorString);
+ }
+ else
+ {
+ SSL_CTX_set_client_CA_list(sslContext, certNames);
+ }
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::loadAndCheckCAFiles()");
+}
+
+DH*
+IceSecurity::Ssl::OpenSSL::System::loadDHParam(const char* dhfile)
+{
+ ICE_METHOD_INV(string("OpenSSL::System::loadDHParam(") + dhfile + string(")"));
+
+ DH* ret = 0;
+ BIO* bio;
+
+ if ((bio = BIO_new_file(dhfile,"r")) != 0)
+ {
+ ret = PEM_read_bio_DHparams(bio, 0, 0, 0);
+ }
+
+ if (bio != 0)
+ {
+ BIO_free(bio);
+ }
+
+ ICE_METHOD_RET(string("OpenSSL::System::loadDHParam(") + dhfile + string(")"));
+
+ return ret;
+}
+
+DH*
+IceSecurity::Ssl::OpenSSL::System::getTempDH(unsigned char* p, int plen, unsigned char* g, int glen)
+{
+ ICE_METHOD_INV("OpenSSL::System::getTempDH()");
+
+ DH* dh = 0;
+
+ if ((dh = DH_new()) != 0)
+ {
+ dh->p = BN_bin2bn(p, plen, 0);
+
+ dh->g = BN_bin2bn(g, glen, 0);
+
+ if ((dh->p == 0) || (dh->g == 0))
+ {
+ DH_free(dh);
+ dh = 0;
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::getTempDH()");
+
+ return dh;
+}
+
+DH*
+IceSecurity::Ssl::OpenSSL::System::getTempDH512()
+{
+ ICE_METHOD_INV("OpenSSL::System::getTempDH512()");
+
+ DH* dh = getTempDH(_tempDiffieHellman512p, sizeof(_tempDiffieHellman512p),
+ _tempDiffieHellman512g, sizeof(_tempDiffieHellman512g));
+
+ ICE_METHOD_RET("OpenSSL::System::getTempDH512()");
+
+ return dh;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::setDHParams(SSL_CTX* sslContext, BaseCertificates& baseCerts)
+{
+ ICE_METHOD_INV("OpenSSL::System::setDHParams()");
+
+ string dhFile;
+ int encoding = 0;
+
+ if (baseCerts.getDHParams().getKeySize() != 0)
+ {
+ dhFile = baseCerts.getDHParams().getFileName();
+ encoding = baseCerts.getDHParams().getEncoding();
+ }
+ else if (baseCerts.getRSACert().getKeySize() != 0)
+ {
+ dhFile = baseCerts.getRSACert().getPublic().getFileName();
+ encoding = baseCerts.getRSACert().getPublic().getEncoding();
+ }
+
+ DH* dh = 0;
+
+ // File type must be PEM - that's the only way we can load
+ // DH Params, apparently.
+ if ((!dhFile.empty()) && (encoding == SSL_FILETYPE_PEM))
+ {
+ dh = loadDHParam(dhFile.c_str());
+ }
+
+ if (dh == 0)
+ {
+ ICE_WARNING("Could not load Diffie-Hellman params, generating a temporary 512bit key.");
+
+ dh = getTempDH512();
+ }
+
+ if (dh != 0)
+ {
+ SSL_CTX_set_tmp_dh(sslContext, dh);
+
+ DH_free(dh);
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::setDHParams()");
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::setCipherList(SSL_CTX* sslContext, const string& cipherList)
+{
+ ICE_METHOD_INV("OpenSSL::System::setCipherList()");
+
+ if (!cipherList.empty() && (!SSL_CTX_set_cipher_list(sslContext, cipherList.c_str())))
+ {
+ string errorString = "Error setting cipher list " + cipherList + " - using default list.\n";
+
+ errorString += sslGetErrors();
+
+ ICE_WARNING(errorString);
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::setCipherList()");
+}
+
+int
+IceSecurity::Ssl::OpenSSL::System::seedRand()
+{
+ ICE_METHOD_INV("OpenSSL::System::seedRand()");
+
+ int retCode = 1;
+ char buffer[1024];
+
+#ifdef WINDOWS
+ RAND_screen();
+#endif
+
+ const char* file = RAND_file_name(buffer, sizeof(buffer));
+
+ if (file == 0 || !RAND_load_file(file, -1))
+ {
+ retCode = 0;
+ }
+ else
+ {
+ _randSeeded = 1;
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::seedRand()");
+
+ return retCode;
+}
+
+long
+IceSecurity::Ssl::OpenSSL::System::loadRandFiles(const string& names)
+{
+ ICE_METHOD_INV("OpenSSL::System::loadRandFiles(" + names + ")");
+
+ long tot = 0;
+
+ if (!names.empty())
+ {
+ int egd;
+
+ // Make a modifiable copy of the string.
+ char* namesString = new char[names.length() + 1];
+ strcpy(namesString, names.c_str());
+
+ char seps[5];
+
+ sprintf(seps, "%c", LIST_SEPARATOR_CHAR);
+
+ char* token = strtok(namesString, seps);
+
+ while (token != 0)
+ {
+ egd = RAND_egd(token);
+
+ if (egd > 0)
+ {
+ tot += egd;
+ }
+ else
+ {
+ tot += RAND_load_file(token, -1);
+ }
+
+ token = strtok(0, seps);
+ }
+
+ if (tot > 512)
+ {
+ _randSeeded = 1;
+ }
+
+ delete []namesString;
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::loadRandFiles(" + names + ")");
+
+ return tot;
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::initRandSystem(const string& randBytesFiles)
+{
+ ICE_METHOD_INV("OpenSSL::System::initRandSystem(" + randBytesFiles + ")");
+
+ if (!_randSeeded)
+ {
+ long randBytesLoaded = 0;
+
+ if (!seedRand() && randBytesFiles.empty() && !RAND_status())
+ {
+ ICE_WARNING("There is a lack of random data, consider specifying a random data file.");
+ }
+
+ if (!randBytesFiles.empty())
+ {
+ randBytesLoaded = loadRandFiles(randBytesFiles);
+ }
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::initRandSystem(" + randBytesFiles + ")");
+}
+
+void
+IceSecurity::Ssl::OpenSSL::System::loadTempCerts(TempCertificates& tempCerts)
+{
+ ICE_METHOD_INV("OpenSSL::System::loadTempCerts()");
+
+ RSAVector::iterator iRSA = tempCerts.getRSACerts().begin();
+ RSAVector::iterator eRSA = tempCerts.getRSACerts().end();
+
+ while (iRSA != eRSA)
+ {
+ _tempRSAFileMap[(*iRSA).getKeySize()] = *iRSA;
+ iRSA++;
+ }
+
+ DSAVector::iterator iDSA = tempCerts.getDSACerts().begin();
+ DSAVector::iterator eDSA = tempCerts.getDSACerts().end();
+
+ while (iDSA != eDSA)
+ {
+ _tempDSAFileMap[(*iDSA).getKeySize()] = *iDSA;
+ iDSA++;
+ }
+
+ DHVector::iterator iDHP = tempCerts.getDHParams().begin();
+ DHVector::iterator eDHP = tempCerts.getDHParams().end();
+
+ while (iDHP != eDHP)
+ {
+ _tempDHParamsFileMap[(*iDHP).getKeySize()] = *iDHP;
+ iDHP++;
+ }
+
+ ICE_METHOD_RET("OpenSSL::System::loadTempCerts()");
+}
diff --git a/cpp/src/Ice/SslSystemOpenSSL.h b/cpp/src/Ice/SslSystemOpenSSL.h index d09e1efd696..ad1d7e81eac 100644 --- a/cpp/src/Ice/SslSystemOpenSSL.h +++ b/cpp/src/Ice/SslSystemOpenSSL.h @@ -1,197 +1,197 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** -#ifndef ICE_SSL_SYSTEM_OPENSSL_H -#define ICE_SSL_SYSTEM_OPENSSL_H - -#include <openssl/ssl.h> -#include <string> -#include <map> -#include <JTC/JTC.h> -#include <Ice/Config.h> -#include <Ice/TraceLevels.h> -#include <Ice/Logger.h> -#include <Ice/SslFactory.h> -#include <Ice/SslSystem.h> -#include <Ice/SslConnection.h> -#include <Ice/SslConnectionOpenSSL.h> - -namespace IceSecurity -{ - -namespace Ssl -{ - -typedef enum -{ - SSL_V2 = 1, // Only speak SSLv2 - SSL_V23, // Speak SSLv2 and SSLv3 - SSL_V3, // Only speak SSLv3 - TLS_V1 // Only speak TLSv1 -} SslProtocol; - -} - -} - -#include <Ice/SslGeneralConfig.h> -#include <Ice/SslCertificateDesc.h> -#include <Ice/SslCertificateAuthority.h> -#include <Ice/SslBaseCerts.h> -#include <Ice/SslTempCerts.h> - -extern "C" -{ - RSA* tmpRSACallback(SSL*, int, int); - DH* tmpDHCallback(SSL*, int, int); -} - -namespace IceSecurity -{ - -namespace Ssl -{ - -class GeneralConfig; - -namespace OpenSSL -{ - -using namespace Ice; -using namespace IceSecurity::Ssl; - -using std::map; -using std::string; - -typedef map<int,RSA*> RSAMap; -typedef map<int,DH*> DHMap; - -typedef map<int,CertificateDesc> RSACertMap; -typedef map<int,CertificateDesc> DSACertMap; -typedef map<int,DiffieHellmanParamsFile> DHParamsMap; - -class System : public IceSecurity::Ssl::System -{ - -public: - - void printContextInfo(SSL_CTX*); - - // This is how we create a Server connection. - virtual IceSecurity::Ssl::Connection* createServerConnection(int); - - // This is how we create a Client connection. - virtual IceSecurity::Ssl::Connection* createClientConnection(int); - - // Shuts down the SSL System. - virtual void shutdown(); - - virtual bool isConfigLoaded(); - virtual void loadConfig(); - - // Returns the desired RSA Key, or creates it if not already created. - // This is public because the tmpRSACallback must be able to access it. - RSA* getRSAKey(SSL*, int, int); - - // Returns the desired DH Params. If the Params do not already exist, and the key - // requested is a 512bit or 1024bit key, we use the compiled-in temporary params. - // If the key is some other length, we read the desired key, based on length, - // from a DH Param file. - // This is public because the tmpDHCallback must be able to access it. - DH* getDHParams(SSL*, int, int); - - static TraceLevelsPtr _globalTraceLevels; - static Ice::LoggerPtr _globalLogger; - -protected: - - System(string&); - ~System(); - -private: - - // Base Diffie-Hellman 512bit key (only to be used for key exchange). - static unsigned char _tempDiffieHellman512p[]; - static unsigned char _tempDiffieHellman512g[]; - - // Default SSL Contexts, for both Server and Client connections. - SSL_CTX* _sslServerContext; - SSL_CTX* _sslClientContext; - - // Keep a cache of all temporary RSA keys. - RSAMap _tempRSAKeys; - JTCMutex _tempRSAKeysMutex; - - // Keep a cache of all temporary Diffie-Hellman keys. - DHMap _tempDHKeys; - JTCMutex _tempDHKeysMutex; - - // Maps of all temporary keying information. - // The files themselves will not be loaded until - // needed. - RSACertMap _tempRSAFileMap; - DSACertMap _tempDSAFileMap; - DHParamsMap _tempDHParamsFileMap; - - // The Session ID Context (Server Only). - string _sessionContext; - - // Flag as to whether the Random Number system has been seeded. - int _randSeeded; - - bool _configLoaded; - - // Call to initialize the SSL system. - void initClient(GeneralConfig&, CertificateAuthority&, BaseCertificates&); - void initServer(GeneralConfig&, CertificateAuthority&, BaseCertificates&, TempCertificates&); - - SSL_METHOD* getSslMethod(SslProtocol); - - void processCertificate(SSL_CTX*, const CertificateDesc&); - void addKeyCert(SSL_CTX*, const CertificateFile&, const CertificateFile&); - - SSL_CTX* createContext(SslProtocol); - - // Retrieves errors from the OpenSSL library. - string sslGetErrors(); - - // Create a connection. - SSL* createConnection(SSL_CTX*, int); - - // Methods for loading CAFiles into a Context. - void loadCAFiles(SSL_CTX*, CertificateAuthority&); - void loadCAFiles(SSL_CTX*, const char*, const char*); - void loadAndCheckCAFiles(SSL_CTX*, CertificateAuthority&); - - DH* loadDHParam(const char *); - DH* getTempDH(unsigned char*, int, unsigned char*, int); - DH* getTempDH512(); - void setDHParams(SSL_CTX*, BaseCertificates&); - - void setCipherList(SSL_CTX*, const string&); - - // Cryptographic Random Number System related routines. - int seedRand(); - long loadRandFiles(const string&); - void initRandSystem(const string&); - - void loadTempCerts(TempCertificates&); - - friend class IceSecurity::Ssl::Factory; - friend class Connection; - -}; - -} - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+#ifndef ICE_SSL_SYSTEM_OPENSSL_H
+#define ICE_SSL_SYSTEM_OPENSSL_H
+
+#include <openssl/ssl.h>
+#include <string>
+#include <map>
+#include <JTC/JTC.h>
+#include <Ice/Config.h>
+#include <Ice/TraceLevels.h>
+#include <Ice/Logger.h>
+#include <Ice/SslFactory.h>
+#include <Ice/SslSystem.h>
+#include <Ice/SslConnection.h>
+#include <Ice/SslConnectionOpenSSL.h>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+typedef enum
+{
+ SSL_V2 = 1, // Only speak SSLv2
+ SSL_V23, // Speak SSLv2 and SSLv3
+ SSL_V3, // Only speak SSLv3
+ TLS_V1 // Only speak TLSv1
+} SslProtocol;
+
+}
+
+}
+
+#include <Ice/SslGeneralConfig.h>
+#include <Ice/SslCertificateDesc.h>
+#include <Ice/SslCertificateAuthority.h>
+#include <Ice/SslBaseCerts.h>
+#include <Ice/SslTempCerts.h>
+
+extern "C"
+{
+ RSA* tmpRSACallback(SSL*, int, int);
+ DH* tmpDHCallback(SSL*, int, int);
+}
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+class GeneralConfig;
+
+namespace OpenSSL
+{
+
+using namespace Ice;
+using namespace IceSecurity::Ssl;
+
+using std::map;
+using std::string;
+
+typedef map<int,RSA*> RSAMap;
+typedef map<int,DH*> DHMap;
+
+typedef map<int,CertificateDesc> RSACertMap;
+typedef map<int,CertificateDesc> DSACertMap;
+typedef map<int,DiffieHellmanParamsFile> DHParamsMap;
+
+class System : public IceSecurity::Ssl::System
+{
+
+public:
+
+ void printContextInfo(SSL_CTX*);
+
+ // This is how we create a Server connection.
+ virtual IceSecurity::Ssl::Connection* createServerConnection(int);
+
+ // This is how we create a Client connection.
+ virtual IceSecurity::Ssl::Connection* createClientConnection(int);
+
+ // Shuts down the SSL System.
+ virtual void shutdown();
+
+ virtual bool isConfigLoaded();
+ virtual void loadConfig();
+
+ // Returns the desired RSA Key, or creates it if not already created.
+ // This is public because the tmpRSACallback must be able to access it.
+ RSA* getRSAKey(SSL*, int, int);
+
+ // Returns the desired DH Params. If the Params do not already exist, and the key
+ // requested is a 512bit or 1024bit key, we use the compiled-in temporary params.
+ // If the key is some other length, we read the desired key, based on length,
+ // from a DH Param file.
+ // This is public because the tmpDHCallback must be able to access it.
+ DH* getDHParams(SSL*, int, int);
+
+ static TraceLevelsPtr _globalTraceLevels;
+ static Ice::LoggerPtr _globalLogger;
+
+protected:
+
+ System(string&);
+ ~System();
+
+private:
+
+ // Base Diffie-Hellman 512bit key (only to be used for key exchange).
+ static unsigned char _tempDiffieHellman512p[];
+ static unsigned char _tempDiffieHellman512g[];
+
+ // Default SSL Contexts, for both Server and Client connections.
+ SSL_CTX* _sslServerContext;
+ SSL_CTX* _sslClientContext;
+
+ // Keep a cache of all temporary RSA keys.
+ RSAMap _tempRSAKeys;
+ JTCMutex _tempRSAKeysMutex;
+
+ // Keep a cache of all temporary Diffie-Hellman keys.
+ DHMap _tempDHKeys;
+ JTCMutex _tempDHKeysMutex;
+
+ // Maps of all temporary keying information.
+ // The files themselves will not be loaded until
+ // needed.
+ RSACertMap _tempRSAFileMap;
+ DSACertMap _tempDSAFileMap;
+ DHParamsMap _tempDHParamsFileMap;
+
+ // The Session ID Context (Server Only).
+ string _sessionContext;
+
+ // Flag as to whether the Random Number system has been seeded.
+ int _randSeeded;
+
+ bool _configLoaded;
+
+ // Call to initialize the SSL system.
+ void initClient(GeneralConfig&, CertificateAuthority&, BaseCertificates&);
+ void initServer(GeneralConfig&, CertificateAuthority&, BaseCertificates&, TempCertificates&);
+
+ SSL_METHOD* getSslMethod(SslProtocol);
+
+ void processCertificate(SSL_CTX*, const CertificateDesc&);
+ void addKeyCert(SSL_CTX*, const CertificateFile&, const CertificateFile&);
+
+ SSL_CTX* createContext(SslProtocol);
+
+ // Retrieves errors from the OpenSSL library.
+ string sslGetErrors();
+
+ // Create a connection.
+ SSL* createConnection(SSL_CTX*, int);
+
+ // Methods for loading CAFiles into a Context.
+ void loadCAFiles(SSL_CTX*, CertificateAuthority&);
+ void loadCAFiles(SSL_CTX*, const char*, const char*);
+ void loadAndCheckCAFiles(SSL_CTX*, CertificateAuthority&);
+
+ DH* loadDHParam(const char *);
+ DH* getTempDH(unsigned char*, int, unsigned char*, int);
+ DH* getTempDH512();
+ void setDHParams(SSL_CTX*, BaseCertificates&);
+
+ void setCipherList(SSL_CTX*, const string&);
+
+ // Cryptographic Random Number System related routines.
+ int seedRand();
+ long loadRandFiles(const string&);
+ void initRandSystem(const string&);
+
+ void loadTempCerts(TempCertificates&);
+
+ friend class IceSecurity::Ssl::Factory;
+ friend class Connection;
+
+};
+
+}
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslTempCerts.cpp b/cpp/src/Ice/SslTempCerts.cpp index 6397175865b..3deebdffd59 100644 --- a/cpp/src/Ice/SslTempCerts.cpp +++ b/cpp/src/Ice/SslTempCerts.cpp @@ -1,41 +1,41 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include <Ice/SslTempCerts.h> - -IceSecurity::Ssl::TempCertificates::TempCertificates() -{ -} - -IceSecurity::Ssl::TempCertificates::~TempCertificates() -{ - _rsaCerts.clear(); - _dsaCerts.clear(); - _rsaCerts.clear(); -} - -void -IceSecurity::Ssl::TempCertificates::addRSACert(CertificateDesc& certDesc) -{ - _rsaCerts.push_back(certDesc); -} - -void -IceSecurity::Ssl::TempCertificates::addDSACert(CertificateDesc& certDesc) -{ - _dsaCerts.push_back(certDesc); -} - -void -IceSecurity::Ssl::TempCertificates::addDHParams(DiffieHellmanParamsFile& dhParams) -{ - _dhParams.push_back(dhParams); -} - +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/SslTempCerts.h>
+
+IceSecurity::Ssl::TempCertificates::TempCertificates()
+{
+}
+
+IceSecurity::Ssl::TempCertificates::~TempCertificates()
+{
+ _rsaCerts.clear();
+ _dsaCerts.clear();
+ _rsaCerts.clear();
+}
+
+void
+IceSecurity::Ssl::TempCertificates::addRSACert(CertificateDesc& certDesc)
+{
+ _rsaCerts.push_back(certDesc);
+}
+
+void
+IceSecurity::Ssl::TempCertificates::addDSACert(CertificateDesc& certDesc)
+{
+ _dsaCerts.push_back(certDesc);
+}
+
+void
+IceSecurity::Ssl::TempCertificates::addDHParams(DiffieHellmanParamsFile& dhParams)
+{
+ _dhParams.push_back(dhParams);
+}
+
diff --git a/cpp/src/Ice/SslTempCerts.h b/cpp/src/Ice/SslTempCerts.h index a150673909b..47048a5bc0b 100644 --- a/cpp/src/Ice/SslTempCerts.h +++ b/cpp/src/Ice/SslTempCerts.h @@ -1,89 +1,89 @@ -// ********************************************************************** -// -// Copyright (c) 2001 -// MutableRealms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#ifndef ICE_SSL_TEMP_CERTS_H -#define ICE_SSL_TEMP_CERTS_H - -#include <Ice/SslCertificateDesc.h> -#include <ostream> - -namespace IceSecurity -{ - -namespace Ssl -{ - -class TempCertificates -{ - -public: - TempCertificates(); - ~TempCertificates(); - - void addRSACert(CertificateDesc&); - void addDSACert(CertificateDesc&); - void addDHParams(DiffieHellmanParamsFile&); - - inline RSAVector& getRSACerts() { return _rsaCerts; }; - inline DSAVector& getDSACerts() { return _dsaCerts; }; - inline DHVector& getDHParams() { return _dhParams; }; - -protected: - RSAVector _rsaCerts; - DSAVector _dsaCerts; - DHVector _dhParams; -}; - -using std::endl; - -template<class Stream> -inline Stream& operator << (Stream& target, TempCertificates& tmpCerts) -{ - RSAVector::iterator iRSA = tmpCerts.getRSACerts().begin(); - RSAVector::iterator eRSA = tmpCerts.getRSACerts().end(); - - while (iRSA != eRSA) - { - target << "RSA" << endl << "{" << endl; - target << *iRSA; - target << "}" << endl << endl; - iRSA++; - } - - DSAVector::iterator iDSA = tmpCerts.getDSACerts().begin(); - DSAVector::iterator eDSA = tmpCerts.getDSACerts().end(); - - while (iDSA != eDSA) - { - target << "DSA" << endl << "{" << endl; - target << *iDSA; - target << "}" << endl << endl; - iDSA++; - } - - DHVector::iterator iDHP = tmpCerts.getDHParams().begin(); - DHVector::iterator eDHP = tmpCerts.getDHParams().end(); - - while (iDHP != eDHP) - { - target << "DH" << endl << "{" << endl; - target << *iDHP; - target << "}" << endl << endl; - iDHP++; - } - - return target; -} - -} - -} - -#endif +// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_SSL_TEMP_CERTS_H
+#define ICE_SSL_TEMP_CERTS_H
+
+#include <Ice/SslCertificateDesc.h>
+#include <ostream>
+
+namespace IceSecurity
+{
+
+namespace Ssl
+{
+
+class TempCertificates
+{
+
+public:
+ TempCertificates();
+ ~TempCertificates();
+
+ void addRSACert(CertificateDesc&);
+ void addDSACert(CertificateDesc&);
+ void addDHParams(DiffieHellmanParamsFile&);
+
+ inline RSAVector& getRSACerts() { return _rsaCerts; };
+ inline DSAVector& getDSACerts() { return _dsaCerts; };
+ inline DHVector& getDHParams() { return _dhParams; };
+
+protected:
+ RSAVector _rsaCerts;
+ DSAVector _dsaCerts;
+ DHVector _dhParams;
+};
+
+using std::endl;
+
+template<class Stream>
+inline Stream& operator << (Stream& target, TempCertificates& tmpCerts)
+{
+ RSAVector::iterator iRSA = tmpCerts.getRSACerts().begin();
+ RSAVector::iterator eRSA = tmpCerts.getRSACerts().end();
+
+ while (iRSA != eRSA)
+ {
+ target << "RSA" << endl << "{" << endl;
+ target << *iRSA;
+ target << "}" << endl << endl;
+ iRSA++;
+ }
+
+ DSAVector::iterator iDSA = tmpCerts.getDSACerts().begin();
+ DSAVector::iterator eDSA = tmpCerts.getDSACerts().end();
+
+ while (iDSA != eDSA)
+ {
+ target << "DSA" << endl << "{" << endl;
+ target << *iDSA;
+ target << "}" << endl << endl;
+ iDSA++;
+ }
+
+ DHVector::iterator iDHP = tmpCerts.getDHParams().begin();
+ DHVector::iterator eDHP = tmpCerts.getDHParams().end();
+
+ while (iDHP != eDHP)
+ {
+ target << "DH" << endl << "{" << endl;
+ target << *iDHP;
+ target << "}" << endl << endl;
+ iDHP++;
+ }
+
+ return target;
+}
+
+}
+
+}
+
+#endif
diff --git a/cpp/src/Ice/SslTransceiver.cpp b/cpp/src/Ice/SslTransceiver.cpp index d0de45476b2..47fc85a627e 100644 --- a/cpp/src/Ice/SslTransceiver.cpp +++ b/cpp/src/Ice/SslTransceiver.cpp @@ -7,27 +7,22 @@ // All Rights Reserved // // ********************************************************************** - -#include <Ice/Security.h> -#include <Ice/SslConnection.h> -#include <Ice/SslTransceiver.h> +
+#include <Ice/Security.h>
+#include <Ice/SslConnection.h>
+#include <Ice/SslTransceiver.h>
#include <Ice/Instance.h> #include <Ice/TraceLevels.h> #include <Ice/Logger.h> #include <Ice/Buffer.h> #include <Ice/Network.h> #include <Ice/Exception.h> -#include <Ice/SslException.h> -#include <sstream> +#include <sstream>
using namespace std; using namespace Ice; using namespace IceInternal; -using IceSecurity::SecurityException; -using IceSecurity::Ssl::InitException; -using IceSecurity::Ssl::ReInitException; -using IceSecurity::Ssl::ShutdownException; - +
int IceInternal::SslTransceiver::fd() { @@ -37,8 +32,8 @@ IceInternal::SslTransceiver::fd() void IceInternal::SslTransceiver::close() { - METHOD_INV("SslTransceiver::close()"); - + ICE_METHOD_INV("SslTransceiver::close()");
+
if (_traceLevels->network >= 1) { ostringstream s; @@ -47,19 +42,19 @@ IceInternal::SslTransceiver::close() } int fd = _fd; - cleanUpSSL(); + cleanUpSSL();
_fd = INVALID_SOCKET; ::shutdown(fd, SHUT_RDWR); // helps to unblock threads in recv() closeSocket(fd); - - METHOD_RET("SslTransceiver::close()"); +
+ ICE_METHOD_RET("SslTransceiver::close()");
} void IceInternal::SslTransceiver::shutdown() { - METHOD_INV("SslTransceiver::shutdown()"); - + ICE_METHOD_INV("SslTransceiver::shutdown()");
+
if (_traceLevels->network >= 2) { ostringstream s; @@ -68,31 +63,31 @@ IceInternal::SslTransceiver::shutdown() } ::shutdown(_fd, SHUT_WR); // Shutdown socket for writing - - METHOD_RET("SslTransceiver::shutdown()"); +
+ ICE_METHOD_RET("SslTransceiver::shutdown()");
} void IceInternal::SslTransceiver::write(Buffer& buf, int timeout) -{ - METHOD_INV("SslTransceiver::write()") - _sslConnection->write(buf, timeout); - METHOD_RET("SslTransceiver::write()"); +{
+ ICE_METHOD_INV("SslTransceiver::write()")
+ _sslConnection->write(buf, timeout);
+ ICE_METHOD_RET("SslTransceiver::write()");
} void IceInternal::SslTransceiver::read(Buffer& buf, int timeout) { - METHOD_INV("SslTransceiver::read()"); - - if (!_sslConnection->read(buf, timeout)) - { - ConnectionLostException clEx(__FILE__, __LINE__); - clEx.error = 0; - throw clEx; - } - - METHOD_RET("SslTransceiver::read()"); + ICE_METHOD_INV("SslTransceiver::read()");
+
+ if (!_sslConnection->read(buf, timeout))
+ {
+ ConnectionLostException clEx(__FILE__, __LINE__);
+ clEx.error = 0;
+ throw clEx;
+ }
+
+ ICE_METHOD_RET("SslTransceiver::read()");
} string @@ -101,15 +96,15 @@ IceInternal::SslTransceiver::toString() const return fdToString(_fd); } -IceInternal::SslTransceiver::SslTransceiver(const InstancePtr& instance, int fd, Connection* sslConnection) : - _instance(instance), - _fd(fd), - _traceLevels(instance->traceLevels()), - _logger(instance->logger()), - _sslConnection(sslConnection) +IceInternal::SslTransceiver::SslTransceiver(const InstancePtr& instance, int fd, Connection* sslConnection) :
+ _instance(instance),
+ _fd(fd),
+ _traceLevels(instance->traceLevels()),
+ _logger(instance->logger()),
+ _sslConnection(sslConnection)
{ - assert(sslConnection != 0); - + assert(sslConnection != 0);
+
FD_ZERO(&_rFdSet); FD_ZERO(&_wFdSet); } @@ -117,17 +112,17 @@ IceInternal::SslTransceiver::SslTransceiver(const InstancePtr& instance, int fd, IceInternal::SslTransceiver::~SslTransceiver() { assert(_fd == INVALID_SOCKET); - - cleanUpSSL(); -} - -void -IceInternal::SslTransceiver::cleanUpSSL() -{ - if (_sslConnection != 0) - { - _sslConnection->shutdown(); - delete _sslConnection; - _sslConnection = 0; - } +
+ cleanUpSSL();
} +
+void
+IceInternal::SslTransceiver::cleanUpSSL()
+{
+ if (_sslConnection != 0)
+ {
+ _sslConnection->shutdown();
+ delete _sslConnection;
+ _sslConnection = 0;
+ }
+}
diff --git a/cpp/src/Ice/SslTransceiver.h b/cpp/src/Ice/SslTransceiver.h index c4a1290e12f..13c3ab8998f 100644 --- a/cpp/src/Ice/SslTransceiver.h +++ b/cpp/src/Ice/SslTransceiver.h @@ -11,7 +11,7 @@ #ifndef ICE_SSL_TRANSCEIVER_H #define ICE_SSL_TRANSCEIVER_H -#include <Ice/SslConnection.h> +#include <Ice/SslConnection.h>
#include <Ice/InstanceF.h> #include <Ice/TraceLevelsF.h> #include <Ice/LoggerF.h> @@ -20,8 +20,8 @@ namespace IceInternal { -using IceSecurity::Ssl::Connection; - +using IceSecurity::Ssl::Connection;
+
class SslConnector; class SslAcceptor; @@ -38,10 +38,10 @@ public: private: - SslTransceiver(const InstancePtr&, int, Connection*); - - virtual ~SslTransceiver(); - void cleanUpSSL(); + SslTransceiver(const InstancePtr&, int, Connection*);
+
+ virtual ~SslTransceiver();
+ void cleanUpSSL();
friend class SslConnector; friend class SslAcceptor; @@ -51,8 +51,8 @@ private: ::Ice::LoggerPtr _logger; fd_set _rFdSet; fd_set _wFdSet; - - Connection* _sslConnection; +
+ Connection* _sslConnection;
}; } diff --git a/cpp/src/Ice/ice.dsp b/cpp/src/Ice/ice.dsp index 16b8efc11ef..5cf2ffa93d9 100644 --- a/cpp/src/Ice/ice.dsp +++ b/cpp/src/Ice/ice.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBRARY_EXPORTS" /Yu"stdafx.h" /FD /c
-# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I ".." /I "../../include" /D "WIN32" /D "_UNICODE" /D "NDEBUG" /D "_CONSOLE" /D "_USRDLL" /D "ICE_API_EXPORTS" /D "SSL_EXTENSION" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I ".." /I "../../include" /D "WIN32" /D "_UNICODE" /D "NDEBUG" /D "_CONSOLE" /D "_USRDLL" /D "ICE_API_EXPORTS" /YX /FD /c
# SUBTRACT CPP /Fr
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@@ -75,7 +75,7 @@ PostBuild_Cmds=copy Release\ice001.* ..\..\lib # PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBRARY_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I ".." /I "../../include" /D "WIN32" /D "_UNICODE" /D "_DEBUG" /D "_CONSOLE" /D "_USRDLL" /D "ICE_API_EXPORTS" /D "SSL_EXTENSION" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /Zi /Od /I ".." /I "../../include" /D "WIN32" /D "_UNICODE" /D "_DEBUG" /D "_CONSOLE" /D "_USRDLL" /D "ICE_API_EXPORTS" /YX /FD /GZ /c
# SUBTRACT CPP /WX /Fr
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|