diff options
author | Anthony Neal <aneal@zeroc.com> | 2002-09-13 10:36:31 +0000 |
---|---|---|
committer | Anthony Neal <aneal@zeroc.com> | 2002-09-13 10:36:31 +0000 |
commit | aacdab0bfc03b9e1e3aa3b58223359d7858aced9 (patch) | |
tree | 1841c95649f16a5131629f6ea5f23637ad6ef54b /cpp/src/IceSSL/ContextOpenSSL.cpp | |
parent | fixes (diff) | |
download | ice-aacdab0bfc03b9e1e3aa3b58223359d7858aced9.tar.bz2 ice-aacdab0bfc03b9e1e3aa3b58223359d7858aced9.tar.xz ice-aacdab0bfc03b9e1e3aa3b58223359d7858aced9.zip |
Cleanup of IceSSL, removal of OpenSSL namespace.
Diffstat (limited to 'cpp/src/IceSSL/ContextOpenSSL.cpp')
-rw-r--r-- | cpp/src/IceSSL/ContextOpenSSL.cpp | 660 |
1 files changed, 0 insertions, 660 deletions
diff --git a/cpp/src/IceSSL/ContextOpenSSL.cpp b/cpp/src/IceSSL/ContextOpenSSL.cpp deleted file mode 100644 index 405e4379c58..00000000000 --- a/cpp/src/IceSSL/ContextOpenSSL.cpp +++ /dev/null @@ -1,660 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2002 -// Mutable Realms, Inc. -// Huntsville, AL, USA -// -// All Rights Reserved -// -// ********************************************************************** - -#include <Ice/Logger.h> -#include <Ice/Properties.h> - -#include <IceSSL/DefaultCertificateVerifier.h> -#include <IceSSL/Exception.h> -#include <IceSSL/RSAKeyPair.h> -#include <IceSSL/CertificateDesc.h> -#include <IceSSL/SslTransceiver.h> -#include <IceSSL/ContextOpenSSL.h> -#include <IceSSL/OpenSSLJanitors.h> -#include <IceSSL/OpenSSLUtils.h> -#include <IceSSL/TraceLevels.h> - -#include <openssl/err.h> - -using namespace std; -using namespace Ice; -using namespace IceInternal; - -void ::IceInternal::incRef(::IceSSL::Context* p) { p->__incRef(); } -void ::IceInternal::decRef(::IceSSL::Context* p) { p->__decRef(); } - -IceSSL::Context::~Context() -{ - if(_sslContext != 0) - { - SSL_CTX_free(_sslContext); - - _sslContext = 0; - } -} - -bool -IceSSL::Context::isConfigured() -{ - return (_sslContext != 0 ? true : false); -} - -void -IceSSL::Context::setCertificateVerifier(const OpenSSL::CertificateVerifierPtr& verifier) -{ - _certificateVerifier = verifier; -} - -void -IceSSL::Context::addTrustedCertificateBase64(const string& trustedCertString) -{ - OpenSSL::RSAPublicKey pubKey(trustedCertString); - - addTrustedCertificate(pubKey); -} - -void -IceSSL::Context::addTrustedCertificate(const Ice::ByteSeq& trustedCert) -{ - OpenSSL::RSAPublicKey pubKey(trustedCert); - - addTrustedCertificate(pubKey); -} - -void -IceSSL::Context::setRSAKeysBase64(const string& privateKey, - const string& publicKey) -{ - if(privateKey.empty()) - { - IceSSL::PrivateKeyException privateKeyEx(__FILE__, __LINE__); - - privateKeyEx.message = "Empty private key supplied."; - - throw privateKeyEx; - } - - addKeyCert(privateKey, publicKey); -} - -void -IceSSL::Context::setRSAKeys(const Ice::ByteSeq& privateKey, const Ice::ByteSeq& publicKey) -{ - if(privateKey.empty()) - { - IceSSL::PrivateKeyException privateKeyEx(__FILE__, __LINE__); - - privateKeyEx.message = "Empty private key supplied."; - - throw privateKeyEx; - } - - addKeyCert(privateKey, publicKey); -} - -void -IceSSL::Context::configure(const GeneralConfig& generalConfig, - const CertificateAuthority& certificateAuthority, - const BaseCertificates& baseCertificates) -{ - // Create an SSL Context based on the context params. - createContext(generalConfig.getProtocol()); - - // Get the cipherlist and set it in the context. - setCipherList(generalConfig.getCipherList()); - - // Set the certificate verification mode. - SSL_CTX_set_verify(_sslContext, generalConfig.getVerifyMode(), verifyCallback); - - // Set the certificate verify depth - SSL_CTX_set_verify_depth(_sslContext, generalConfig.getVerifyDepth()); - - // Determine the number of retries the user gets on passphrase entry. - string passphraseRetries = _properties->getPropertyWithDefault(_passphraseRetriesProperty, - _maxPassphraseRetriesDefault); - int retries = atoi(passphraseRetries.c_str()); - retries = (retries < 0 ? 0 : retries); - _maxPassphraseTries = retries + 1; - - // Process the RSA Certificate - setKeyCert(baseCertificates.getRSACert(), _rsaPrivateKeyProperty, _rsaPublicKeyProperty); - - // Process the DSA Certificate - setKeyCert(baseCertificates.getDSACert(), _dsaPrivateKeyProperty, _dsaPublicKeyProperty); - - // Set the DH key agreement parameters. - if(baseCertificates.getDHParams().getKeySize() != 0) - { - setDHParams(baseCertificates); - } -} - -// -// Protected -// - -IceSSL::Context::Context(const TraceLevelsPtr& traceLevels, const LoggerPtr& logger, const PropertiesPtr& properties) : - _traceLevels(traceLevels), - _logger(logger), - _properties(properties) -{ - _certificateVerifier = new OpenSSL::DefaultCertificateVerifier(traceLevels, logger); - _sslContext = 0; - - _maxPassphraseRetriesDefault = "4"; -} - -SSL_METHOD* -IceSSL::Context::getSslMethod(SslProtocol sslVersion) -{ - 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 : - { - if(_traceLevels->security >= IceSSL::SECURITY_WARNINGS) - { - string errorString; - - errorString = "ssl version "; - errorString += sslVersion; - errorString += " not supported (defaulting to SSL_V23)"; - _logger->trace(_traceLevels->securityCat, "WRN " + errorString); - } - - sslMethod = SSLv23_method(); - } - } - - return sslMethod; -} - -void -IceSSL::Context::createContext(SslProtocol sslProtocol) -{ - if(_sslContext != 0) - { - SSL_CTX_free(_sslContext); - _sslContext = 0; - } - - _sslContext = SSL_CTX_new(getSslMethod(sslProtocol)); - - if(_sslContext == 0) - { - OpenSSL::ContextInitializationException contextInitEx(__FILE__, __LINE__); - - contextInitEx.message = "unable to create ssl context\n" + OpenSSL::sslGetErrors(); - - throw contextInitEx; - } - - // Turn off session caching, supposedly fixes a problem with multithreading. - SSL_CTX_set_session_cache_mode(_sslContext, SSL_SESS_CACHE_OFF); -} - -void -IceSSL::Context::loadCertificateAuthority(const CertificateAuthority& certAuth) -{ - assert(_sslContext != 0); - - string fileName = certAuth.getCAFileName(); - string certPath = certAuth.getCAPath(); - - const char* caFile = 0; - const char* caPath = 0; - - // The following checks are required to send the expected values to the OpenSSL library. - // It does not like receiving "", but prefers NULLs. - - if(!fileName.empty()) - { - caFile = fileName.c_str(); - } - - if(!certPath.length()) - { - caPath = certPath.c_str(); - } - - // SSL_CTX_set_default_passwd_cb(sslContext, passwordCallback); - - // Check the Certificate Authority file(s). - int loadVerifyRet = SSL_CTX_load_verify_locations(_sslContext, caFile, caPath); - - if(!loadVerifyRet) - { - if(_traceLevels->security >= IceSSL::SECURITY_WARNINGS) - { - _logger->trace(_traceLevels->securityCat, "WRN unable to load certificate authorities."); - } - } - else - { - int setDefaultVerifyPathsRet = SSL_CTX_set_default_verify_paths(_sslContext); - - - if(!setDefaultVerifyPathsRet && (_traceLevels->security >= IceSSL::SECURITY_WARNINGS)) - { - _logger->trace(_traceLevels->securityCat, "WRN unable to verify certificate authorities."); - } - } - - // Now we add whatever override/addition that we wish to put into the trusted certificates list - string caCertBase64 = _properties->getProperty(_caCertificateProperty); - if(!caCertBase64.empty()) - { - addTrustedCertificateBase64(caCertBase64); - } -} - -void -IceSSL::Context::setKeyCert(const CertificateDesc& certDesc, - const string& privateProperty, - const string& publicProperty) -{ - string privateKey; - string publicKey; - - if(!privateProperty.empty()) - { - privateKey = _properties->getProperty(privateProperty); - } - - if(!publicProperty.empty()) - { - publicKey = _properties->getProperty(publicProperty); - } - - if(!privateKey.empty() && !publicKey.empty()) - { - addKeyCert(privateKey, publicKey); - } - else if(certDesc.getKeySize() != 0) - { - const CertificateFile& privateKey = certDesc.getPrivate(); - const CertificateFile& publicKey = certDesc.getPublic(); - - addKeyCert(privateKey, publicKey); - } -} - -void -IceSSL::Context::checkKeyCert() -{ - assert(_sslContext != 0); - - // 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)) - { - OpenSSL::CertificateKeyMatchException certKeyMatchEx(__FILE__, __LINE__); - - certKeyMatchEx.message = "private key does not match the certificate public key"; - string sslError = OpenSSL::sslGetErrors(); - - if(!sslError.empty()) - { - certKeyMatchEx.message += "\n"; - certKeyMatchEx.message += sslError; - } - - throw certKeyMatchEx; - } -} - -void -IceSSL::Context::addTrustedCertificate(const OpenSSL::RSAPublicKey& trustedCertificate) -{ - if(_sslContext == 0) - { - OpenSSL::ContextNotConfiguredException contextConfigEx(__FILE__, __LINE__); - - contextConfigEx.message = "ssl context not configured"; - - throw contextConfigEx; - } - - X509_STORE* certStore = SSL_CTX_get_cert_store(_sslContext); - - assert(certStore != 0); - - if(X509_STORE_add_cert(certStore, trustedCertificate.getX509PublicKey()) == 0) - { - OpenSSL::TrustedCertificateAddException trustEx(__FILE__, __LINE__); - - trustEx.message = OpenSSL::sslGetErrors(); - - throw trustEx; - } -} - -void -IceSSL::Context::addKeyCert(const CertificateFile& privateKey, const CertificateFile& publicCert) -{ - assert(_sslContext != 0); - - 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) - { - OpenSSL::CertificateLoadException certLoadEx(__FILE__, __LINE__); - - certLoadEx.message = "unable to load certificate from '"; - certLoadEx.message += publicFile; - certLoadEx.message += "'\n"; - certLoadEx.message += OpenSSL::sslGetErrors(); - - throw certLoadEx; - } - - if(privateKey.getFileName().empty()) - { - if(_traceLevels->security >= IceSSL::SECURITY_WARNINGS) - { - _logger->trace(_traceLevels->securityCat, "WRN no private key specified -- using the certificate"); - } - - privKeyFile = publicFile; - privKeyFileType = publicEncoding; - } - - int retryCount = 0; - int pkLoadResult; - int errCode = 0; - - while(retryCount != _maxPassphraseTries) - { - // We ignore the errors and remove them from the stack. - string errorString = OpenSSL::sslGetErrors(); - - // Set which Private Key file to use. - pkLoadResult = SSL_CTX_use_PrivateKey_file(_sslContext, privKeyFile, privKeyFileType); - - if(pkLoadResult <= 0) - { - errCode = ERR_GET_REASON(ERR_peek_error()); - } - else - { - // The load went fine - continue on. - break; - } - - // PEM errors, most likely related to a bad passphrase. - if(errCode != PEM_R_BAD_PASSWORD_READ && - errCode != PEM_R_BAD_DECRYPT && - errCode != PEM_R_BAD_BASE64_DECODE) - { - // Other errors get dealt with below. - break; - } - - cout << "Passphrase error!" << endl; - - retryCount++; - } - - if(pkLoadResult <= 0) - { - int errCode = ERR_GET_REASON(ERR_peek_error()); - - // Note: Because OpenSSL currently (V0.9.6b) performs a check to see if the - // key matches the private key when calling SSL_CTX_use_PrivateKey_file(). - if(errCode == X509_R_KEY_VALUES_MISMATCH || errCode == X509_R_KEY_TYPE_MISMATCH) - { - OpenSSL::CertificateKeyMatchException certKeyMatchEx(__FILE__, __LINE__); - - certKeyMatchEx.message = "private key does not match the certificate public key"; - string sslError = OpenSSL::sslGetErrors(); - - if(!sslError.empty()) - { - certKeyMatchEx.message += "\n"; - certKeyMatchEx.message += sslError; - } - - throw certKeyMatchEx; - } - else - { - OpenSSL::PrivateKeyLoadException pklEx(__FILE__, __LINE__); - - pklEx.message = "unable to load private key from '"; - pklEx.message += privKeyFile; - pklEx.message += "'\n"; - pklEx.message += OpenSSL::sslGetErrors(); - - throw pklEx; - } - } - - checkKeyCert(); - } -} - -void -IceSSL::Context::addKeyCert(const OpenSSL::RSAKeyPair& keyPair) -{ - if(_sslContext == 0) - { - OpenSSL::ContextNotConfiguredException contextConfigEx(__FILE__, __LINE__); - - contextConfigEx.message = "ssl context not configured"; - - throw contextConfigEx; - } - - // Note: Normally I would use an X509Janitor and RSAJanitor to ensure that - // memory was being freed properly when exceptions are thrown, but - // both SSL_CTX_use_certificate and SSL_CTX_use_RSAPrivateKey free - // certificate/key memory regardless if the call succeeded. - - // Set which Public Key file to use. - if(SSL_CTX_use_certificate(_sslContext, keyPair.getX509PublicKey()) <= 0) - { - OpenSSL::CertificateLoadException certLoadEx(__FILE__, __LINE__); - - certLoadEx.message = "unable to set certificate from memory"; - string sslError = OpenSSL::sslGetErrors(); - - if(!sslError.empty()) - { - certLoadEx.message += "\n"; - certLoadEx.message += sslError; - } - - throw certLoadEx; - } - - // Set which Private Key file to use. - if(SSL_CTX_use_RSAPrivateKey(_sslContext, keyPair.getRSAPrivateKey()) <= 0) - { - int errCode = ERR_GET_REASON(ERR_peek_error()); - - // Note: Because OpenSSL currently (V0.9.6b) performs a check to see if the - // key matches the private key when calling SSL_CTX_use_PrivateKey_file(). - if(errCode == X509_R_KEY_VALUES_MISMATCH || errCode == X509_R_KEY_TYPE_MISMATCH) - { - OpenSSL::CertificateKeyMatchException certKeyMatchEx(__FILE__, __LINE__); - - certKeyMatchEx.message = "private key does not match the certificate public key"; - string sslError = OpenSSL::sslGetErrors(); - - if(!sslError.empty()) - { - certKeyMatchEx.message += "\n"; - certKeyMatchEx.message += sslError; - } - - throw certKeyMatchEx; - } - else - { - OpenSSL::PrivateKeyLoadException pklEx(__FILE__, __LINE__); - - pklEx.message = "unable to set private key from memory"; - string sslError = OpenSSL::sslGetErrors(); - - if(!sslError.empty()) - { - pklEx.message += "\n"; - pklEx.message += sslError; - } - - throw pklEx; - } - } - - checkKeyCert(); -} - -void -IceSSL::Context::addKeyCert(const Ice::ByteSeq& privateKey, const Ice::ByteSeq& publicKey) -{ - Ice::ByteSeq privKey = privateKey; - - if(privKey.empty()) - { - if(_traceLevels->security >= IceSSL::SECURITY_WARNINGS) - { - _logger->trace(_traceLevels->securityCat, "WRN no private key specified -- using the certificate"); - } - - privKey = publicKey; - } - - // Make a key pair based on the DER encoded byte sequences. - addKeyCert(OpenSSL::RSAKeyPair(privKey, publicKey)); -} - -void -IceSSL::Context::addKeyCert(const string& privateKey, const string& publicKey) -{ - string privKey = privateKey; - - if(privKey.empty()) - { - if(_traceLevels->security >= IceSSL::SECURITY_WARNINGS) - { - _logger->trace(_traceLevels->securityCat, "WRN no private key specified -- using the certificate"); - } - - privKey = publicKey; - } - - // Make a key pair based on the Base64 encoded strings. - addKeyCert(OpenSSL::RSAKeyPair(privKey, publicKey)); -} - -SSL* -IceSSL::Context::createSSLConnection(int socket) -{ - assert(_sslContext != 0); - - SSL* sslConnection = SSL_new(_sslContext); - assert(sslConnection != 0); - - SSL_clear(sslConnection); - - SSL_set_fd(sslConnection, socket); - - return sslConnection; -} - -void -IceSSL::Context::transceiverSetup(const SslTransceiverPtr& transceiver) -{ - // Set the Post-Handshake Read timeout - // This timeout is implemented once on the first read after hanshake. - int handshakeReadTimeout = _properties->getPropertyAsIntWithDefault(_handshakeTimeoutProperty, 5000); - transceiver->setHandshakeReadTimeout(handshakeReadTimeout); -} - -void -IceSSL::Context::setCipherList(const string& cipherList) -{ - assert(_sslContext != 0); - - if(!cipherList.empty() && (!SSL_CTX_set_cipher_list(_sslContext, cipherList.c_str())) && - (_traceLevels->security >= IceSSL::SECURITY_WARNINGS)) - { - string errorString = "WRN error setting cipher list " + cipherList + " -- using default list\n"; - errorString += OpenSSL::sslGetErrors(); - _logger->trace(_traceLevels->securityCat, errorString); - } -} - -void -IceSSL::Context::setDHParams(const BaseCertificates& baseCerts) -{ - DH* dh = 0; - - string dhFile = baseCerts.getDHParams().getFileName(); - int encoding = baseCerts.getDHParams().getEncoding(); - - // File type must be PEM - that's the only way we can load DH Params, apparently. - if((!dhFile.empty()) && (encoding == SSL_FILETYPE_PEM)) - { - dh = OpenSSL::loadDHParam(dhFile.c_str()); - } - - if(dh == 0) - { - if(_traceLevels->security >= IceSSL::SECURITY_WARNINGS) - { - _logger->trace(_traceLevels->securityCat, - "WRN Could not load Diffie-Hellman params, generating a temporary 512bit key."); - } - - dh = OpenSSL::getTempDH512(); - } - - if(dh != 0) - { - SSL_CTX_set_tmp_dh(_sslContext, dh); - - DH_free(dh); - } -} |