int SSL_get_app_data2_idx(void) { static int app_data2_idx = -1; if (app_data2_idx < 0) { app_data2_idx = SSL_get_ex_new_index(0, "Second Application Data for SSL", NULL, NULL, NULL); app_data2_idx = SSL_get_ex_new_index(0, "Second Application Data for SSL", NULL, NULL, NULL); } return(app_data2_idx); }
void SSLContext::initializeOpenSSLLocked() { if (initialized_) { return; } SSL_library_init(); SSL_load_error_strings(); ERR_load_crypto_strings(); // static locking locks.reset(new SSLLock[::CRYPTO_num_locks()]); for (auto it: lockTypes) { locks[it.first].lockType = it.second; } CRYPTO_set_id_callback(callbackThreadID); CRYPTO_set_locking_callback(callbackLocking); // dynamic locking 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; }
int ssl_init(void) { /* init SSL before parsing configuration file */ SSL_load_error_strings(); SSL_library_init(); index_cli=SSL_get_ex_new_index(0, "cli index", NULL, NULL, NULL); index_opt=SSL_CTX_get_ex_new_index(0, "opt index", NULL, NULL, NULL); index_redirect=SSL_SESSION_get_ex_new_index(0, "redirect index", NULL, NULL, NULL); index_addr=SSL_SESSION_get_ex_new_index(0, "addr index", NULL, NULL, cb_free); if(index_cli<0 || index_opt<0 || index_redirect<0 || index_addr<0) { s_log(LOG_ERR, "Application specific data initialization failed"); return 1; } #ifndef OPENSSL_NO_ENGINE ENGINE_load_builtin_engines(); #endif #ifndef OPENSSL_NO_DH dh_params=get_dh2048(); if(!dh_params) { s_log(LOG_ERR, "Failed to get default DH parameters"); return 1; } #endif /* OPENSSL_NO_DH */ return 0; }
static void tls_init_once(void) { SSL_library_init(); SSL_load_error_strings(); tls_ex_data_idx = SSL_get_ex_new_index(0, "sofia-sip private data", NULL, NULL, NULL); }
SSL_CTX *ssl_init() { SSL_CTX *ctx = NULL; SSL_load_error_strings(); SSL_library_init(); OpenSSL_add_all_algorithms(); ssl_data_index = SSL_get_ex_new_index(0,0,0,0,0); if ((locks = calloc(CRYPTO_num_locks(), sizeof(pthread_mutex_t)))) { for (int i = 0; i < CRYPTO_num_locks(); i++) { pthread_mutex_init(&locks[i], NULL); } CRYPTO_set_locking_callback(ssl_lock); CRYPTO_set_id_callback(ssl_id); if ((ctx = SSL_CTX_new(SSLv23_client_method()))) { SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); SSL_CTX_set_verify_depth(ctx, 0); SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT); SSL_CTX_sess_set_new_cb(ctx, new_session_callback); SSL_CTX_set_info_callback(ctx, ssl_info_callback); } } return ctx; }
int rb_init_ssl(void) { int ret = 1; char libratbox_data[] = "libratbox data"; SSL_load_error_strings(); SSL_library_init(); libratbox_index = SSL_get_ex_new_index(0, libratbox_data, NULL, NULL, NULL); ssl_server_ctx = SSL_CTX_new(SSLv23_server_method()); if(ssl_server_ctx == NULL) { rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s", get_ssl_error(ERR_get_error())); ret = 0; } /* Disable SSLv2, make the client use our settings */ SSL_CTX_set_options(ssl_server_ctx, SSL_OP_NO_SSLv2 | SSL_OP_CIPHER_SERVER_PREFERENCE); SSL_CTX_set_verify(ssl_server_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb); ssl_client_ctx = SSL_CTX_new(TLSv1_client_method()); if(ssl_client_ctx == NULL) { rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s", get_ssl_error(ERR_get_error())); ret = 0; } return ret; }
static void init_openssl(struct module *module) { unsigned char f_randfile[PATH_MAX]; /* In a nutshell, on OS's without a /dev/urandom, the OpenSSL library * cannot initialize the PRNG and so every attempt to use SSL fails. * It's actually an OpenSSL FAQ, and according to them, it's up to the * application coders to seed the RNG. -- William Yodlowsky */ RAND_file_name(f_randfile, sizeof(f_randfile)); #ifdef HAVE_RAND_EGD if (RAND_egd(f_randfile) < 0) { /* Not an EGD, so read and write to it */ #endif if (RAND_load_file(f_randfile, -1)) RAND_write_file(f_randfile); #ifdef HAVE_RAND_EGD } #endif SSLeay_add_ssl_algorithms(); context = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_options(context, SSL_OP_ALL); SSL_CTX_set_default_verify_paths(context); socket_SSL_ex_data_idx = SSL_get_ex_new_index(0, NULL, NULL, socket_SSL_ex_data_dup, NULL); }
void tls_init_lib() { SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms (); mydata_index = SSL_get_ex_new_index(0, "struct session *", NULL, NULL, NULL); ASSERT (mydata_index >= 0); }
int rb_init_ssl(void) { int ret = 1; char libratbox_data[] = "libratbox data"; SSL_load_error_strings(); SSL_library_init(); libratbox_index = SSL_get_ex_new_index(0, libratbox_data, NULL, NULL, NULL); return ret; }
int SSLSocket::GetSSLExDataIndex() { if (s_ex_data_index >= 0) { return s_ex_data_index; } Lock lock(s_mutex); if (s_ex_data_index < 0) { s_ex_data_index = SSL_get_ex_new_index(0, (void*)"PHP stream index", NULL, NULL, NULL); ASSERT(s_ex_data_index >= 0); } return s_ex_data_index; }
int SSLSocket::GetSSLExDataIndex() { if (s_ex_data_index >= 0) { return s_ex_data_index; } Lock lock(s_mutex); if (s_ex_data_index < 0) { s_ex_data_index = SSL_get_ex_new_index(0, (void*)"PHP stream index", nullptr, nullptr, nullptr); assert(s_ex_data_index >= 0); } return s_ex_data_index; }
/* this should only happen once ever in the life of the library. it's used to associate a getdns_context_t with an SSL_CTX, to be able to do custom verification. see doc/HOWTO/proxy_certificates.txt as an example */ static int _get_ssl_getdns_upstream_idx() { static volatile int idx = -1; if (idx < 0) { CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); if (idx < 0) idx = SSL_get_ex_new_index(0, "associated getdns upstream", NULL,NULL,NULL); CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); } return idx; }
int rb_init_ssl(void) { int ret = 1; char libratbox_data[] = "libratbox data"; SSL_load_error_strings(); SSL_library_init(); libratbox_index = SSL_get_ex_new_index(0, libratbox_data, NULL, NULL, NULL); ssl_server_ctx = SSL_CTX_new(SSLv23_server_method()); if(ssl_server_ctx == NULL) { rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s", get_ssl_error(ERR_get_error())); ret = 0; } /* Disable SSLv2, make the client use our settings */ SSL_CTX_set_options(ssl_server_ctx, SSL_OP_NO_SSLv2 | SSL_OP_CIPHER_SERVER_PREFERENCE #ifdef SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_DH_USE #endif ); SSL_CTX_set_verify(ssl_server_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb); SSL_CTX_set_session_id_context(ssl_server_ctx, (const unsigned char *)"libratbox", 9); SSL_CTX_set_cipher_list(ssl_server_ctx, "EECDH+HIGH:EDH+HIGH:HIGH:!aNULL"); /* Set ECDHE on OpenSSL 1.00+, but make sure it's actually available because redhat are dicks and bastardise their OpenSSL for stupid reasons... */ #if (OPENSSL_VERSION_NUMBER >= 0x10000000) && defined(NID_secp384r1) EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp384r1); if (key) { SSL_CTX_set_tmp_ecdh(ssl_server_ctx, key); EC_KEY_free(key); } #ifdef SSL_OP_SINGLE_ECDH_USE SSL_CTX_set_options(ssl_server_ctx, SSL_OP_SINGLE_ECDH_USE); #endif #endif ssl_client_ctx = SSL_CTX_new(TLSv1_client_method()); if(ssl_client_ctx == NULL) { rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s", get_ssl_error(ERR_get_error())); ret = 0; } return ret; }
void as_tls_check_init() { // Bail if we've already initialized. if (s_tls_inited) { return; } // Acquire the initialization mutex. pthread_mutex_lock(&s_tls_init_mutex); // Check the flag again, in case we lost a race. if (! s_tls_inited) { #if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined USE_XDR OpenSSL_add_all_algorithms(); ERR_load_BIO_strings(); ERR_load_crypto_strings(); SSL_load_error_strings(); SSL_library_init(); threading_setup(); // Install an atexit handler to cleanup. atexit(as_tls_cleanup); #endif s_ex_name_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); s_ex_ctxt_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); as_fence_memory(); s_tls_inited = true; } pthread_mutex_unlock(&s_tls_init_mutex); }
static int tls_bootstrap (int majorid, int minorid, void *serverarg, void *clientarg) { char indexname[] = "_netsnmp_verify_info"; /* don't do this more than once */ if (have_done_bootstrap) return 0; have_done_bootstrap = 1; netsnmp_certs_load (); openssl_local_index = SSL_get_ex_new_index (0, indexname, NULL, NULL, NULL); return 0; }
void modssl_init_app_data2_idx(void) { int i; if (app_data2_idx > -1) { return; } /* we _do_ need to call this twice */ for (i = 0; i <= 1; i++) { app_data2_idx = SSL_get_ex_new_index(0, "Second Application Data for SSL", NULL, NULL, NULL); } }
void _mosquitto_net_init(void) { #ifdef WIN32 WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData); #endif #ifdef WITH_TLS SSL_load_error_strings(); SSL_library_init(); OpenSSL_add_all_algorithms(); if(tls_ex_index_mosq == -1){ tls_ex_index_mosq = SSL_get_ex_new_index(0, "client context", NULL, NULL, NULL); } #endif }
int lws_context_init_ssl_library(struct lws_context_creation_info *info) { #ifdef USE_WOLFSSL #ifdef USE_OLD_CYASSL lwsl_notice(" Compiled with CyaSSL support\n"); #else lwsl_notice(" Compiled with wolfSSL support\n"); #endif #else #if defined(LWS_USE_POLARSSL) lwsl_notice(" Compiled with PolarSSL support\n"); #else #if defined(LWS_USE_MBEDTLS) lwsl_notice(" Compiled with mbedTLS support\n"); #else lwsl_notice(" Compiled with OpenSSL support\n"); #endif #endif #endif if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) { lwsl_notice(" SSL disabled: no LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT\n"); return 0; } /* basic openssl init */ #if defined(LWS_USE_POLARSSL) #else #if defined(LWS_USE_MBEDTLS) #else SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); openssl_websocket_private_data_index = SSL_get_ex_new_index(0, "lws", NULL, NULL, NULL); openssl_SSL_CTX_private_data_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); #endif #endif return 0; }
int rb_init_ssl(void) { char librb_data[] = "librb data"; #if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* * OpenSSL 1.1.0 and above automatically initialises itself with sane defaults */ SSL_library_init(); SSL_load_error_strings(); #endif librb_index = SSL_get_ex_new_index(0, librb_data, NULL, NULL, NULL); return 1; }
int lws_context_init_ssl_library(const struct lws_context_creation_info *info) { #ifdef USE_WOLFSSL #ifdef USE_OLD_CYASSL lwsl_info(" Compiled with CyaSSL support\n"); #else lwsl_info(" Compiled with wolfSSL support\n"); #endif #else #if defined(LWS_WITH_BORINGSSL) lwsl_info(" Compiled with BoringSSL support\n"); #else lwsl_info(" Compiled with OpenSSL support\n"); #endif #endif if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) { lwsl_info(" SSL disabled: no " "LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT\n"); return 0; } /* basic openssl init */ lwsl_info("Doing SSL library init\n"); #if OPENSSL_VERSION_NUMBER < 0x10100000L SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); #else OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); #endif #if defined(LWS_WITH_NETWORK) openssl_websocket_private_data_index = SSL_get_ex_new_index(0, "lws", NULL, NULL, NULL); openssl_SSL_CTX_private_data_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); #endif return 0; }
static void er_dtls_connection_class_init(ErDtlsConnectionClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); g_type_class_add_private(klass, sizeof(ErDtlsConnectionPrivate)); gobject_class->set_property = er_dtls_connection_set_property; connection_ex_index = SSL_get_ex_new_index(0, "erdtlsagent connection index", NULL, NULL, NULL); signals[SIGNAL_ON_DECODER_KEY] = g_signal_new("on-decoder-key", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT); signals[SIGNAL_ON_ENCODER_KEY] = g_signal_new("on-encoder-key", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT); signals[SIGNAL_ON_PEER_CERTIFICATE] = g_signal_new("on-peer-certificate", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 1, G_TYPE_STRING); properties[PROP_AGENT] = g_param_spec_object("agent", "ERDtlsAgent", "Agent to use in creation of the connection", ER_TYPE_DTLS_AGENT, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(gobject_class, NUM_PROPERTIES, properties); _er_dtls_init_openssl(); gobject_class->finalize = er_dtls_connection_finalize; }
bool TLSGenericInitialize() { static bool is_initialised = false; /* We must make sure that SSL_get_ex_new_index() is called only once! */ if (is_initialised) { return true; } /* OpenSSL is needed for TLS. */ SSL_library_init(); SSL_load_error_strings(); /* Register a unique place to store ConnectionInfo within SSL struct. */ CONNECTIONINFO_SSL_IDX = SSL_get_ex_new_index(0, "Pointer to ConnectionInfo", NULL, NULL, NULL); is_initialised = true; return true; }
/* static */ void BSecureSocket::Private::_CreateContext() { sContext = SSL_CTX_new(SSLv23_method()); // Disable legacy protocols. They have known vulnerabilities. SSL_CTX_set_options(sContext, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); // Don't bother us with ERROR_WANT_READ. SSL_CTX_set_mode(sContext, SSL_MODE_AUTO_RETRY); // Setup certificate verification BPath certificateStore; find_directory(B_SYSTEM_DATA_DIRECTORY, &certificateStore); certificateStore.Append("ssl/CARootCertificates.pem"); // TODO we may want to add a non-packaged certificate directory? // (would make it possible to store user-added certificate exceptions // there) SSL_CTX_load_verify_locations(sContext, certificateStore.Path(), NULL); SSL_CTX_set_verify(sContext, SSL_VERIFY_PEER, VerifyCallback); // OpenSSL 1.0.2 and later: use the alternate "trusted first" algorithm to validate certificate // chains. This makes the validation stop as soon as a recognized certificate is found in the // chain, instead of validating the whole chain, then seeing if the root certificate is known. #ifdef X509_V_FLAG_TRUSTED_FIRST X509_VERIFY_PARAM* verifyParam = X509_VERIFY_PARAM_new(); X509_VERIFY_PARAM_set_flags(verifyParam, X509_V_FLAG_TRUSTED_FIRST); SSL_CTX_set1_param(sContext, verifyParam); // TODO we need to free this after freeing the SSL context (which we currently never do) // X509_VERIFY_PARAM_free(verifyParam); #endif // Get an unique index number for storing application data in SSL // structs. We will store a pointer to the BSecureSocket class there. sDataIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); }
int rb_init_ssl(void) { int ret = 1; char libratbox_data[] = "libratbox data"; const char libratbox_ciphers[] = "kEECDH+HIGH:kEDH+HIGH:HIGH:!RC4:!aNULL"; SSL_load_error_strings(); SSL_library_init(); libratbox_index = SSL_get_ex_new_index(0, libratbox_data, NULL, NULL, NULL); #if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L) ssl_server_ctx = SSL_CTX_new(SSLv23_server_method()); #else ssl_server_ctx = SSL_CTX_new(TLS_server_method()); #endif if(ssl_server_ctx == NULL) { rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s", get_ssl_error(ERR_get_error())); ret = 0; } long server_options = SSL_CTX_get_options(ssl_server_ctx); #if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L) server_options |= SSL_OP_NO_SSLv2; server_options |= SSL_OP_NO_SSLv3; #endif #ifdef SSL_OP_SINGLE_DH_USE server_options |= SSL_OP_SINGLE_DH_USE; #endif #ifdef SSL_OP_SINGLE_ECDH_USE server_options |= SSL_OP_SINGLE_ECDH_USE; #endif #ifdef SSL_OP_NO_TICKET server_options |= SSL_OP_NO_TICKET; #endif server_options |= SSL_OP_CIPHER_SERVER_PREFERENCE; SSL_CTX_set_options(ssl_server_ctx, server_options); SSL_CTX_set_verify(ssl_server_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb); SSL_CTX_set_session_cache_mode(ssl_server_ctx, SSL_SESS_CACHE_OFF); SSL_CTX_set_cipher_list(ssl_server_ctx, libratbox_ciphers); /* Set ECDHE on OpenSSL 1.00+, but make sure it's actually available because redhat are dicks and bastardise their OpenSSL for stupid reasons... */ #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && defined(NID_secp384r1) EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp384r1); if (key) { SSL_CTX_set_tmp_ecdh(ssl_server_ctx, key); EC_KEY_free(key); } #endif #if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L) ssl_client_ctx = SSL_CTX_new(TLSv1_client_method()); #else ssl_client_ctx = SSL_CTX_new(TLS_client_method()); #endif if(ssl_client_ctx == NULL) { rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s", get_ssl_error(ERR_get_error())); ret = 0; } #ifdef SSL_OP_NO_TICKET SSL_CTX_set_options(ssl_client_ctx, SSL_OP_NO_TICKET); #endif SSL_CTX_set_cipher_list(ssl_client_ctx, libratbox_ciphers); return ret; }
bud_error_t bud_config_init(bud_config_t* config) { bud_error_t err; int i; int r; /* Get addresses of frontend and backend */ r = bud_config_str_to_addr(config->frontend.host, config->frontend.port, &config->frontend.addr); if (r != 0) return bud_error_num(kBudErrPton, r); for (i = 0; i < config->frontend.interface.count; i++) { bud_config_addr_t* addr; addr = &config->frontend.interface.list[i]; r = bud_config_str_to_addr(addr->host, addr->port, &addr->addr); if (r != 0) return bud_error_num(kBudErrPton, r); } err = bud_config_format_proxyline(config); if (!bud_is_ok(err)) return err; i = 0; config->balance_e = bud_config_balance_to_enum(config->balance); /* At least one backend should be present for non-SNI balancing */ if (config->contexts[0].backend.count == 0 && config->balance_e != kBudBalanceSNI) { err = bud_error(kBudErrNoBackend); goto fatal; } /* Get indexes for SSL_set_ex_data()/SSL_get_ex_data() */ if (kBudSSLClientIndex == -1) { kBudSSLConfigIndex = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); kBudSSLClientIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); kBudSSLSNIIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); kBudSSLTicketKeyIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); if (kBudSSLConfigIndex == -1 || kBudSSLClientIndex == -1 || kBudSSLSNIIndex == -1 || kBudSSLTicketKeyIndex == -1) { err = bud_error(kBudErrNoSSLIndex); goto fatal; } } #ifndef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB if (config->context_count != 0) { err = bud_error(kBudErrSNINotSupported); goto fatal; } #endif /* !SSL_CTRL_SET_TLSEXT_SERVERNAME_CB */ /* Allocate workers */ if (!config->is_worker && config->worker_count != 0) { config->workers = calloc(config->worker_count, sizeof(*config->workers)); if (config->workers == NULL) { err = bud_error_str(kBudErrNoMem, "workers"); goto fatal; } } /* Initialize logger */ config->logger = bud_logger_new(config, &err); if (!bud_is_ok(err)) goto fatal; err = bud_config_init_tracing(&config->trace); if (!bud_is_ok(err)) goto fatal; if (config->is_worker || config->worker_count == 0) { /* Connect to SNI server */ if (config->sni.enabled) { config->sni.pool = bud_http_pool_new(config, config->sni.host, config->sni.port, &err); if (config->sni.pool == NULL) goto fatal; } /* Connect to OCSP Stapling server */ if (config->stapling.enabled) { config->stapling.pool = bud_http_pool_new(config, config->stapling.host, config->stapling.port, &err); if (config->stapling.pool == NULL) goto fatal; } } /* Init all contexts */ for (i = 0; i < config->context_count + 1; i++) { err = bud_context_init(config, &config->contexts[i]); if (!bud_is_ok(err)) goto fatal; } return bud_ok(); fatal: /* Free all allocated contexts */ do bud_context_free(&config->contexts[i--]); while (i >= 0); return err; }
TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props) { long off = 0; int cachable; int scache_timeout; SSL_CTX *client_ctx; TLS_APPL_STATE *app_ctx; int log_mask; /* * Convert user loglevel to internal logmask. */ log_mask = tls_log_mask(props->log_param, props->log_level); if (log_mask & TLS_LOG_VERBOSE) msg_info("initializing the client-side TLS engine"); /* * Load (mostly cipher related) TLS-library internal main.cf parameters. */ tls_param_init(); /* * Detect mismatch between compile-time headers and run-time library. */ tls_check_version(); /* * Initialize the OpenSSL library by the book! To start with, we must * initialize the algorithms. We want cleartext error messages instead of * just error codes, so we load the error_strings. */ SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); /* * Create an application data index for SSL objects, so that we can * attach TLScontext information; this information is needed inside * tls_verify_certificate_callback(). */ if (TLScontext_index < 0) { if ((TLScontext_index = SSL_get_ex_new_index(0, 0, 0, 0, 0)) < 0) { msg_warn("Cannot allocate SSL application data index: " "disabling TLS support"); return (0); } } /* * If the administrator specifies an unsupported digest algorithm, fail * now, rather than in the middle of a TLS handshake. */ if (!tls_validate_digest(props->mdalg)) { msg_warn("disabling TLS support"); return (0); } /* * Initialize the PRNG (Pseudo Random Number Generator) with some seed * from external and internal sources. Don't enable TLS without some real * entropy. */ if (tls_ext_seed(var_tls_daemon_rand_bytes) < 0) { msg_warn("no entropy for TLS key generation: disabling TLS support"); return (0); } tls_int_seed(); /* * The SSL/TLS specifications require the client to send a message in the * oldest specification it understands with the highest level it * understands in the message. RFC2487 is only specified for TLSv1, but * we want to be as compatible as possible, so we will start off with a * SSLv2 greeting allowing the best we can offer: TLSv1. We can restrict * this with the options setting later, anyhow. */ ERR_clear_error(); if ((client_ctx = SSL_CTX_new(SSLv23_client_method())) == 0) { msg_warn("cannot allocate client SSL_CTX: disabling TLS support"); tls_print_errors(); return (0); } /* * See the verify callback in tls_verify.c */ SSL_CTX_set_verify_depth(client_ctx, props->verifydepth + 1); /* * Protocol selection is destination dependent, so we delay the protocol * selection options to the per-session SSL object. */ off |= tls_bug_bits(); SSL_CTX_set_options(client_ctx, off); /* * Set the call-back routine for verbose logging. */ if (log_mask & TLS_LOG_DEBUG) SSL_CTX_set_info_callback(client_ctx, tls_info_callback); /* * Load the CA public key certificates for both the client cert and for * the verification of server certificates. As provided by OpenSSL we * support two types of CA certificate handling: One possibility is to * add all CA certificates to one large CAfile, the other possibility is * a directory pointed to by CApath, containing separate files for each * CA with softlinks named after the hash values of the certificate. The * first alternative has the advantage that the file is opened and read * at startup time, so that you don't have the hassle to maintain another * copy of the CApath directory for chroot-jail. */ if (tls_set_ca_certificate_info(client_ctx, props->CAfile, props->CApath) < 0) { /* tls_set_ca_certificate_info() already logs a warning. */ SSL_CTX_free(client_ctx); /* 200411 */ return (0); } /* * We do not need a client certificate, so the certificates are only * loaded (and checked) if supplied. A clever client would handle * multiple client certificates and decide based on the list of * acceptable CAs, sent by the server, which certificate to submit. * OpenSSL does however not do this and also has no call-back hooks to * easily implement it. * * Load the client public key certificate and private key from file and * check whether the cert matches the key. We can use RSA certificates * ("cert") DSA certificates ("dcert") or ECDSA certificates ("eccert"). * All three can be made available at the same time. The CA certificates * for all three are handled in the same setup already finished. Which * one is used depends on the cipher negotiated (that is: the first * cipher listed by the client which does match the server). The client * certificate is presented after the server chooses the session cipher, * so we will just present the right cert for the chosen cipher (if it * uses certificates). */ if (tls_set_my_certificate_key_info(client_ctx, props->cert_file, props->key_file, props->dcert_file, props->dkey_file, props->eccert_file, props->eckey_file) < 0) { /* tls_set_my_certificate_key_info() already logs a warning. */ SSL_CTX_free(client_ctx); /* 200411 */ return (0); } /* * According to the OpenSSL documentation, temporary RSA key is needed * export ciphers are in use. We have to provide one, so well, we just do * it. */ SSL_CTX_set_tmp_rsa_callback(client_ctx, tls_tmp_rsa_cb); /* * Finally, the setup for the server certificate checking, done "by the * book". */ SSL_CTX_set_verify(client_ctx, SSL_VERIFY_NONE, tls_verify_certificate_callback); /* * Initialize the session cache. * * Since the client does not search an internal cache, we simply disable it. * It is only useful for expiring old sessions, but we do that in the * tlsmgr(8). * * This makes SSL_CTX_remove_session() not useful for flushing broken * sessions from the external cache, so we must delete them directly (not * via a callback). */ if (tls_mgr_policy(props->cache_type, &cachable, &scache_timeout) != TLS_MGR_STAT_OK) scache_timeout = 0; if (scache_timeout <= 0) cachable = 0; /* * Allocate an application context, and populate with mandatory protocol * and cipher data. */ app_ctx = tls_alloc_app_context(client_ctx, log_mask); /* * The external session cache is implemented by the tlsmgr(8) process. */ if (cachable) { app_ctx->cache_type = mystrdup(props->cache_type); /* * OpenSSL does not use callbacks to load sessions from a client * cache, so we must invoke that function directly. Apparently, * OpenSSL does not provide a way to pass session names from here to * call-back routines that do session lookup. * * OpenSSL can, however, automatically save newly created sessions for * us by callback (we create the session name in the call-back * function). * * XXX gcc 2.95 can't compile #ifdef .. #endif in the expansion of * SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE | * SSL_SESS_CACHE_NO_AUTO_CLEAR. */ #ifndef SSL_SESS_CACHE_NO_INTERNAL_STORE #define SSL_SESS_CACHE_NO_INTERNAL_STORE 0 #endif SSL_CTX_set_session_cache_mode(client_ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE | SSL_SESS_CACHE_NO_AUTO_CLEAR); SSL_CTX_sess_set_new_cb(client_ctx, new_client_session_cb); /* * OpenSSL ignores timed-out sessions. We need to set the internal * cache timeout at least as high as the external cache timeout. This * applies even if no internal cache is used. We set the session to * twice the cache lifetime. This way a session always lasts longer * than its lifetime in the cache. */ SSL_CTX_set_timeout(client_ctx, 2 * scache_timeout); } return (app_ctx); }
static HANDSHAKE_RESULT *do_handshake_internal( SSL_CTX *server_ctx, SSL_CTX *server2_ctx, SSL_CTX *client_ctx, const SSL_TEST_CTX *test_ctx, SSL_SESSION *session_in, SSL_SESSION **session_out) { SSL *server, *client; BIO *client_to_server, *server_to_client; HANDSHAKE_EX_DATA server_ex_data, client_ex_data; CTX_DATA client_ctx_data, server_ctx_data, server2_ctx_data; HANDSHAKE_RESULT *ret = HANDSHAKE_RESULT_new(); int client_turn = 1, shutdown = 0; peer_status_t client_status = PEER_RETRY, server_status = PEER_RETRY; handshake_status_t status = HANDSHAKE_RETRY; unsigned char* tick = NULL; size_t tick_len = 0; SSL_SESSION* sess = NULL; const unsigned char *proto = NULL; /* API dictates unsigned int rather than size_t. */ unsigned int proto_len = 0; memset(&server_ctx_data, 0, sizeof(server_ctx_data)); memset(&server2_ctx_data, 0, sizeof(server2_ctx_data)); memset(&client_ctx_data, 0, sizeof(client_ctx_data)); configure_handshake_ctx(server_ctx, server2_ctx, client_ctx, test_ctx, &server_ctx_data, &server2_ctx_data, &client_ctx_data); server = SSL_new(server_ctx); client = SSL_new(client_ctx); OPENSSL_assert(server != NULL && client != NULL); configure_handshake_ssl(server, client, test_ctx); if (session_in != NULL) { /* In case we're testing resumption without tickets. */ OPENSSL_assert(SSL_CTX_add_session(server_ctx, session_in)); OPENSSL_assert(SSL_set_session(client, session_in)); } memset(&server_ex_data, 0, sizeof(server_ex_data)); memset(&client_ex_data, 0, sizeof(client_ex_data)); ret->result = SSL_TEST_INTERNAL_ERROR; client_to_server = BIO_new(BIO_s_mem()); server_to_client = BIO_new(BIO_s_mem()); OPENSSL_assert(client_to_server != NULL && server_to_client != NULL); /* Non-blocking bio. */ BIO_set_nbio(client_to_server, 1); BIO_set_nbio(server_to_client, 1); SSL_set_connect_state(client); SSL_set_accept_state(server); /* The bios are now owned by the SSL object. */ SSL_set_bio(client, server_to_client, client_to_server); OPENSSL_assert(BIO_up_ref(server_to_client) > 0); OPENSSL_assert(BIO_up_ref(client_to_server) > 0); SSL_set_bio(server, client_to_server, server_to_client); ex_data_idx = SSL_get_ex_new_index(0, "ex data", NULL, NULL, NULL); OPENSSL_assert(ex_data_idx >= 0); OPENSSL_assert(SSL_set_ex_data(server, ex_data_idx, &server_ex_data) == 1); OPENSSL_assert(SSL_set_ex_data(client, ex_data_idx, &client_ex_data) == 1); SSL_set_info_callback(server, &info_cb); SSL_set_info_callback(client, &info_cb); /* * Half-duplex handshake loop. * Client and server speak to each other synchronously in the same process. * We use non-blocking BIOs, so whenever one peer blocks for read, it * returns PEER_RETRY to indicate that it's the other peer's turn to write. * The handshake succeeds once both peers have succeeded. If one peer * errors out, we also let the other peer retry (and presumably fail). */ for(;;) { if (client_turn) { client_status = do_handshake_step(client, shutdown); status = handshake_status(client_status, server_status, 1 /* client went last */); } else { server_status = do_handshake_step(server, shutdown); status = handshake_status(server_status, client_status, 0 /* server went last */); } switch (status) { case HANDSHAKE_SUCCESS: if (shutdown) { ret->result = SSL_TEST_SUCCESS; goto err; } else { client_status = server_status = PEER_RETRY; shutdown = 1; client_turn = 1; break; } case CLIENT_ERROR: ret->result = SSL_TEST_CLIENT_FAIL; goto err; case SERVER_ERROR: ret->result = SSL_TEST_SERVER_FAIL; goto err; case INTERNAL_ERROR: ret->result = SSL_TEST_INTERNAL_ERROR; goto err; case HANDSHAKE_RETRY: /* Continue. */ client_turn ^= 1; break; } } err: ret->server_alert_sent = server_ex_data.alert_sent; ret->server_alert_received = client_ex_data.alert_received; ret->client_alert_sent = client_ex_data.alert_sent; ret->client_alert_received = server_ex_data.alert_received; ret->server_protocol = SSL_version(server); ret->client_protocol = SSL_version(client); ret->servername = server_ex_data.servername; if ((sess = SSL_get0_session(client)) != NULL) SSL_SESSION_get0_ticket(sess, &tick, &tick_len); if (tick == NULL || tick_len == 0) ret->session_ticket = SSL_TEST_SESSION_TICKET_NO; else ret->session_ticket = SSL_TEST_SESSION_TICKET_YES; ret->session_ticket_do_not_call = server_ex_data.session_ticket_do_not_call; SSL_get0_next_proto_negotiated(client, &proto, &proto_len); ret->client_npn_negotiated = dup_str(proto, proto_len); SSL_get0_next_proto_negotiated(server, &proto, &proto_len); ret->server_npn_negotiated = dup_str(proto, proto_len); SSL_get0_alpn_selected(client, &proto, &proto_len); ret->client_alpn_negotiated = dup_str(proto, proto_len); SSL_get0_alpn_selected(server, &proto, &proto_len); ret->server_alpn_negotiated = dup_str(proto, proto_len); ret->client_resumed = SSL_session_reused(client); ret->server_resumed = SSL_session_reused(server); if (session_out != NULL) *session_out = SSL_get1_session(client); ctx_data_free_data(&server_ctx_data); ctx_data_free_data(&server2_ctx_data); ctx_data_free_data(&client_ctx_data); SSL_free(server); SSL_free(client); return ret; }
int dtls_netsock_init(const STREAM_DTLS_CTXT_T *pDtlsCtxt, NETIO_SOCK_T *pnetsock, const DTLS_FINGERPRINT_VERIFY_T *pFingerprintVerify, const DTLS_KEY_UPDATE_CTXT_T *pKeysUpdateCtxt) { int rc = 0; if(!pDtlsCtxt || !pnetsock) { return -1; } if(!pnetsock || PNETIOSOCK_FD(pnetsock) == INVALID_SOCKET) { return -1; } pthread_mutex_lock(&((STREAM_DTLS_CTXT_T *) pDtlsCtxt)->mtx); if(pDtlsCtxt->active != 1) { pthread_mutex_unlock(&((STREAM_DTLS_CTXT_T *) pDtlsCtxt)->mtx); return -1; } if(!(pnetsock->ssl.pCtxt = SSL_new(pDtlsCtxt->pctx))) { LOG(X_ERROR("DTLS SSL_new failed: %s"), ERR_reason_error_string(ERR_get_error())); rc = -1; } pnetsock->ssl.ownCtxt = 1; if(rc >= 0 && !(pnetsock->ssl.pBioRd = BIO_new(BIO_s_mem()))) { LOG(X_ERROR("DTLS BIO_new (reader) failed: %s"), ERR_reason_error_string(ERR_get_error())); rc = -1; } pnetsock->ssl.ownBioRd = 1; if(rc >= 0 && !(pnetsock->ssl.pBioWr = BIO_new(BIO_s_mem()))) { LOG(X_ERROR("DTLS BIO_new (writer) failed: %s"), ERR_reason_error_string(ERR_get_error())); rc = -1; } pnetsock->ssl.ownBioWr = 1; if(rc >= 0) { BIO_set_mem_eof_return(pnetsock->ssl.pBioRd, -1); BIO_set_mem_eof_return(pnetsock->ssl.pBioWr, -1); SSL_set_bio(pnetsock->ssl.pCtxt, pnetsock->ssl.pBioRd, pnetsock->ssl.pBioWr); pnetsock->ssl.ownBioRd = 0; pnetsock->ssl.ownBioWr = 0; SSL_set_mode(pnetsock->ssl.pCtxt, SSL_MODE_AUTO_RETRY); SSL_set_read_ahead(pnetsock->ssl.pCtxt, 1); //SSL_set_connect_state(pnetsock->ssl.pCtxt); //SSL_set_accept_state(pnetsock->ssl.pCtxt); if(pFingerprintVerify) { if(s_sslCbDataIndex == -1) { s_sslCbDataIndex = SSL_get_ex_new_index(0, "verifycbIndex", NULL, NULL, NULL); } SSL_set_verify(pnetsock->ssl.pCtxt, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), dtls_verify_cb); SSL_set_ex_data(pnetsock->ssl.pCtxt, s_sslCbDataIndex, (void *) pFingerprintVerify); //LOG(X_DEBUG("SSL_set_ex_data index:%d, pFingerprintVerify: 0x%x"), s_sslCbDataIndex, pFingerprintVerify); } } pnetsock->ssl.pDtlsCtxt = pDtlsCtxt; pnetsock->flags |= NETIO_FLAG_SSL_DTLS; if(pDtlsCtxt->dtls_srtp) { pnetsock->flags |= NETIO_FLAG_SRTP; if(pKeysUpdateCtxt) { memcpy(&pnetsock->ssl.dtlsKeysUpdateCtxt, pKeysUpdateCtxt, sizeof(pnetsock->ssl.dtlsKeysUpdateCtxt)); } } pthread_mutex_unlock(&((STREAM_DTLS_CTXT_T *) pDtlsCtxt)->mtx); return rc; }
/* * Create Global context SSL and use it in every new session * * - Load the trusted CAs * - Load the Private key & the certificate * - Set the Context options & Verify options */ static SSL_CTX *init_tls_ctx(EAP_TLS_CONF *conf) { SSL_METHOD *meth; SSL_CTX *ctx; X509_STORE *certstore; int verify_mode = SSL_VERIFY_NONE; int ctx_options = 0; int type; /* * Add all the default ciphers and message digests * Create our context. */ SSL_library_init(); SSL_load_error_strings(); /* * SHA256 is in all versions of OpenSSL, but isn't * initialized by default. It's needed for WiMAX * certificates. */ #ifdef HAVE_OPENSSL_EVP_SHA256 EVP_add_digest(EVP_sha256()); #endif meth = TLSv1_method(); ctx = SSL_CTX_new(meth); /* * Identify the type of certificates that needs to be loaded */ if (conf->file_type) { type = SSL_FILETYPE_PEM; } else { type = SSL_FILETYPE_ASN1; } /* * Set the password to load private key */ if (conf->private_key_password) { #ifdef __APPLE__ /* * We don't want to put the private key password in eap.conf, so check * for our special string which indicates we should get the password * programmatically. */ const char* special_string = "Apple:UseCertAdmin"; if (strncmp(conf->private_key_password, special_string, strlen(special_string)) == 0) { char cmd[256]; const long max_password_len = 128; snprintf(cmd, sizeof(cmd) - 1, "/usr/sbin/certadmin --get-private-key-passphrase \"%s\"", conf->private_key_file); DEBUG2("rlm_eap: Getting private key passphrase using command \"%s\"", cmd); FILE* cmd_pipe = popen(cmd, "r"); if (!cmd_pipe) { radlog(L_ERR, "rlm_eap: %s command failed. Unable to get private_key_password", cmd); radlog(L_ERR, "rlm_eap: Error reading private_key_file %s", conf->private_key_file); return NULL; } free(conf->private_key_password); conf->private_key_password = malloc(max_password_len * sizeof(char)); if (!conf->private_key_password) { radlog(L_ERR, "rlm_eap: Can't malloc space for private_key_password"); radlog(L_ERR, "rlm_eap: Error reading private_key_file %s", conf->private_key_file); pclose(cmd_pipe); return NULL; } fgets(conf->private_key_password, max_password_len, cmd_pipe); pclose(cmd_pipe); /* Get rid of newline at end of password. */ conf->private_key_password[strlen(conf->private_key_password) - 1] = '\0'; DEBUG2("rlm_eap: Password from command = \"%s\"", conf->private_key_password); } #endif SSL_CTX_set_default_passwd_cb_userdata(ctx, conf->private_key_password); SSL_CTX_set_default_passwd_cb(ctx, cbtls_password); } /* * Load our keys and certificates * * If certificates are of type PEM then we can make use * of cert chain authentication using openssl api call * SSL_CTX_use_certificate_chain_file. Please see how * the cert chain needs to be given in PEM from * openSSL.org */ if (type == SSL_FILETYPE_PEM) { if (!(SSL_CTX_use_certificate_chain_file(ctx, conf->certificate_file))) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file); return NULL; } } else if (!(SSL_CTX_use_certificate_file(ctx, conf->certificate_file, type))) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file); return NULL; } /* Load the CAs we trust */ if (conf->ca_file || conf->ca_path) { if (!SSL_CTX_load_verify_locations(ctx, conf->ca_file, conf->ca_path)) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error reading Trusted root CA list %s",conf->ca_file ); return NULL; } } if (conf->ca_file && *conf->ca_file) SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(conf->ca_file)); if (!(SSL_CTX_use_PrivateKey_file(ctx, conf->private_key_file, type))) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error reading private key file %s", conf->private_key_file); return NULL; } /* * Check if the loaded private key is the right one */ if (!SSL_CTX_check_private_key(ctx)) { radlog(L_ERR, "rlm_eap_tls: Private key does not match the certificate public key"); return NULL; } /* * Set ctx_options */ ctx_options |= SSL_OP_NO_SSLv2; ctx_options |= SSL_OP_NO_SSLv3; #ifdef SSL_OP_NO_TICKET ctx_options |= SSL_OP_NO_TICKET ; #endif /* * SSL_OP_SINGLE_DH_USE must be used in order to prevent * small subgroup attacks and forward secrecy. Always * using * * SSL_OP_SINGLE_DH_USE has an impact on the computer * time needed during negotiation, but it is not very * large. */ ctx_options |= SSL_OP_SINGLE_DH_USE; /* * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS to work around issues * in Windows Vista client. * http://www.openssl.org/~bodo/tls-cbc.txt * http://www.nabble.com/(RADIATOR)-Radiator-Version-3.16-released-t2600070.html */ ctx_options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; SSL_CTX_set_options(ctx, ctx_options); /* * TODO: Set the RSA & DH * SSL_CTX_set_tmp_rsa_callback(ctx, cbtls_rsa); * SSL_CTX_set_tmp_dh_callback(ctx, cbtls_dh); */ /* * set the message callback to identify the type of * message. For every new session, there can be a * different callback argument. * * SSL_CTX_set_msg_callback(ctx, cbtls_msg); */ /* Set Info callback */ SSL_CTX_set_info_callback(ctx, cbtls_info); /* * Callbacks, etc. for session resumption. */ if (conf->session_cache_enable) { SSL_CTX_sess_set_new_cb(ctx, cbtls_new_session); SSL_CTX_sess_set_get_cb(ctx, cbtls_get_session); SSL_CTX_sess_set_remove_cb(ctx, cbtls_remove_session); SSL_CTX_set_quiet_shutdown(ctx, 1); } /* * Check the certificates for revocation. */ #ifdef X509_V_FLAG_CRL_CHECK if (conf->check_crl) { certstore = SSL_CTX_get_cert_store(ctx); if (certstore == NULL) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error reading Certificate Store"); return NULL; } X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); } #endif /* * Set verify modes * Always verify the peer certificate */ verify_mode |= SSL_VERIFY_PEER; verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; verify_mode |= SSL_VERIFY_CLIENT_ONCE; SSL_CTX_set_verify(ctx, verify_mode, cbtls_verify); if (conf->verify_depth) { SSL_CTX_set_verify_depth(ctx, conf->verify_depth); } /* Load randomness */ if (!(RAND_load_file(conf->random_file, 1024*1024))) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error loading randomness"); return NULL; } /* * Set the cipher list if we were told to */ if (conf->cipher_list) { if (!SSL_CTX_set_cipher_list(ctx, conf->cipher_list)) { radlog(L_ERR, "rlm_eap_tls: Error setting cipher list"); return NULL; } } /* * Setup session caching */ if (conf->session_cache_enable) { /* * Create a unique context Id per EAP-TLS configuration. */ if (conf->session_id_name) { snprintf(conf->session_context_id, sizeof(conf->session_context_id), "FreeRADIUS EAP-TLS %s", conf->session_id_name); } else { snprintf(conf->session_context_id, sizeof(conf->session_context_id), "FreeRADIUS EAP-TLS %p", conf); } /* * Cache it, and DON'T auto-clear it. */ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_AUTO_CLEAR); SSL_CTX_set_session_id_context(ctx, (unsigned char *) conf->session_context_id, (unsigned int) strlen(conf->session_context_id)); /* * Our timeout is in hours, this is in seconds. */ SSL_CTX_set_timeout(ctx, conf->session_timeout * 3600); /* * Set the maximum number of entries in the * session cache. */ SSL_CTX_sess_set_cache_size(ctx, conf->session_cache_size); } else { SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); } /* * Register the application indices. We can't use * hard-coded "0" and "1" as before, because we need to * set up a "free" handler for the cached session * information. */ if (eaptls_handle_idx < 0) { eaptls_handle_idx = SSL_get_ex_new_index(0, &eaptls_handle_idx, NULL, NULL, NULL); } if (eaptls_conf_idx < 0) { eaptls_conf_idx = SSL_get_ex_new_index(0, &eaptls_conf_idx, NULL, NULL, NULL); } if (eaptls_store_idx < 0) { eaptls_store_idx = SSL_get_ex_new_index(0, "eaptls_store_idx", NULL, NULL, NULL); } if (eaptls_session_idx < 0) { eaptls_session_idx = SSL_get_ex_new_index(0, &eaptls_session_idx, NULL, NULL, eaptls_session_free); } return ctx; }
pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode ) { if (!ssl_initialized) { ssl_initialized = 1; SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); ssl_ex_data_index = SSL_get_ex_new_index( 0, (void *) "org.apache.qpid.proton.ssl", NULL, NULL, NULL); } pn_ssl_domain_t *domain = (pn_ssl_domain_t *) calloc(1, sizeof(pn_ssl_domain_t)); if (!domain) return NULL; domain->ref_count = 1; domain->mode = mode; // enable all supported protocol versions, then explicitly disable the // known vulnerable ones. This should allow us to use the latest version // of the TLS standard that the installed library supports. switch(mode) { case PN_SSL_MODE_CLIENT: domain->ctx = SSL_CTX_new(SSLv23_client_method()); // and TLSv1+ if (!domain->ctx) { ssl_log_error("Unable to initialize OpenSSL context."); free(domain); return NULL; } break; case PN_SSL_MODE_SERVER: domain->ctx = SSL_CTX_new(SSLv23_server_method()); // and TLSv1+ if (!domain->ctx) { ssl_log_error("Unable to initialize OpenSSL context."); free(domain); return NULL; } break; default: pn_transport_logf(NULL, "Invalid value for pn_ssl_mode_t: %d", mode); free(domain); return NULL; } const long reject_insecure = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; SSL_CTX_set_options(domain->ctx, reject_insecure); #ifdef SSL_OP_NO_COMPRESSION // Mitigate the CRIME vulnerability SSL_CTX_set_options(domain->ctx, SSL_OP_NO_COMPRESSION); #endif // by default, allow anonymous ciphers so certificates are not required 'out of the box' if (!SSL_CTX_set_cipher_list( domain->ctx, CIPHERS_ANONYMOUS )) { ssl_log_error("Failed to set cipher list to %s", CIPHERS_ANONYMOUS); pn_ssl_domain_free(domain); return NULL; } // ditto: by default do not authenticate the peer (can be done by SASL). if (pn_ssl_domain_set_peer_authentication( domain, PN_SSL_ANONYMOUS_PEER, NULL )) { pn_ssl_domain_free(domain); return NULL; } DH *dh = get_dh2048(); if (dh) { SSL_CTX_set_tmp_dh(domain->ctx, dh); DH_free(dh); SSL_CTX_set_options(domain->ctx, SSL_OP_SINGLE_DH_USE); } return domain; }