diff options
Diffstat (limited to 'cpp/src/IceSSL/ContextOpenSSLServer.cpp')
-rw-r--r-- | cpp/src/IceSSL/ContextOpenSSLServer.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/cpp/src/IceSSL/ContextOpenSSLServer.cpp b/cpp/src/IceSSL/ContextOpenSSLServer.cpp new file mode 100644 index 00000000000..d2d9752a53e --- /dev/null +++ b/cpp/src/IceSSL/ContextOpenSSLServer.cpp @@ -0,0 +1,139 @@ +// ********************************************************************** +// +// Copyright (c) 2002 +// MutableRealms, Inc. +// Huntsville, AL, USA +// +// All Rights Reserved +// +// ********************************************************************** + +#include <Ice/TraceLevels.h> +#include <Ice/Logger.h> + +#include <IceSSL/Exception.h> +#include <IceSSL/SslConnectionOpenSSL.h> +#include <IceSSL/ContextOpenSSLServer.h> +#include <IceSSL/SslConnectionOpenSSLServer.h> +#include <IceSSL/OpenSSLUtils.h> + +using namespace std; + +void +IceSSL::OpenSSL::ServerContext::configure(const GeneralConfig& generalConfig, + const CertificateAuthority& certificateAuthority, + const BaseCertificates& baseCertificates) +{ + Context::configure(generalConfig, certificateAuthority, baseCertificates); + + assert(_sslContext != 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(_sslContext, SSL_OP_NON_EXPORT_FIRST); + + // Always use a new DH key when using Diffie-Hellman key agreement. + SSL_CTX_set_options(_sslContext, SSL_OP_SINGLE_DH_USE); + + // Set the RSA Callback routine in case we need to build a temporary (ephemeral) RSA key. + SSL_CTX_set_tmp_rsa_callback(_sslContext, tmpRSACallback); + + // Set the DH Callback routine in case we need a temporary (ephemeral) DH key. + SSL_CTX_set_tmp_dh_callback(_sslContext, tmpDHCallback); + + loadCertificateAuthority(certificateAuthority); + + // Set the session context for the SSL system [SERVER ONLY]. + string connectionContext = generalConfig.getContext(); + SSL_CTX_set_session_id_context(_sslContext, + reinterpret_cast<const unsigned char *>(connectionContext.c_str()), + connectionContext.size()); + + if (_traceLevels->security >= IceSSL::SECURITY_PROTOCOL) + { + ostringstream s; + + s << endl; + s << "general configuration (server)" << endl; + s << "------------------------------" << endl; + s << generalConfig << endl << endl; + + s << "CA file: " << certificateAuthority.getCAFileName() << endl; + s << "CA path: " << certificateAuthority.getCAPath() << endl; + + s << "base certificates (server)" << endl; + s << "--------------------------" << endl; + s << baseCertificates << endl << endl; + + _logger->trace(_traceLevels->securityCat, s.str()); + } +} + +IceSSL::ConnectionPtr +IceSSL::OpenSSL::ServerContext::createConnection(int socket, const PluginBaseIPtr& plugin) +{ + if (_sslContext == 0) + { + ContextNotConfiguredException contextEx(__FILE__, __LINE__); + + throw contextEx; + } + + ConnectionPtr connection = new ServerConnection(_traceLevels, + _logger, + _certificateVerifier, + createSSLConnection(socket), + plugin); + + connectionSetup(connection); + + return connection; +} + +// +// Protected +// + +IceSSL::OpenSSL::ServerContext::ServerContext(const IceInternal::InstancePtr& instance) : + Context(instance) +{ + _rsaPrivateKeyProperty = "IceSSL.Server.Overrides.RSA.PrivateKey"; + _rsaPublicKeyProperty = "IceSSL.Server.Overrides.RSA.Certificate"; + _dsaPrivateKeyProperty = "IceSSL.Server.Overrides.DSA.PrivateKey"; + _dsaPublicKeyProperty = "IceSSL.Server.Overrides.DSA.Certificate"; + _caCertificateProperty = "IceSSL.Server.Overrides.CACertificate"; + _handshakeTimeoutProperty = "IceSSL.Server.Handshake.ReadTimeout"; + _passphraseRetriesProperty = "IceSSL.Client.Passphrase.Retries"; +} + +void +IceSSL::OpenSSL::ServerContext::loadCertificateAuthority(const CertificateAuthority& certAuth) +{ + assert(_sslContext != 0); + + Context::loadCertificateAuthority(certAuth); + + string caFile = certAuth.getCAFileName(); + + if (caFile.empty()) + { + return; + } + + STACK_OF(X509_NAME)* certNames = SSL_load_client_CA_file(caFile.c_str()); + + if (certNames == 0) + { + if (_traceLevels->security >= IceSSL::SECURITY_WARNINGS) + { + string errorString = "unable to load certificate authorities certificate names from " + caFile + "\n"; + errorString += sslGetErrors(); + _logger->trace(_traceLevels->securityCat, "WRN " + errorString); + } + } + else + { + SSL_CTX_set_client_CA_list(_sslContext, certNames); + } +} |