diff options
Diffstat (limited to 'cpp/src')
35 files changed, 6095 insertions, 6095 deletions
diff --git a/cpp/src/Ice/Collector.cpp b/cpp/src/Ice/Collector.cpp index 2f8a4cc56ef..b9c0ebb3e20 100644 --- a/cpp/src/Ice/Collector.cpp +++ b/cpp/src/Ice/Collector.cpp @@ -569,9 +569,9 @@ IceInternal::CollectorFactory::message(BasicStream&) } catch (const SecurityException& securityEx) { - // TODO: bandaid. Takes care of SSL Handshake problems during creation of a Transceiver
+ // TODO: bandaid. Takes care of SSL Handshake problems during creation of a Transceiver // TODO: THIS DOESN'T WORK!!! For some reason it skips it. - // Ignore, nothing we can do here
+ // Ignore, nothing we can do here warning(securityEx); } catch (const SocketException&) diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp index a6ebb4a2ffd..1fbe4c62ab6 100644 --- a/cpp/src/Ice/ObjectAdapterI.cpp +++ b/cpp/src/Ice/ObjectAdapterI.cpp @@ -361,17 +361,17 @@ Ice::ObjectAdapterI::newProxy(const string& ident) transform(_collectorFactories.begin(), _collectorFactories.end(), back_inserter(endpoints), Ice::constMemFun(&CollectorFactory::endpoint)); - // 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);
+ // 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 b5a04542abf..821636ab2fd 100644 --- a/cpp/src/Ice/Security.h +++ b/cpp/src/Ice/Security.h @@ -1,141 +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 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
+// ********************************************************************** +// +// 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/SecurityException2.cpp b/cpp/src/Ice/SecurityException2.cpp index 90e5d2825bb..2dc3b8361f6 100644 --- a/cpp/src/Ice/SecurityException2.cpp +++ b/cpp/src/Ice/SecurityException2.cpp @@ -1,60 +1,60 @@ -// **********************************************************************
-//
-// Copyright (c) 2001
-// MutableRealms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-#ifdef WIN32
-#pragma warning(disable:4786)
-#endif
-
-#include <Ice/SecurityException.h>
-
-using Ice::SocketException;
-using Ice::Exception;
-using std::ostream;
-
-
-void
-IceSecurity::SecurityException::ice_print(ostream& out) const
-{
- Exception::ice_print(out);
- if (!_message.empty())
- {
- out << ":\n" << _message;
- }
-}
-
-void
-IceSecurity::Ssl::ConfigParseException::ice_print(ostream& out) const
-{
- SecurityException::ice_print(out);
-}
-
-void
-IceSecurity::Ssl::ShutdownException::ice_print(ostream& out) const
-{
- SecurityException::ice_print(out);
-}
-
-void
-IceSecurity::Ssl::ProtocolException::ice_print(ostream& out) const
-{
- SecurityException::ice_print(out);
-}
-
-void
-IceSecurity::Ssl::CertificateException::ice_print(ostream& out) const
-{
- SecurityException::ice_print(out);
-}
-
-void
-IceSecurity::Ssl::OpenSSL::ContextException::ice_print(ostream& out) const
-{
- SecurityException::ice_print(out);
-}
-
+// ********************************************************************** +// +// Copyright (c) 2001 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** +#ifdef WIN32 +#pragma warning(disable:4786) +#endif + +#include <Ice/SecurityException.h> + +using Ice::SocketException; +using Ice::Exception; +using std::ostream; + + +void +IceSecurity::SecurityException::ice_print(ostream& out) const +{ + Exception::ice_print(out); + if (!_message.empty()) + { + out << ":\n" << _message; + } +} + +void +IceSecurity::Ssl::ConfigParseException::ice_print(ostream& out) const +{ + SecurityException::ice_print(out); +} + +void +IceSecurity::Ssl::ShutdownException::ice_print(ostream& out) const +{ + SecurityException::ice_print(out); +} + +void +IceSecurity::Ssl::ProtocolException::ice_print(ostream& out) const +{ + SecurityException::ice_print(out); +} + +void +IceSecurity::Ssl::CertificateException::ice_print(ostream& out) const +{ + SecurityException::ice_print(out); +} + +void +IceSecurity::Ssl::OpenSSL::ContextException::ice_print(ostream& out) const +{ + SecurityException::ice_print(out); +} + diff --git a/cpp/src/Ice/SslAcceptor.cpp b/cpp/src/Ice/SslAcceptor.cpp index 27e538bf833..e9a4987be18 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/SecurityException.h>
-#include <sstream>
+#include <Ice/SecurityException.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,58 +101,58 @@ IceInternal::SslAcceptor::accept(int timeout) s << "accepted ssl connection\n" << fdToString(fd); _logger->trace(_traceLevels->networkCat, s.str()); } -
- 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
- { - 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;
+ + 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 + { + 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 ad5ddb34488..eb2ace00b13 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 840112324ba..b423813441e 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 0c1a42146ed..9247819d4e5 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 69452024235..1cd72d3a482 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 cc1d8e1f2e4..73e636292d4 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 d1eb8a03578..830b3df076f 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 6333726cf33..6d8eca2ea80 100644 --- a/cpp/src/Ice/SslConfig.cpp +++ b/cpp/src/Ice/SslConfig.cpp @@ -1,596 +1,596 @@ -// **********************************************************************
-//
-// 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/SecurityException.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)
- {
- ConfigParseException configEx(__FILE__, __LINE__);
-
- ostringstream s;
- s << "While parsing " << _configFile << flush;
- s << "Xerces-c Init Exception: " << DOMString(toCatch.getMessage());
-
- configEx._message = s.str();
-
- throw configEx;
- }
-
- 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;
- }
-
- ConfigParseException configEx(__FILE__, __LINE__);
-
- ostringstream s;
- s << "While parsing " << _configFile << flush;
- s << "Xerces-c Parsing Error: " << DOMString(e.getMessage());
-
- configEx._message = s.str();
-
- throw configEx;
- }
- catch (const DOM_DOMException& e)
- {
- if (errReporter != 0)
- {
- delete errReporter;
- }
-
- ConfigParseException configEx(__FILE__, __LINE__);
-
- ostringstream s;
- s << "While parsing " << _configFile << flush;
- s << "Xerces-c DOM Parsing Error, DOMException code: " << e.code;
- s << ", message: " << e.msg;
-
- configEx._message = s.str();
-
- throw configEx;
- }
- catch (...)
- {
- if (errReporter != 0)
- {
- delete errReporter;
- }
-
- ConfigParseException configEx(__FILE__, __LINE__);
-
- configEx._message = "While parsing " + _configFile + "\n" + "An unknown error occured during parsing.";
-
- throw configEx;
- }
-
- if (errReporter != 0)
- {
- delete errReporter;
- }
-
- if (errorCount)
- {
- ConfigParseException configEx(__FILE__, __LINE__);
-
- configEx._message = errorCount + "errors occured during parsing.";
-
- throw configEx;
- }
-}
-
-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;
-}
-
+// ********************************************************************** +// +// 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/SecurityException.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) + { + ConfigParseException configEx(__FILE__, __LINE__); + + ostringstream s; + s << "While parsing " << _configFile << flush; + s << "Xerces-c Init Exception: " << DOMString(toCatch.getMessage()); + + configEx._message = s.str(); + + throw configEx; + } + + 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; + } + + ConfigParseException configEx(__FILE__, __LINE__); + + ostringstream s; + s << "While parsing " << _configFile << flush; + s << "Xerces-c Parsing Error: " << DOMString(e.getMessage()); + + configEx._message = s.str(); + + throw configEx; + } + catch (const DOM_DOMException& e) + { + if (errReporter != 0) + { + delete errReporter; + } + + ConfigParseException configEx(__FILE__, __LINE__); + + ostringstream s; + s << "While parsing " << _configFile << flush; + s << "Xerces-c DOM Parsing Error, DOMException code: " << e.code; + s << ", message: " << e.msg; + + configEx._message = s.str(); + + throw configEx; + } + catch (...) + { + if (errReporter != 0) + { + delete errReporter; + } + + ConfigParseException configEx(__FILE__, __LINE__); + + configEx._message = "While parsing " + _configFile + "\n" + "An unknown error occured during parsing."; + + throw configEx; + } + + if (errReporter != 0) + { + delete errReporter; + } + + if (errorCount) + { + ConfigParseException configEx(__FILE__, __LINE__); + + configEx._message = errorCount + "errors occured during parsing."; + + throw configEx; + } +} + +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 3a0a7cd6c55..476e5dde530 100644 --- a/cpp/src/Ice/SslConfig.h +++ b/cpp/src/Ice/SslConfig.h @@ -1,97 +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(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
+// ********************************************************************** +// +// 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 bd466b4a611..eab3948a665 100644 --- a/cpp/src/Ice/SslConfigErrorReporter.cpp +++ b/cpp/src/Ice/SslConfigErrorReporter.cpp @@ -1,85 +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 (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
-}
-
+// ********************************************************************** +// +// 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 7e01761076e..4de2df0e6b9 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 0bd0a587bda..e65b297304b 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 3b3fba3554f..a17ab2f9197 100644 --- a/cpp/src/Ice/SslConnectionOpenSSL.cpp +++ b/cpp/src/Ice/SslConnectionOpenSSL.cpp @@ -1,770 +1,770 @@ -// **********************************************************************
-//
-// 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/SecurityException.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)
- {
- ProtocolException protocolEx(__FILE__, __LINE__);
-
- // Protocol Error: Unexpected EOF
- protocolEx._message = "Encountered an EOF that violates the SSL Protocol.";
-
- ICE_SSLERRORS(protocolEx._message);
- ICE_EXCEPTION(protocolEx._message);
-
- throw protocolEx;
- }
- }
-
- case SSL_ERROR_SSL:
- {
- ProtocolException protocolEx(__FILE__, __LINE__);
-
- protocolEx._message = "Encountered a violation of the SSL Protocol.";
-
- ICE_SSLERRORS(protocolEx._message);
- ICE_EXCEPTION(protocolEx._message);
-
- throw protocolEx;
- }
-
- 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);
- }
-}
+// ********************************************************************** +// +// 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/SecurityException.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) + { + ProtocolException protocolEx(__FILE__, __LINE__); + + // Protocol Error: Unexpected EOF + protocolEx._message = "Encountered an EOF that violates the SSL Protocol."; + + ICE_SSLERRORS(protocolEx._message); + ICE_EXCEPTION(protocolEx._message); + + throw protocolEx; + } + } + + case SSL_ERROR_SSL: + { + ProtocolException protocolEx(__FILE__, __LINE__); + + protocolEx._message = "Encountered a violation of the SSL Protocol."; + + ICE_SSLERRORS(protocolEx._message); + ICE_EXCEPTION(protocolEx._message); + + throw protocolEx; + } + + 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 fa14a3542f6..c0c8be8b5b3 100644 --- a/cpp/src/Ice/SslConnectionOpenSSL.h +++ b/cpp/src/Ice/SslConnectionOpenSSL.h @@ -1,116 +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);
-
- // 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
+// ********************************************************************** +// +// 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 02b29b61012..9634855fd21 100644 --- a/cpp/src/Ice/SslConnectionOpenSSLClient.cpp +++ b/cpp/src/Ice/SslConnectionOpenSSLClient.cpp @@ -1,489 +1,489 @@ -// **********************************************************************
-//
-// 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/SecurityException.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
- {
- ProtocolException protocolEx(__FILE__, __LINE__);
-
- // Protocol Error: Unexpected EOF
- protocolEx._message = "Encountered an EOF during handshake that violates the SSL Protocol.\n";
-
- ICE_SSLERRORS(protocolEx._message);
- ICE_EXCEPTION(protocolEx._message);
-
- throw protocolEx;
- }
- }
-
- case SSL_ERROR_SSL:
- {
- ProtocolException protocolEx(__FILE__, __LINE__);
-
- protocolEx._message = "Encountered a violation of the SSL Protocol during handshake.\n";
-
- ICE_SSLERRORS(protocolEx._message);
- ICE_EXCEPTION(protocolEx._message);
-
- throw protocolEx;
- }
- }
-
- 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)
- {
- ProtocolException protocolEx(__FILE__, __LINE__);
-
- // Protocol Error: Unexpected EOF
- protocolEx._message = "Encountered an EOF that violates the SSL Protocol.\n";
-
- ICE_SSLERRORS(protocolEx._message);
- ICE_EXCEPTION(protocolEx._message);
-
- throw protocolEx;
- }
- 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:
- {
- ProtocolException protocolEx(__FILE__, __LINE__);
-
- protocolEx._message = "Encountered a violation of the SSL Protocol.\n";
-
- ICE_SSLERRORS(protocolEx._message);
- ICE_EXCEPTION(protocolEx._message);
-
- throw protocolEx;
- }
-
- 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()");
-}
+// ********************************************************************** +// +// 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/SecurityException.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 + { + ProtocolException protocolEx(__FILE__, __LINE__); + + // Protocol Error: Unexpected EOF + protocolEx._message = "Encountered an EOF during handshake that violates the SSL Protocol.\n"; + + ICE_SSLERRORS(protocolEx._message); + ICE_EXCEPTION(protocolEx._message); + + throw protocolEx; + } + } + + case SSL_ERROR_SSL: + { + ProtocolException protocolEx(__FILE__, __LINE__); + + protocolEx._message = "Encountered a violation of the SSL Protocol during handshake.\n"; + + ICE_SSLERRORS(protocolEx._message); + ICE_EXCEPTION(protocolEx._message); + + throw protocolEx; + } + } + + 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) + { + ProtocolException protocolEx(__FILE__, __LINE__); + + // Protocol Error: Unexpected EOF + protocolEx._message = "Encountered an EOF that violates the SSL Protocol.\n"; + + ICE_SSLERRORS(protocolEx._message); + ICE_EXCEPTION(protocolEx._message); + + throw protocolEx; + } + 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: + { + ProtocolException protocolEx(__FILE__, __LINE__); + + protocolEx._message = "Encountered a violation of the SSL Protocol.\n"; + + ICE_SSLERRORS(protocolEx._message); + ICE_EXCEPTION(protocolEx._message); + + throw protocolEx; + } + + 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 cf2d36ee36c..48e9b2725e6 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 772f2587d00..c13995e07b2 100644 --- a/cpp/src/Ice/SslConnectionOpenSSLServer.cpp +++ b/cpp/src/Ice/SslConnectionOpenSSLServer.cpp @@ -1,475 +1,475 @@ -// **********************************************************************
-//
-// 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/SecurityException.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)
- {
- CertificateException certEx(__FILE__, __LINE__);
-
- certEx._message = "SSL certificate verification error.";
-
- ICE_EXCEPTION(certEx._message);
-
- throw certEx;
- }
- else
- {
- ProtocolException protocolEx(__FILE__, __LINE__);
-
- protocolEx._message = "Encountered an SSL Protocol violation during handshake.";
-
- ICE_SSLERRORS(protocolEx._message);
- ICE_EXCEPTION(protocolEx._message);
-
- throw protocolEx;
- }
- }
-
- 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
- {
- ProtocolException protocolEx(__FILE__, __LINE__);
-
- // Protocol Error: Unexpected EOF
- protocolEx._message = "Encountered an EOF during handshake that violates the SSL Protocol.";
-
- ICE_SSLERRORS(protocolEx._message);
- ICE_EXCEPTION(protocolEx._message);
-
- throw protocolEx;
- }
- }
-
- case SSL_ERROR_SSL:
- {
- ProtocolException protocolEx(__FILE__, __LINE__);
-
- protocolEx._message = "Encountered a violation of the SSL Protocol during handshake.";
-
- ICE_SSLERRORS(protocolEx._message);
- ICE_EXCEPTION(protocolEx._message);
-
- throw protocolEx;
- }
- }
-
- 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
- {
- ProtocolException protocolEx(__FILE__, __LINE__);
-
- // Protocol Error: Unexpected EOF
- protocolEx._message = "Encountered an EOF that violates the SSL Protocol.";
-
- ICE_SSLERRORS(protocolEx._message);
- ICE_EXCEPTION(protocolEx._message);
-
- throw protocolEx;
- }
- }
-
- case SSL_ERROR_SSL:
- {
- ProtocolException protocolEx(__FILE__, __LINE__);
-
- protocolEx._message = "Encountered a violation of the SSL Protocol.";
-
- ICE_SSLERRORS(protocolEx._message);
- ICE_EXCEPTION(protocolEx._message);
-
- throw protocolEx;
- }
-
- 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()");
-}
+// ********************************************************************** +// +// 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/SecurityException.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) + { + CertificateException certEx(__FILE__, __LINE__); + + certEx._message = "SSL certificate verification error."; + + ICE_EXCEPTION(certEx._message); + + throw certEx; + } + else + { + ProtocolException protocolEx(__FILE__, __LINE__); + + protocolEx._message = "Encountered an SSL Protocol violation during handshake."; + + ICE_SSLERRORS(protocolEx._message); + ICE_EXCEPTION(protocolEx._message); + + throw protocolEx; + } + } + + 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 + { + ProtocolException protocolEx(__FILE__, __LINE__); + + // Protocol Error: Unexpected EOF + protocolEx._message = "Encountered an EOF during handshake that violates the SSL Protocol."; + + ICE_SSLERRORS(protocolEx._message); + ICE_EXCEPTION(protocolEx._message); + + throw protocolEx; + } + } + + case SSL_ERROR_SSL: + { + ProtocolException protocolEx(__FILE__, __LINE__); + + protocolEx._message = "Encountered a violation of the SSL Protocol during handshake."; + + ICE_SSLERRORS(protocolEx._message); + ICE_EXCEPTION(protocolEx._message); + + throw protocolEx; + } + } + + 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 + { + ProtocolException protocolEx(__FILE__, __LINE__); + + // Protocol Error: Unexpected EOF + protocolEx._message = "Encountered an EOF that violates the SSL Protocol."; + + ICE_SSLERRORS(protocolEx._message); + ICE_EXCEPTION(protocolEx._message); + + throw protocolEx; + } + } + + case SSL_ERROR_SSL: + { + ProtocolException protocolEx(__FILE__, __LINE__); + + protocolEx._message = "Encountered a violation of the SSL Protocol."; + + ICE_SSLERRORS(protocolEx._message); + ICE_EXCEPTION(protocolEx._message); + + throw protocolEx; + } + + 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 183b3cb3a90..4ee9d4ecb95 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 07ead39fc11..dbba59701d8 100644 --- a/cpp/src/Ice/SslConnector.cpp +++ b/cpp/src/Ice/SslConnector.cpp @@ -6,34 +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/SecurityException.h>
-#include <sstream>
+#include <Ice/SecurityException.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 std::ostringstream; +using std::string; +using IceSecurity::Ssl::Connection; +using IceSecurity::Ssl::Factory; +using IceSecurity::Ssl::System; + TransceiverPtr IceInternal::SslConnector::connect(int timeout) { @@ -54,57 +54,57 @@ IceInternal::SslConnector::connect(int timeout) _logger->trace(_traceLevels->networkCat, s.str()); } - 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;
+ 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/SslFactory.cpp b/cpp/src/Ice/SslFactory.cpp index d565fee8728..54e0af0a8fc 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 bb226619d6d..44b02f49a4b 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 6c804c1027f..5d32a43c9d9 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 024b14a6461..f8f06f8443d 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 04a8059676d..947bf48f556 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 9fd62fa01ff..fe585fd212f 100644 --- a/cpp/src/Ice/SslSystem.h +++ b/cpp/src/Ice/SslSystem.h @@ -1,79 +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>
-#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
+// ********************************************************************** +// +// 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 cefd35e811d..46a8da9c00b 100644 --- a/cpp/src/Ice/SslSystemOpenSSL.cpp +++ b/cpp/src/Ice/SslSystemOpenSSL.cpp @@ -1,1584 +1,1584 @@ -// **********************************************************************
-//
-// 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/SecurityException.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)
- {
- ContextException contextEx(__FILE__, __LINE__);
-
- contextEx._message = "Unable to get certificate from '";
- contextEx._message += publicFile;
- contextEx._message += "'\n";
- contextEx._message += sslGetErrors();
-
- ICE_EXCEPTION(contextEx._message);
-
- throw contextEx;
- }
-
- 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)
- {
- ContextException contextEx(__FILE__, __LINE__);
-
- contextEx._message = "Unable to get private key from '";
- contextEx._message += privKeyFile;
- contextEx._message += "'\n";
- contextEx._message += sslGetErrors();
-
- ICE_EXCEPTION(contextEx._message);
-
- throw contextEx;
- }
-
- // 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))
- {
- ContextException contextEx(__FILE__, __LINE__);
-
- contextEx._message = "Private key does not match the certificate public key.";
- string sslError = sslGetErrors();
-
- if (!sslError.empty())
- {
- contextEx._message += "\n";
- contextEx._message += sslError;
- }
-
- ICE_EXCEPTION(contextEx._message);
-
- throw contextEx;
- }
- }
-
- 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)
- {
- ContextException contextEx(__FILE__, __LINE__);
-
- contextEx._message = "Unable to create SSL Context.\n" + sslGetErrors();
-
- ICE_EXCEPTION(contextEx._message);
-
- throw contextEx;
- }
-
- // Turn off session caching, supposedly fixes a problem with multithreading.
- SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
-
- 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()");
-}
+// ********************************************************************** +// +// 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/SecurityException.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) + { + ContextException contextEx(__FILE__, __LINE__); + + contextEx._message = "Unable to get certificate from '"; + contextEx._message += publicFile; + contextEx._message += "'\n"; + contextEx._message += sslGetErrors(); + + ICE_EXCEPTION(contextEx._message); + + throw contextEx; + } + + 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) + { + ContextException contextEx(__FILE__, __LINE__); + + contextEx._message = "Unable to get private key from '"; + contextEx._message += privKeyFile; + contextEx._message += "'\n"; + contextEx._message += sslGetErrors(); + + ICE_EXCEPTION(contextEx._message); + + throw contextEx; + } + + // 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)) + { + ContextException contextEx(__FILE__, __LINE__); + + contextEx._message = "Private key does not match the certificate public key."; + string sslError = sslGetErrors(); + + if (!sslError.empty()) + { + contextEx._message += "\n"; + contextEx._message += sslError; + } + + ICE_EXCEPTION(contextEx._message); + + throw contextEx; + } + } + + 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) + { + ContextException contextEx(__FILE__, __LINE__); + + contextEx._message = "Unable to create SSL Context.\n" + sslGetErrors(); + + ICE_EXCEPTION(contextEx._message); + + throw contextEx; + } + + // Turn off session caching, supposedly fixes a problem with multithreading. + SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF); + + 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 ad1d7e81eac..d09e1efd696 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 3deebdffd59..6397175865b 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 47048a5bc0b..a150673909b 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 47fc85a627e..03186976538 100644 --- a/cpp/src/Ice/SslTransceiver.cpp +++ b/cpp/src/Ice/SslTransceiver.cpp @@ -7,22 +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 <sstream>
+#include <sstream> using namespace std; using namespace Ice; using namespace IceInternal; -
+ int IceInternal::SslTransceiver::fd() { @@ -32,8 +32,8 @@ IceInternal::SslTransceiver::fd() void IceInternal::SslTransceiver::close() { - ICE_METHOD_INV("SslTransceiver::close()");
-
+ ICE_METHOD_INV("SslTransceiver::close()"); + if (_traceLevels->network >= 1) { ostringstream s; @@ -42,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); -
- ICE_METHOD_RET("SslTransceiver::close()");
+ + ICE_METHOD_RET("SslTransceiver::close()"); } void IceInternal::SslTransceiver::shutdown() { - ICE_METHOD_INV("SslTransceiver::shutdown()");
-
+ ICE_METHOD_INV("SslTransceiver::shutdown()"); + if (_traceLevels->network >= 2) { ostringstream s; @@ -63,31 +63,31 @@ IceInternal::SslTransceiver::shutdown() } ::shutdown(_fd, SHUT_WR); // Shutdown socket for writing -
- ICE_METHOD_RET("SslTransceiver::shutdown()");
+ + ICE_METHOD_RET("SslTransceiver::shutdown()"); } void IceInternal::SslTransceiver::write(Buffer& buf, int timeout) -{
- ICE_METHOD_INV("SslTransceiver::write()")
- _sslConnection->write(buf, timeout);
- ICE_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) { - ICE_METHOD_INV("SslTransceiver::read()");
-
- if (!_sslConnection->read(buf, timeout))
- {
- ConnectionLostException clEx(__FILE__, __LINE__);
- clEx.error = 0;
- throw clEx;
- }
-
- ICE_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 @@ -96,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); } @@ -112,17 +112,17 @@ IceInternal::SslTransceiver::SslTransceiver(const InstancePtr& instance, int fd, IceInternal::SslTransceiver::~SslTransceiver() { assert(_fd == INVALID_SOCKET); -
- cleanUpSSL();
+ + cleanUpSSL(); +} + +void +IceInternal::SslTransceiver::cleanUpSSL() +{ + if (_sslConnection != 0) + { + _sslConnection->shutdown(); + delete _sslConnection; + _sslConnection = 0; + } } -
-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 13c3ab8998f..c4a1290e12f 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; }; } |