namespace folly {
-uint64_t SSLContext::count_ = 0;
+bool SSLContext::initialized_ = false;
std::mutex SSLContext::mutex_;
#ifdef OPENSSL_NPN_NEGOTIATED
int SSLContext::sNextProtocolsExDataIndex_ = -1;
+#endif
+#ifndef SSLCONTEXT_NO_REFCOUNT
+uint64_t SSLContext::count_ = 0;
#endif
+
// SSLContext implementation
SSLContext::SSLContext(SSLVersion version) {
{
std::lock_guard<std::mutex> g(mutex_);
- if (!count_++) {
- initializeOpenSSL();
- randomize();
-#ifdef OPENSSL_NPN_NEGOTIATED
- sNextProtocolsExDataIndex_ = SSL_get_ex_new_index(0,
- (void*)"Advertised next protocol index", nullptr, nullptr, nullptr);
+#ifndef SSLCONTEXT_NO_REFCOUNT
+ count_++;
#endif
- }
+ initializeOpenSSLLocked();
}
ctx_ = SSL_CTX_new(SSLv23_method());
deleteNextProtocolsStrings();
#endif
- std::lock_guard<std::mutex> g(mutex_);
- if (!--count_) {
- cleanupOpenSSL();
+#ifndef SSLCONTEXT_NO_REFCOUNT
+ {
+ std::lock_guard<std::mutex> g(mutex_);
+ if (!--count_) {
+ cleanupOpenSSLLocked();
+ }
}
+#endif
}
void SSLContext::ciphers(const std::string& ciphers) {
}
void SSLContext::initializeOpenSSL() {
+ std::lock_guard<std::mutex> g(mutex_);
+ initializeOpenSSLLocked();
+}
+
+void SSLContext::initializeOpenSSLLocked() {
+ if (initialized_) {
+ return;
+ }
SSL_library_init();
SSL_load_error_strings();
ERR_load_crypto_strings();
CRYPTO_set_dynlock_create_callback(dyn_create);
CRYPTO_set_dynlock_lock_callback(dyn_lock);
CRYPTO_set_dynlock_destroy_callback(dyn_destroy);
+ randomize();
+#ifdef OPENSSL_NPN_NEGOTIATED
+ sNextProtocolsExDataIndex_ = SSL_get_ex_new_index(0,
+ (void*)"Advertised next protocol index", nullptr, nullptr, nullptr);
+#endif
+ initialized_ = true;
}
void SSLContext::cleanupOpenSSL() {
+ std::lock_guard<std::mutex> g(mutex_);
+ cleanupOpenSSLLocked();
+}
+
+void SSLContext::cleanupOpenSSLLocked() {
+ if (!initialized_) {
+ return;
+ }
+
CRYPTO_set_id_callback(nullptr);
CRYPTO_set_locking_callback(nullptr);
CRYPTO_set_dynlock_create_callback(nullptr);
EVP_cleanup();
ERR_remove_state(0);
locks.reset();
+ initialized_ = false;
}
void SSLContext::setOptions(long options) {
* Load a client CA list for validating clients
*/
virtual void loadClientCAList(const char* path);
- /**
- * Default randomize method.
- */
- virtual void randomize();
/**
* Override default OpenSSL password collector.
*
*/
static bool matchName(const char* host, const char* pattern, int size);
+ /**
+ * Functions for setting up and cleaning up openssl.
+ * They can be invoked during the start of the application.
+ */
+ static void initializeOpenSSL();
+ static void cleanupOpenSSL();
+
+ /**
+ * Default randomize method.
+ */
+ static void randomize();
+
protected:
SSL_CTX* ctx_;
#endif
static std::mutex mutex_;
+ static bool initialized_;
+
+#ifndef SSLCONTEXT_NO_REFCOUNT
static uint64_t count_;
+#endif
#ifdef OPENSSL_NPN_NEGOTIATED
/**
static int passwordCallback(char* password, int size, int, void* data);
- static void initializeOpenSSL();
- static void cleanupOpenSSL();
-
-
#if OPENSSL_VERSION_NUMBER >= 0x1000105fL && !defined(OPENSSL_NO_TLSEXT)
/**
* The function that will be called directly from openssl
#endif
std::string providedCiphersString_;
+
+ // Functions are called when locked by the calling function.
+ static void initializeOpenSSLLocked();
+ static void cleanupOpenSSLLocked();
};
typedef std::shared_ptr<SSLContext> SSLContextPtr;