📄 sslcontext.cpp
字号:
X509_NAME_oneline(X509_get_issuer_name(currentCert), buf, 256); String issuerName = String(buf); // // Create the certificate object // // insert at the beginning of the array so that the peer certificate is // first and the root CA is last exData->_rep->peerCertificate.insert(0, new SSLCertificateInfo( subjectName, issuerName, version, serialNumber, notBefore, notAfter, depth, errorCode, errorStr, preVerifyOk)); PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL3, "Created SSLCertificateInfo"); // NOT_YET_VALID checks do not work correctly on subsequent tries -- // Bugzilla#4283 // call this prior to calling the user-specified callback in case they // want to override it if (errorCode == X509_V_OK && (CIMDateTime::getDifference( CIMDateTime::getCurrentDateTime(), notBefore) > 0)) { PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "Certificate was not yet valid."); X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_NOT_YET_VALID); } // // Call the user-specified application callback if it is specified. // If it is null, return OpenSSL's verification code. // Note that the verification result does not automatically get set // to X509_V_OK if the callback is successful. // This is because OpenSSL retains the original default error in case // we want to use it later. // To set the error, we could use X509_STORE_CTX_set_error(ctx, // verifyError); but there is no real benefit to doing that here. // if (exData->_rep->verifyCertificateCallback == NULL) { return preVerifyOk; } else { if (exData->_rep->verifyCertificateCallback( *exData->_rep->peerCertificate[0])) { Tracer::trace(TRC_SSL, Tracer::LEVEL4, "--> SSL: _rep->verifyCertificateCallback() returned " "X509_V_OK"); PEG_METHOD_EXIT(); return 1; } else // verification failed, handshake will be immediately terminated { Tracer::trace(TRC_SSL, Tracer::LEVEL4, "--> SSL: _rep->verifyCertificateCallback() returned error %d", exData->_rep->peerCertificate[0]->getErrorCode()); PEG_METHOD_EXIT(); return 0; } }}//// Callback function called by OpenSSL. This request is merely forwarded// to the static function SSLCallback::callback(). The SSLCallback class// is a friend class of the Pegasus SSL related classes needed to complete// the callback.//extern "C" int prepareForCallback(int preVerifyOk, X509_STORE_CTX *ctx){ return SSLCallback::verificationCallback(preVerifyOk, ctx);}//// Implement OpenSSL locking callback.//void pegasus_locking_callback( int mode, int type, const char* file, int line){ // Check whether the mode is lock or unlock. if ( mode & CRYPTO_LOCK ) { /*Tracer::trace(TRC_SSL, Tracer::LEVEL4, "Now locking for %d", Threads::id());*/ SSLContextRep::_sslLocks.get()[type].lock( ); } else { /*Tracer::trace(TRC_SSL, Tracer::LEVEL4, "Now unlocking for %d", Threads::id());*/ SSLContextRep::_sslLocks.get()[type].unlock( ); }}//// Initialize OpenSSL Locking and id callbacks.//void SSLContextRep::init_ssl(){ // Allocate Memory for _sslLocks. SSL locks needs to be able to handle // up to CRYPTO_num_locks() different mutex locks. PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "Initialized SSL callback.");#ifdef PEGASUS_OS_OS400 // Load the OpenSSL library and get the exports SSL_OS400_Init();#endif _sslLocks.reset(new Mutex[CRYPTO_num_locks()]);#if defined(PEGASUS_HAVE_PTHREADS) && !defined(PEGASUS_OS_VMS) // Set the ID callback. The ID callback returns a thread ID. CRYPTO_set_id_callback((CRYPTO_SET_ID_CALLBACK) pthread_self);#endif // Set the locking callback to pegasus_locking_callback. CRYPTO_set_locking_callback( (CRYPTO_SET_LOCKING_CALLBACK) pegasus_locking_callback);}// Free OpenSSL Locking and id callbacks.void SSLContextRep::free_ssl(){ // Cleanup _sslLocks and set locking & id callback to NULL. CRYPTO_set_locking_callback(NULL); CRYPTO_set_id_callback (NULL); PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "Freed SSL callback."); _sslLocks.reset();}//// SSL context area//// For the OSs that don't have /dev/random device file,// must enable PEGASUS_SSL_RANDOMFILE flag.//SSLContextRep::SSLContextRep( const String& trustStore, const String& certPath, const String& keyPath, const String& crlPath, SSLCertificateVerifyFunction* verifyCert, const String& randomFile){ PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()"); _trustStore = trustStore; _certPath = certPath; _keyPath = keyPath; _crlPath = crlPath; _crlStore = NULL; _certificateVerifyFunction = verifyCert; // // If a truststore and/or peer verification function is specified, // enable peer verification // if (trustStore != String::EMPTY || verifyCert != NULL) { _verifyPeer = true; } else { _verifyPeer = false; } // // Initialize SSL callbacks and increment the SSLContextRep object _counter. // { AutoMutex autoMut(_countRepMutex); Tracer::trace(TRC_SSL, Tracer::LEVEL4, "Value of Countrep in constructor %d", _countRep); if ( _countRep == 0 ) { init_ssl(); // // load SSL library // Tracer::trace(TRC_SSL, Tracer::LEVEL4, "Before calling SSL_load_error_strings %d", Threads::id()); SSL_load_error_strings(); Tracer::trace(TRC_SSL, Tracer::LEVEL4, "After calling SSL_load_error_strings %d", Threads::id()); Tracer::trace(TRC_SSL, Tracer::LEVEL4, "Before calling SSL_library_init %d", Threads::id()); SSL_library_init(); Tracer::trace(TRC_SSL, Tracer::LEVEL4, "After calling SSL_library_init %d", Threads::id()); } _countRep++; } // mutex unlocks here _randomInit(randomFile); _sslContext = _makeSSLContext(); PEG_METHOD_EXIT();}SSLContextRep::SSLContextRep(const SSLContextRep& sslContextRep){ PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::SSLContextRep()"); _trustStore = sslContextRep._trustStore; _certPath = sslContextRep._certPath; _keyPath = sslContextRep._keyPath; _crlPath = sslContextRep._crlPath; _crlStore = sslContextRep._crlStore; _verifyPeer = sslContextRep._verifyPeer; _certificateVerifyFunction = sslContextRep._certificateVerifyFunction; _randomFile = sslContextRep._randomFile; // Initialize SSL callbacks and increment the SSLContextRep object _counter. { AutoMutex autoMut(_countRepMutex); Tracer::trace(TRC_SSL, Tracer::LEVEL4, "Value of Countrep in copy constructor %d", _countRep); if ( _countRep == 0 ) { init_ssl(); } _countRep++; } // mutex unlocks here _sslContext = _makeSSLContext(); PEG_METHOD_EXIT();}//// Destructor//SSLContextRep::~SSLContextRep(){ PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::~SSLContextRep()"); SSL_CTX_free(_sslContext); // Decrement the SSLContextRep object _counter. { AutoMutex autoMut(_countRepMutex); _countRep--; // Free SSL locks if no instances of SSLContextRep exist. Tracer::trace(TRC_SSL, Tracer::LEVEL4, "Value of Countrep in destructor %d", _countRep); if ( _countRep == 0 ) { free_ssl(); } } PEG_METHOD_EXIT();}//// initialize OpenSSL's PRNG//void SSLContextRep::_randomInit(const String& randomFile){ PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_randomInit()"); Boolean ret; int retVal = 0;#ifdef PEGASUS_SSL_RANDOMFILE if ( RAND_status() == 0 ) { // // Initialise OpenSSL random number generator. // if ( randomFile == String::EMPTY ) { PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "Random seed file is required."); PEG_METHOD_EXIT(); MessageLoaderParms parms( "Common.SSLContext.RANDOM_SEED_FILE_REQUIRED", "Random seed file required"); throw SSLException(parms); } // // Try the given random seed file // ret = FileSystem::exists(randomFile); if (ret) { retVal = RAND_load_file(randomFile.getCString(), -1); if ( retVal < 0 ) { PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "Not enough seed data in seed file: " + randomFile); PEG_METHOD_EXIT(); // do not put in $0 in default message, but pass in filename // for bundle message MessageLoaderParms parms( "Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE", "Not enough seed data in random seed file.", randomFile); throw SSLException(parms); } } else { PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "seed file - " + randomFile + " does not exist."); PEG_METHOD_EXIT(); MessageLoaderParms parms( "Common.SSLContext.SEED_FILE_DOES_NOT_EXIST", "Seed file '$0' does not exist.", randomFile); throw SSLException(parms); } if ( RAND_status() == 0 ) { // // Try to do more seeding // long seedNumber; #if defined(PEGASUS_COMPILER_MSVC) srand((unsigned int)time(NULL)); // Initialize seedNumber = rand(); #else srandom((unsigned int)time(NULL)); // Initialize seedNumber = random(); #endif RAND_seed((unsigned char *) &seedNumber, sizeof(seedNumber)); int seedRet = RAND_status(); if ( seedRet == 0 ) { PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "Not enough seed data in random seed file, RAND_status = " + seedRet); PEG_METHOD_EXIT(); // do not put in $0 in default message, but pass in filename // for bundle message MessageLoaderParms parms( "Common.SSLContext.NOT_ENOUGH_SEED_DATA_IN_FILE", "Not enough seed data in random seed file.", randomFile); throw SSLException(parms); } } }#endif /* PEGASUS_SSL_RANDOMFILE */ int seedRet = RAND_status(); if (seedRet == 0) { PEG_TRACE_STRING(TRC_SSL, Tracer::LEVEL4, "Not enough seed data , RAND_status = " + seedRet ); PEG_METHOD_EXIT(); MessageLoaderParms parms( "Common.SSLContext.NOT_ENOUGH_SEED_DATA", "Not enough seed data."); throw SSLException(parms); } PEG_METHOD_EXIT();}SSL_CTX* SSLContextRep::_makeSSLContext(){ PEG_METHOD_ENTER(TRC_SSL, "SSLContextRep::_makeSSLContext()"); SSL_CTX * sslContext = 0; // // create SSL Context Area // if (!(sslContext = SSL_CTX_new(SSLv23_method()))) { PEG_METHOD_EXIT(); MessageLoaderParms parms( "Common.SSLContext.COULD_NOT_GET", "Could not get SSL CTX"); throw SSLException(parms); }#ifdef PEGASUS_SSL_WEAKENCRYPTION if (!(SSL_CTX_set_cipher_list(sslContext, SSL_TXT_EXP40))) { MessageLoaderParms parms(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -