/* * initialize ssl methods */ static void init_ssl_methods(void) { LM_DBG("entered\n"); ssl_methods[TLS_USE_TLSv1_cli-1] = (SSL_METHOD*)TLSv1_client_method(); ssl_methods[TLS_USE_TLSv1_srv-1] = (SSL_METHOD*)TLSv1_server_method(); ssl_methods[TLS_USE_TLSv1-1] = (SSL_METHOD*)TLSv1_method(); ssl_methods[TLS_USE_SSLv23_cli-1] = (SSL_METHOD*)SSLv23_client_method(); ssl_methods[TLS_USE_SSLv23_srv-1] = (SSL_METHOD*)SSLv23_server_method(); ssl_methods[TLS_USE_SSLv23-1] = (SSL_METHOD*)SSLv23_method(); #if OPENSSL_VERSION_NUMBER >= 0x10001000L ssl_methods[TLS_USE_TLSv1_2_cli-1] = (SSL_METHOD*)TLSv1_2_client_method(); ssl_methods[TLS_USE_TLSv1_2_srv-1] = (SSL_METHOD*)TLSv1_2_server_method(); ssl_methods[TLS_USE_TLSv1_2-1] = (SSL_METHOD*)TLSv1_2_method(); #endif }
/* Initializes SSL and allocate global context SSL_context SYNOPSIS my_ssl_start mysql connection handle RETURN VALUES 0 success 1 error */ int my_ssl_start(MYSQL *mysql) { int rc= 0; DBUG_ENTER("my_ssl_start"); /* lock mutex to prevent multiple initialization */ pthread_mutex_lock(&LOCK_ssl_config); if (!my_ssl_initialized) { #if OPENSSL_VERSION_NUMBER < 0x10100000 if (ssl_crypto_init()) goto end; #endif #if OPENSSL_VERSION_NUMBER >= 0x10100000L OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); #else SSL_library_init(); #if SSLEAY_VERSION_NUMBER >= 0x00907000L OPENSSL_config(NULL); #endif #endif /* load errors */ SSL_load_error_strings(); /* digests and ciphers */ OpenSSL_add_all_algorithms(); #if OPENSSL_VERSION_NUMBER >= 0x10100000L if (!(SSL_context= SSL_CTX_new(TLS_client_method()))) #else if (!(SSL_context= SSL_CTX_new(TLSv1_client_method()))) #endif { my_SSL_error(mysql); rc= 1; goto end; } my_ssl_initialized= TRUE; } end: pthread_mutex_unlock(&LOCK_ssl_config); DBUG_RETURN(rc); }
void _lm_ssl_initialize (LmSSL *ssl) { static gboolean initialized = FALSE; /*const char *cert_file = NULL;*/ if (!initialized) { SSL_library_init(); /* FIXME: Is this needed when we are not in debug? */ SSL_load_error_strings(); initialized = TRUE; } ssl->ssl_method = TLSv1_client_method(); if (ssl->ssl_method == NULL) { g_warning ("TLSv1_client_method() == NULL"); abort(); } ssl->ssl_ctx = SSL_CTX_new(ssl->ssl_method); if (ssl->ssl_ctx == NULL) { g_warning ("SSL_CTX_new() == NULL"); abort(); } /* Set the NO_TICKET option on the context to allow for talk to Google Talk * which apparently seems to be having a problem handling empty session * tickets due to a bug in Java. * * See http://twistedmatrix.com/trac/ticket/3463 and * Loudmouth [#28]. */ SSL_CTX_set_options (ssl->ssl_ctx, SSL_OP_NO_TICKET); /*if (access("/etc/ssl/cert.pem", R_OK) == 0) cert_file = "/etc/ssl/cert.pem"; if (!SSL_CTX_load_verify_locations(ssl->ssl_ctx, cert_file, "/etc/ssl/certs")) { g_warning("SSL_CTX_load_verify_locations() failed"); }*/ SSL_CTX_set_default_verify_paths (ssl->ssl_ctx); SSL_CTX_set_verify (ssl->ssl_ctx, SSL_VERIFY_PEER, ssl_verify_cb); }
// Establish a connection using an SSL layer connection *sslConnect (void) { connection *c; c = malloc (sizeof (connection)); c->sslHandle = NULL; c->sslContext = NULL; c->socket = tcpConnect (); if (c->socket) { // Register the error strings for libcrypto & libssl SSL_load_error_strings (); // Register the available ciphers and digests SSL_library_init (); // SSL_CTX_set_verify( tlsctx, SSL_VERIFY_PEER, verify_callback ); // New context saying we are a client, and using SSL 2 or 3 c->sslContext = SSL_CTX_new (TLSv1_client_method ()); // c->sslContext = SSL_CTX_new (TLSv1_client_method()); if (c->sslContext == NULL) ERR_print_errors_fp (stderr); // Create an SSL struct for the connection c->sslHandle = SSL_new (c->sslContext); if (c->sslHandle == NULL) ERR_print_errors_fp (stderr); // Connect the SSL struct to our connection if (!SSL_set_fd (c->sslHandle, c->socket)) ERR_print_errors_fp (stderr); // Initiate SSL handshake if (SSL_connect (c->sslHandle) != 1) ERR_print_errors_fp (stderr); } else { perror ("Connect failed"); } return c; }
SSL* imap_create_ssl(void) { SSL *ssl; g_mutex_lock(&global_tls_lock); if(!global_ssl_context) { /* Initialize OpenSSL library, follow "Network Security with OpenSSL", ISBN 0-596-00270-X, guidelines. Example 4-2. */ imaptls_thread_setup(); SSL_library_init(); SSL_load_error_strings(); #if 0 global_ssl_context = SSL_CTX_new (TLSv1_client_method ()); #else /* Note: SSLv23_client_method() actually enables *all* protocols, including * SSLv(2|3) and TLSv1.(0|1|2), so we must switch all unsafe ones off */ global_ssl_context = SSL_CTX_new (SSLv23_client_method ()); #ifdef ENABLE_SSL3 SSL_CTX_set_options(global_ssl_context, SSL_OP_ALL|SSL_OP_NO_SSLv2); #else SSL_CTX_set_options(global_ssl_context, SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3); #endif #endif /* no client certificate password support yet * SSL_CTX_set_default_passwd_cb (ctx, ctx_password_cb); * SSL_CTX_set_default_passwd_cb_userdata (ctx, ctx_password_cb_arg); */ /* Load the trusted CAs here. We just trust the system CA for the moment but we could try to be compatible with libESMTP in this respect. */ SSL_CTX_set_default_verify_paths (global_ssl_context); } g_mutex_unlock(&global_tls_lock); ssl = SSL_new(global_ssl_context); /* setup client certificates here */ return ssl; }
/* * initialize ssl methods */ static void init_ssl_methods(void) { DBG("init_methods: Entered\n"); ssl_methods[TLS_USE_SSLv2_cli - 1] = SSLv2_client_method(); ssl_methods[TLS_USE_SSLv2_srv - 1] = SSLv2_server_method(); ssl_methods[TLS_USE_SSLv2 - 1] = SSLv2_method(); ssl_methods[TLS_USE_SSLv3_cli - 1] = SSLv3_client_method(); ssl_methods[TLS_USE_SSLv3_srv - 1] = SSLv3_server_method(); ssl_methods[TLS_USE_SSLv3 - 1] = SSLv3_method(); ssl_methods[TLS_USE_TLSv1_cli - 1] = TLSv1_client_method(); ssl_methods[TLS_USE_TLSv1_srv - 1] = TLSv1_server_method(); ssl_methods[TLS_USE_TLSv1 - 1] = TLSv1_method(); ssl_methods[TLS_USE_SSLv23_cli - 1] = SSLv23_client_method(); ssl_methods[TLS_USE_SSLv23_srv - 1] = SSLv23_server_method(); ssl_methods[TLS_USE_SSLv23 - 1] = SSLv23_method(); }
SSL_CTX *cr_ssl_context_cli(void) { const SSL_METHOD *meth; SSL_CTX *ssl; /* loading ssl features */ SSL_load_error_strings(); OpenSSL_add_all_algorithms(); SSL_library_init(); /* creat a TLSv1 method instance */ meth = TLSv1_client_method(); ssl = SSL_CTX_new(meth); if(!ssl) { ERR_print_errors_fp(stderr); return NULL; } return ssl; }
void TLSConnectionPrivate::OnConnect(uv_connect_t *connect, int status) { TLSConnectionPrivate *cp = static_cast<TLSConnectionPrivate *>(connect->data); assert(cp->state_ == TLS_CONNECTION_STATE_PRE_CONNECT); // Unable to connect. if (status == -1) { cp->ShutdownError(UVUtils::ErrorFromLastUVError(cp->loop_)); return; } // Begin reading the incoming stream of data. int err = uv_read_start(connect->handle, TLSConnectionPrivate::AllocCallback, TLSConnectionPrivate::OnRead); if (err != UV_OK) { cp->ShutdownError(UVUtils::ErrorFromLastUVError(cp->loop_)); return; } // Set up the OpenSSL context const SSL_METHOD *meth = TLSv1_client_method(); cp->ctx_ = SSL_CTX_new(meth); SSL_CTX_set_verify(cp->ctx_, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); SSL_CTX_set_cert_verify_callback(cp->ctx_, TLSConnectionPrivate::SSLVerifyCallback, cp); cp->ssl_ = SSL_new(cp->ctx_); SSL_set_connect_state(cp->ssl_); cp->bio_ = BIO_new(UVBioState::GetMethod()); cp->biostate_ = new UVBioState(connect); cp->bio_->ptr = cp->biostate_; SSL_set_bio(cp->ssl_, cp->bio_, cp->bio_); // Set an empty X509_STORE as our SSL_CTX cert store. // The default store should be empty as well, but let's // make sure. X509_STORE *store = X509_STORE_new(); SSL_CTX_set_cert_store(cp->ctx_, store); cp->state_ = TLS_CONNECTION_STATE_STARVED_SSL_CONNECT; cp->HandleStarvedConnectState(); }
/** * Get internal ssl method ID * @param SSL method pointer * @return Internal ID or 0 if unknown */ uint_fast8_t get_ssl_method_id(const SSL_METHOD *method) { #ifndef OPENSSL_NO_SSL2 if (method == SSLv2_client_method()) return ssl_v2; #endif // #ifndef OPENSSL_NO_SSL2 if (method == SSLv3_client_method()) return ssl_v3; if (method == TLSv1_client_method()) return tls_v10; #if OPENSSL_VERSION_NUMBER >= 0x1000008fL || OPENSSL_VERSION_NUMBER >= 0x1000100fL if (method == TLSv1_1_client_method()) return tls_v11; if (method == TLSv1_2_client_method()) return tls_v12; #endif // #if OPENSSL_VERSION_NUMBER >= 0x1000008fL || OPENSSL_VERSION_NUMBER >= 0x1000100fL return 0; }
/** * Get a ssl method pointer by internal ID * @param id Internal ID * @return SSL method pointer */ const SSL_METHOD *get_ssl_method_by_id(uint_fast8_t id) { #ifndef OPENSSL_NO_SSL2 if (id == ssl_v2) return SSLv2_client_method(); #endif // #ifndef OPENSSL_NO_SSL2 if (id == ssl_v3) return SSLv3_client_method(); if (id == tls_v10) return TLSv1_client_method(); #if OPENSSL_VERSION_NUMBER >= 0x1000008fL || OPENSSL_VERSION_NUMBER >= 0x1000100fL if (id == tls_v11) return TLSv1_1_client_method(); if (id == tls_v12) return TLSv1_2_client_method(); #endif // #if OPENSSL_VERSION_NUMBER >= 0x1000008fL || OPENSSL_VERSION_NUMBER >= 0x1000100fL return NULL; }
/* * Negotiate SSL on the socket */ static DWORD negotiate_ssl(Remote *remote) { DWORD hres = ERROR_SUCCESS; SOCKET fd = remote_get_fd(remote); DWORD ret; SSL_load_error_strings(); SSL_library_init(); remote->meth = TLSv1_client_method(); remote->ctx = SSL_CTX_new(remote->meth); SSL_CTX_set_mode(remote->ctx, SSL_MODE_AUTO_RETRY); remote->ssl = SSL_new(remote->ctx); SSL_set_verify(remote->ssl, SSL_VERIFY_NONE, NULL); if (SSL_set_fd(remote->ssl, remote->fd) == 0) { perror("set fd failed"); exit(1); } if ((ret = SSL_connect(remote->ssl)) != 1) { printf("connect failed %d\n", SSL_get_error(remote->ssl, ret)); exit(1); } dprintf("Sending a HTTP GET request to the remote side..."); if((ret = SSL_write(remote->ssl, "GET / HTTP/1.0\r\n\r\n", 18)) <= 0) { dprintf("SSL write failed during negotiation with return: %d (%d)", ret, SSL_get_error(remote->ssl, ret)); } dprintf("Completed writing the HTTP GET request: %d", ret); if(ret < 0) ExitThread(0); return(0); }
int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsaData = {0}; WSAStartup(MAKEWORD(2, 2), &wsaData); SSLeay_add_all_algorithms(); pthread_t pid; ERR_load_BIO_strings(); SSL_library_init(); SSL_load_error_strings(); SSL *ssl = NULL; SSL_CTX *ctx = NULL; //这里要注意是client ctx = SSL_CTX_new(TLSv1_client_method()); if (ctx == NULL) { printf("ssl ctx new eer\n"); exit(-1); } transf_lock_cs = (pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); transf_lock_count = (long *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); for (int i = 0; i < CRYPTO_num_locks(); i++) { transf_lock_count[i] = 0; pthread_mutex_init(&(transf_lock_cs[i]), NULL); } CRYPTO_set_id_callback((unsigned long(*)())transf_pthreads_thread_id); CRYPTO_set_locking_callback(transf_client_locking_callback); pthread_create(&pid, NULL, tcp_forwardlistenthread, ctx); pthread_join(pid, NULL); system("pause"); getchar(); SSL_CTX_free(ctx); WSACleanup(); return 0; }
int tls_connect(rdpTls* tls, BIO *underlying) { int options = 0; /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; if (!tls_prepare(tls, underlying, TLSv1_client_method(), options, TRUE)) return FALSE; return tls_do_handshake(tls, TRUE); }
const SSL_METHOD * hb_ssl_method_id_to_ptr( int n ) { const SSL_METHOD * p; switch( n ) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L case HB_SSL_CTX_NEW_METHOD_TLS: p = TLS_method(); break; case HB_SSL_CTX_NEW_METHOD_TLS_SERVER: p = TLS_server_method(); break; case HB_SSL_CTX_NEW_METHOD_TLS_CLIENT: p = TLS_client_method(); break; #else case HB_SSL_CTX_NEW_METHOD_TLSV1: p = TLSv1_method(); break; case HB_SSL_CTX_NEW_METHOD_TLSV1_SERVER: p = TLSv1_server_method(); break; case HB_SSL_CTX_NEW_METHOD_TLSV1_CLIENT: p = TLSv1_client_method(); break; case HB_SSL_CTX_NEW_METHOD_TLS: p = SSLv23_method(); break; case HB_SSL_CTX_NEW_METHOD_TLS_SERVER: p = SSLv23_server_method(); break; case HB_SSL_CTX_NEW_METHOD_TLS_CLIENT: p = SSLv23_client_method(); break; #endif default: p = SSLv23_method(); } return p; }
SSL *ssl_client_connect(const char *host, const char *port){ SSL_METHOD *my_ssl_method; SSL_CTX *my_ssl_ctx; SSL *my_ssl; BIO *my_bio; char *host_port; host_port = w_malloc(strlen(host) + strlen(port) + 2); sprintf(host_port, "%s: %s", port, port); my_ssl_method = TLSv1_client_method(); if ((my_ssl_ctx = SSL_CTX_new(my_ssl_method)) == NULL) return NULL; if ((my_ssl = SSL_new(my_ssl_ctx)) == NULL){ SSL_CTX_free(my_ssl_ctx); return NULL; } if ((my_bio = BIO_new_connect(host_port)) == NULL){ SSL_free(my_ssl); w_free(host_port); return NULL; } if (BIO_do_connect(my_bio) <= 0){ SSL_free(my_ssl); BIO_free(my_bio); w_free(host_port); return NULL; } SSL_set_bio(my_ssl, my_bio, my_bio); if (SSL_connect(my_ssl) <= 0){ SSL_free(my_ssl); w_free(host_port); return NULL; } w_free(host_port); return my_ssl; }
static int tls_sc_create(lua_State *L) { tls_sc_t *ctx; const char *method_string = lua_tostring(L, 1); const SSL_METHOD *method = SSLv23_method(); if (method_string) { if (strcmp(method_string, "SSLv3_method") == 0) { method = SSLv3_method(); } else if (strcmp(method_string, "SSLv3_server_method") == 0) { method = SSLv3_server_method(); } else if (strcmp(method_string, "SSLv3_client_method") == 0) { method = SSLv3_client_method(); } else if (strcmp(method_string, "SSLv23_method") == 0) { method = SSLv23_method(); } else if (strcmp(method_string, "SSLv23_server_method") == 0) { method = SSLv23_server_method(); } else if (strcmp(method_string, "SSLv23_client_method") == 0) { method = SSLv23_client_method(); } else if (strcmp(method_string, "TLSv1_method") == 0) { method = TLSv1_method(); } else if (strcmp(method_string, "TLSv1_server_method") == 0) { method = TLSv1_server_method(); } else if (strcmp(method_string, "TLSv1_client_method") == 0) { method = TLSv1_client_method(); } else { return luaL_error(L, "method not supported: %s", method_string); } } ctx = newSC(L); ctx->ctx = SSL_CTX_new(method); /* TODO: customize Session cache */ SSL_CTX_set_session_cache_mode(ctx->ctx, SSL_SESS_CACHE_SERVER); return 1; }
bool SSLSocket::setupCrypto(SSLSocket *session /* = NULL */) { if (m_data->m_handle) { raise_warning("SSL/TLS already set-up for this stream"); return false; } /* need to do slightly different things, based on client/server method, * so lets remember which method was selected */ #if OPENSSL_VERSION_NUMBER < 0x00909000L SSL_METHOD *smethod; #else const SSL_METHOD *smethod; #endif switch (m_data->m_method) { case CryptoMethod::ClientSSLv23: m_data->m_client = true; smethod = SSLv23_client_method(); break; case CryptoMethod::ClientSSLv3: m_data->m_client = true; smethod = SSLv3_client_method(); break; case CryptoMethod::ClientTLS: m_data->m_client = true; smethod = TLSv1_client_method(); break; case CryptoMethod::ServerSSLv23: m_data->m_client = false; smethod = SSLv23_server_method(); break; case CryptoMethod::ServerSSLv3: m_data->m_client = false; smethod = SSLv3_server_method(); break; /* SSLv2 protocol might be disabled in the OpenSSL library */ #ifndef OPENSSL_NO_SSL2 case CryptoMethod::ClientSSLv2: m_data->m_client = true; smethod = SSLv2_client_method(); break; case CryptoMethod::ServerSSLv2: m_data->m_client = false; smethod = SSLv2_server_method(); break; #else case CryptoMethod::ClientSSLv2: case CryptoMethod::ServerSSLv2: raise_warning("OpenSSL library does not support SSL2 protocol"); return false; break; #endif case CryptoMethod::ServerTLS: m_data->m_client = false; smethod = TLSv1_server_method(); break; default: return false; } SSL_CTX *ctx = SSL_CTX_new(smethod); if (ctx == nullptr) { raise_warning("failed to create an SSL context"); return false; } SSL_CTX_set_options(ctx, SSL_OP_ALL); m_data->m_handle = createSSL(ctx); if (m_data->m_handle == nullptr) { raise_warning("failed to create an SSL handle"); SSL_CTX_free(ctx); return false; } if (!SSL_set_fd(m_data->m_handle, getFd())) { handleError(0, true); } if (session) { SSL_copy_session_id(m_data->m_handle, session->m_data->m_handle); } return true; }
int openconnect_open_https(struct openconnect_info *vpninfo) { method_const SSL_METHOD *ssl3_method; SSL *https_ssl; BIO *https_bio; int ssl_sock; int err; if (vpninfo->https_ssl) return 0; if (vpninfo->peer_cert) { X509_free(vpninfo->peer_cert); vpninfo->peer_cert = NULL; } ssl_sock = connect_https_socket(vpninfo); if (ssl_sock < 0) return ssl_sock; ssl3_method = TLSv1_client_method(); if (!vpninfo->https_ctx) { vpninfo->https_ctx = SSL_CTX_new(ssl3_method); /* Some servers (or their firewalls) really don't like seeing extensions. */ #ifdef SSL_OP_NO_TICKET SSL_CTX_set_options(vpninfo->https_ctx, SSL_OP_NO_TICKET); #endif if (vpninfo->cert) { err = load_certificate(vpninfo); if (err) { vpn_progress(vpninfo, PRG_ERR, _("Loading certificate failed. Aborting.\n")); SSL_CTX_free(vpninfo->https_ctx); vpninfo->https_ctx = NULL; close(ssl_sock); return err; } check_certificate_expiry(vpninfo); } /* We just want to do: SSL_CTX_set_purpose(vpninfo->https_ctx, X509_PURPOSE_ANY); ... but it doesn't work with OpenSSL < 0.9.8k because of problems with inheritance (fixed in v1.1.4.6 of crypto/x509/x509_vpm.c) so we have to play silly buggers instead. This trick doesn't work _either_ in < 0.9.7 but I don't know of _any_ workaround which will, and can't be bothered to find out either. */ #if OPENSSL_VERSION_NUMBER >= 0x00908000 SSL_CTX_set_cert_verify_callback(vpninfo->https_ctx, ssl_app_verify_callback, NULL); #endif SSL_CTX_set_default_verify_paths(vpninfo->https_ctx); #ifdef ANDROID_KEYSTORE if (vpninfo->cafile && !strncmp(vpninfo->cafile, "keystore:", 9)) { STACK_OF(X509_INFO) *stack; X509_STORE *store; X509_INFO *info; BIO *b = BIO_from_keystore(vpninfo, vpninfo->cafile); if (!b) { SSL_CTX_free(vpninfo->https_ctx); vpninfo->https_ctx = NULL; close(ssl_sock); return -EINVAL; } stack = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL); BIO_free(b); if (!stack) { vpn_progress(vpninfo, PRG_ERR, _("Failed to read certs from CA file '%s'\n"), vpninfo->cafile); openconnect_report_ssl_errors(vpninfo); SSL_CTX_free(vpninfo->https_ctx); vpninfo->https_ctx = NULL; close(ssl_sock); return -ENOENT; } store = SSL_CTX_get_cert_store(vpninfo->https_ctx); while ((info = sk_X509_INFO_pop(stack))) { if (info->x509) X509_STORE_add_cert(store, info->x509); if (info->crl) X509_STORE_add_crl(store, info->crl); X509_INFO_free(info); } sk_X509_INFO_free(stack); } else #endif if (vpninfo->cafile) { if (!SSL_CTX_load_verify_locations(vpninfo->https_ctx, vpninfo->cafile, NULL)) { vpn_progress(vpninfo, PRG_ERR, _("Failed to open CA file '%s'\n"), vpninfo->cafile); openconnect_report_ssl_errors(vpninfo); SSL_CTX_free(vpninfo->https_ctx); vpninfo->https_ctx = NULL; close(ssl_sock); return -EINVAL; } } } https_ssl = SSL_new(vpninfo->https_ctx); workaround_openssl_certchain_bug(vpninfo, https_ssl); https_bio = BIO_new_socket(ssl_sock, BIO_NOCLOSE); BIO_set_nbio(https_bio, 1); SSL_set_bio(https_ssl, https_bio, https_bio); vpn_progress(vpninfo, PRG_INFO, _("SSL negotiation with %s\n"), vpninfo->hostname); while ((err = SSL_connect(https_ssl)) <= 0) { fd_set wr_set, rd_set; int maxfd = ssl_sock; FD_ZERO(&wr_set); FD_ZERO(&rd_set); err = SSL_get_error(https_ssl, err); if (err == SSL_ERROR_WANT_READ) FD_SET(ssl_sock, &rd_set); else if (err == SSL_ERROR_WANT_WRITE) FD_SET(ssl_sock, &wr_set); else { vpn_progress(vpninfo, PRG_ERR, _("SSL connection failure\n")); openconnect_report_ssl_errors(vpninfo); SSL_free(https_ssl); close(ssl_sock); return -EINVAL; } cmd_fd_set(vpninfo, &rd_set, &maxfd); select(maxfd + 1, &rd_set, &wr_set, NULL, NULL); if (is_cancel_pending(vpninfo, &rd_set)) { vpn_progress(vpninfo, PRG_ERR, _("SSL connection cancelled\n")); SSL_free(https_ssl); close(ssl_sock); return -EINVAL; } } if (verify_peer(vpninfo, https_ssl)) { SSL_free(https_ssl); close(ssl_sock); return -EINVAL; } vpninfo->ssl_fd = ssl_sock; vpninfo->https_ssl = https_ssl; /* Stash this now, because it might not be available later if the server has disconnected. */ vpninfo->peer_cert = SSL_get_peer_certificate(vpninfo->https_ssl); vpn_progress(vpninfo, PRG_INFO, _("Connected to HTTPS on %s\n"), vpninfo->hostname); return 0; }
/* Create a socket and connect it to 'ip' on port 'port'. * Returns -1 on failure (ip is NULL, socket creation/connection error) * Returns sock number on success. */ int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking) { mosq_sock_t sock = INVALID_SOCKET; int rc; #ifdef WITH_TLS int ret; BIO *bio; #endif if(!mosq || !host || !port) return MOSQ_ERR_INVAL; rc = _mosquitto_try_connect(mosq, host, port, &sock, bind_address, blocking); if(rc > 0) return rc; #ifdef WITH_TLS if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){ #if OPENSSL_VERSION_NUMBER >= 0x10001000L if(!mosq->tls_version || !strcmp(mosq->tls_version, "tlsv1.2")){ mosq->ssl_ctx = SSL_CTX_new(TLSv1_2_client_method()); }else if(!strcmp(mosq->tls_version, "tlsv1.1")){ mosq->ssl_ctx = SSL_CTX_new(TLSv1_1_client_method()); }else if(!strcmp(mosq->tls_version, "tlsv1")){ mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method()); }else{ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version); COMPAT_CLOSE(sock); return MOSQ_ERR_INVAL; } #else if(!mosq->tls_version || !strcmp(mosq->tls_version, "tlsv1")){ mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method()); }else{ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version); COMPAT_CLOSE(sock); return MOSQ_ERR_INVAL; } #endif if(!mosq->ssl_ctx){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to create TLS context."); COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } #if OPENSSL_VERSION_NUMBER >= 0x10000000 /* Disable compression */ SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_COMPRESSION); #endif #ifdef SSL_MODE_RELEASE_BUFFERS /* Use even less memory per SSL connection. */ SSL_CTX_set_mode(mosq->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); #endif if(mosq->tls_ciphers){ ret = SSL_CTX_set_cipher_list(mosq->ssl_ctx, mosq->tls_ciphers); if(ret == 0){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", mosq->tls_ciphers); COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } } if(mosq->tls_cafile || mosq->tls_capath){ ret = SSL_CTX_load_verify_locations(mosq->ssl_ctx, mosq->tls_cafile, mosq->tls_capath); if(ret == 0){ #ifdef WITH_BROKER if(mosq->tls_cafile && mosq->tls_capath){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\" and bridge_capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); }else if(mosq->tls_cafile){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\".", mosq->tls_cafile); }else{ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_capath \"%s\".", mosq->tls_capath); } #else if(mosq->tls_cafile && mosq->tls_capath){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\" and capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); }else if(mosq->tls_cafile){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\".", mosq->tls_cafile); }else{ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath); } #endif COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } if(mosq->tls_cert_reqs == 0){ SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_NONE, NULL); }else{ SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_PEER, _mosquitto_server_certificate_verify); } if(mosq->tls_pw_callback){ SSL_CTX_set_default_passwd_cb(mosq->ssl_ctx, mosq->tls_pw_callback); SSL_CTX_set_default_passwd_cb_userdata(mosq->ssl_ctx, mosq); } if(mosq->tls_certfile){ ret = SSL_CTX_use_certificate_chain_file(mosq->ssl_ctx, mosq->tls_certfile); if(ret != 1){ #ifdef WITH_BROKER _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate, check bridge_certfile \"%s\".", mosq->tls_certfile); #else _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate \"%s\".", mosq->tls_certfile); #endif COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } } if(mosq->tls_keyfile){ ret = SSL_CTX_use_PrivateKey_file(mosq->ssl_ctx, mosq->tls_keyfile, SSL_FILETYPE_PEM); if(ret != 1){ #ifdef WITH_BROKER _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file, check bridge_keyfile \"%s\".", mosq->tls_keyfile); #else _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file \"%s\".", mosq->tls_keyfile); #endif COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } ret = SSL_CTX_check_private_key(mosq->ssl_ctx); if(ret != 1){ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Client certificate/key are inconsistent."); COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } } #ifdef REAL_WITH_TLS_PSK }else if(mosq->tls_psk){ SSL_CTX_set_psk_client_callback(mosq->ssl_ctx, psk_client_callback); #endif } mosq->ssl = SSL_new(mosq->ssl_ctx); if(!mosq->ssl){ COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } SSL_set_ex_data(mosq->ssl, tls_ex_index_mosq, mosq); bio = BIO_new_socket(sock, BIO_NOCLOSE); if(!bio){ COMPAT_CLOSE(sock); return MOSQ_ERR_TLS; } SSL_set_bio(mosq->ssl, bio, bio); mosq->sock = sock; if(mosquitto__socket_connect_tls(mosq)){ return MOSQ_ERR_TLS; } } #endif mosq->sock = sock; return rc; }
boolean tls_connect(rdpTls* tls) { CryptoCert cert; int connection_status; tls->ctx = SSL_CTX_new(TLSv1_client_method()); if (tls->ctx == NULL) { printf("SSL_CTX_new failed\n"); return false; } /* * This is necessary, because the Microsoft TLS implementation is not perfect. * SSL_OP_ALL enables a couple of workarounds for buggy TLS implementations, * but the most important workaround being SSL_OP_TLS_BLOCK_PADDING_BUG. * As the size of the encrypted payload may give hints about its contents, * block padding is normally used, but the Microsoft TLS implementation * won't recognize it and will disconnect you after sending a TLS alert. */ SSL_CTX_set_options(tls->ctx, SSL_OP_ALL); tls->ssl = SSL_new(tls->ctx); if (tls->ssl == NULL) { SSL_CTX_free(tls->ctx); printf("SSL_new failed\n"); return false; } if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) { SSL_free(tls->ssl); SSL_CTX_free(tls->ctx); printf("SSL_set_fd failed\n"); return false; } connection_status = SSL_connect(tls->ssl); if (connection_status <= 0) { if (tls_print_error("SSL_connect", tls->ssl, connection_status)) { SSL_free(tls->ssl); SSL_CTX_free(tls->ctx); return false; } } cert = tls_get_certificate(tls); if (cert == NULL) { printf("tls_connect: tls_get_certificate failed to return the server certificate.\n"); return false; } if (!crypto_cert_get_public_key(cert, &tls->public_key)) { printf("tls_connect: crypto_cert_get_public_key failed to return the server public key.\n"); return false; } if (!tls_verify_certificate(tls, cert, tls->settings->hostname)) tls_disconnect(tls); tls_free_certificate(cert); return true; }
boolean tls_connect(rdpTls* tls) { CryptoCert cert; long options = 0; int connection_status; tls->ctx = SSL_CTX_new(TLSv1_client_method()); if (tls->ctx == NULL) { printf("SSL_CTX_new failed\n"); return false; } /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; SSL_CTX_set_options(tls->ctx, options); tls->ssl = SSL_new(tls->ctx); if (tls->ssl == NULL) { printf("SSL_new failed\n"); return false; } if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) { printf("SSL_set_fd failed\n"); return false; } connection_status = SSL_connect(tls->ssl); if (connection_status <= 0) { if (tls_print_error("SSL_connect", tls->ssl, connection_status)) { return false; } } cert = tls_get_certificate(tls, true); if (cert == NULL) { printf("tls_connect: tls_get_certificate failed to return the server certificate.\n"); return false; } if (!crypto_cert_get_public_key(cert, &tls->public_key)) { printf("tls_connect: crypto_cert_get_public_key failed to return the server public key.\n"); tls_free_certificate(cert) ; return false; } if (!tls_verify_certificate(tls, cert, tls->settings->hostname)) { printf("tls_connect: certificate not trusted, aborting.\n"); tls_disconnect(tls); tls_free_certificate(cert); return false; } tls_free_certificate(cert); return true; }
BOOL tls_connect(rdpTls* tls) { CryptoCert cert; long options = 0; int connection_status; char *hostname; tls->ctx = SSL_CTX_new(TLSv1_client_method()); if (tls->ctx == NULL) { fprintf(stderr, "SSL_CTX_new failed\n"); return FALSE; } //SSL_CTX_set_mode(tls->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE); /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; SSL_CTX_set_options(tls->ctx, options); tls->ssl = SSL_new(tls->ctx); if (tls->ssl == NULL) { fprintf(stderr, "SSL_new failed\n"); return FALSE; } if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) { fprintf(stderr, "SSL_set_fd failed\n"); return FALSE; } connection_status = SSL_connect(tls->ssl); if (connection_status <= 0) { if (tls_print_error("SSL_connect", tls->ssl, connection_status)) { return FALSE; } } cert = tls_get_certificate(tls, TRUE); if (cert == NULL) { fprintf(stderr, "tls_connect: tls_get_certificate failed to return the server certificate.\n"); return FALSE; } tls->Bindings = tls_get_channel_bindings(cert->px509); if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength)) { fprintf(stderr, "tls_connect: crypto_cert_get_public_key failed to return the server public key.\n"); tls_free_certificate(cert); return FALSE; } if (tls->settings->GatewayUsageMethod) hostname = tls->settings->GatewayHostname; else hostname = tls->settings->ServerHostname; if (!tls_verify_certificate(tls, cert, hostname)) { fprintf(stderr, "tls_connect: certificate not trusted, aborting.\n"); tls_disconnect(tls); tls_free_certificate(cert); return FALSE; } tls_free_certificate(cert); return TRUE; }
static struct mailstream_ssl_data * tls_data_new(int fd, time_t timeout, void (* callback)(struct mailstream_ssl_context * ssl_context, void * cb_data), void * cb_data) { return ssl_data_new_full(fd, timeout, TLSv1_client_method(), callback, cb_data); }
/** * Run SSL handshake and store the resulting time value in the * 'time_map'. * * @param time_map where to store the current time */ static void run_ssl (uint32_t *time_map) { BIO *s_bio; BIO *c_bio; SSL_CTX *ctx; SSL *ssl; SSL_load_error_strings(); SSL_library_init(); ctx = NULL; if (0 == strcmp("sslv23", protocol)) { verb ("V: using SSLv23_client_method()\n"); ctx = SSL_CTX_new(SSLv23_client_method()); } else if (0 == strcmp("sslv3", protocol)) { verb ("V: using SSLv3_client_method()\n"); ctx = SSL_CTX_new(SSLv3_client_method()); } else if (0 == strcmp("tlsv1", protocol)) { verb ("V: using TLSv1_client_method()\n"); ctx = SSL_CTX_new(TLSv1_client_method()); } else die("Unsupported protocol `%s'\n", protocol); if (ctx == NULL) die("OpenSSL failed to support protocol `%s'\n", protocol); if (ca_racket) { // For google specifically: // SSL_CTX_load_verify_locations(ctx, "/etc/ssl/certs/Equifax_Secure_CA.pem", NULL); if (1 != SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs/")) fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); } if (NULL == (s_bio = BIO_new_ssl_connect(ctx))) die ("SSL BIO setup failed\n"); BIO_get_ssl(s_bio, &ssl); if (NULL == ssl) die ("SSL setup failed\n"); SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); if ( (1 != BIO_set_conn_hostname(s_bio, host)) || (1 != BIO_set_conn_port(s_bio, port)) ) die ("Failed to initialize connection to `%s:%s'\n", host, port); if (NULL == (c_bio = BIO_new_fp(stdout, BIO_NOCLOSE))) die ("FIXME: error message"); // This should run in seccomp // eg: prctl(PR_SET_SECCOMP, 1); if (1 != BIO_do_connect(s_bio)) // XXX TODO: BIO_should_retry() later? die ("SSL connection failed\n"); if (1 != BIO_do_handshake(s_bio)) die ("SSL handshake failed\n"); // Verify the peer certificate against the CA certs on the local system if (ca_racket) { X509 *x509; long ssl_verify_result; if (NULL == (x509 = SSL_get_peer_certificate(ssl)) ) die ("Getting SSL certificate failed\n"); // In theory, we verify that the cert is valid ssl_verify_result = SSL_get_verify_result(ssl); switch (ssl_verify_result) { case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: die ("SSL certificate is self signed\n"); case X509_V_OK: verb ("V: SSL certificate verification passed\n"); break; default: die ("SSL certification verification error: %ld\n", ssl_verify_result); } } else { verb ("V: Certificate verification skipped!\n"); } // from /usr/include/openssl/ssl3.h // ssl->s3->server_random is an unsigned char of 32 bytes memcpy(time_map, ssl->s3->server_random, sizeof (uint32_t)); }
int main(int argc, char **argv) { int port = 0; int messagenumber = 5; char local_addr[256]; int c; int mclient = 1; char peer_address[129] = "\0"; int peer_port = PEER_DEFAULT_PORT; char rest_api_separator = ':'; int use_null_cipher=0; set_logfile("stdout"); set_execdir(); set_system_parameters(0); ns_bzero(local_addr, sizeof(local_addr)); while ((c = getopt(argc, argv, "d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:vsyhcxXgtTSAPDNOUHMRIGB")) != -1) { switch (c){ case 'B': random_disconnect = 1; break; case 'G': extra_requests = 1; break; case 'F': STRCPY(cipher_suite,optarg); break; case 'I': no_permissions = 1; break; case 'M': mobility = 1; break; case 'H': shatype = SHATYPE_SHA256; break; case 'E': { char* fn = find_config_file(optarg,1); if(!fn) { fprintf(stderr,"ERROR: file %s not found\n",optarg); exit(-1); } STRCPY(ca_cert_file,fn); } break; case 'O': dos = 1; break; case 'C': rest_api_separator=*optarg; break; case 'D': mandatory_channel_padding = 1; break; case 'N': negative_test = 1; break; case 'R': negative_protocol_test = 1; break; case 'z': RTP_PACKET_INTERVAL = atoi(optarg); break; case 'A': use_short_term = 1; break; case 'u': STRCPY(g_uname, optarg); break; case 'w': STRCPY(g_upwd, optarg); break; case 'g': dont_fragment = 1; break; case 'd': STRCPY(client_ifname, optarg); break; case 'x': default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; break; case 'X': default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4; break; case 'l': clmessage_length = atoi(optarg); break; case 's': do_not_use_channel = 1; break; case 'n': messagenumber = atoi(optarg); break; case 'p': port = atoi(optarg); break; case 'L': STRCPY(local_addr, optarg); break; case 'e': STRCPY(peer_address, optarg); break; case 'r': peer_port = atoi(optarg); break; case 'v': clnet_verbose = TURN_VERBOSE_NORMAL; break; case 'h': hang_on = 1; break; case 'c': no_rtcp = 1; break; case 'm': mclient = atoi(optarg); break; case 'y': c2c = 1; break; case 't': use_tcp = 1; break; case 'P': passive_tcp = 1; /* implies 'T': */ /* no break */ case 'T': relay_transport = STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE; break; case 'U': use_null_cipher = 1; /* implies 'S' */ /* no break */ case 'S': use_secure = 1; break; case 'W': g_use_auth_secret_with_timestamp = 1; STRCPY(g_auth_secret,optarg); break; case 'i': { char* fn = find_config_file(optarg,1); if(!fn) { fprintf(stderr,"ERROR: file %s not found\n",optarg); exit(-1); } STRCPY(cert_file,fn); free(fn); } break; case 'k': { char* fn = find_config_file(optarg,1); if(!fn) { fprintf(stderr,"ERROR: file %s not found\n",optarg); exit(-1); } STRCPY(pkey_file,fn); free(fn); } break; default: fprintf(stderr, "%s\n", Usage); exit(1); } } if(g_use_auth_secret_with_timestamp) { if(use_short_term) { fprintf(stderr,"ERROR: You cannot use authentication secret (REST API) with short-term credentials mechanism.\n"); exit(-1); } { char new_uname[1025]; const unsigned long exp_time = 3600 * 24; /* one day */ if(g_uname[0]) { snprintf(new_uname,sizeof(new_uname),"%lu%c%s",(unsigned long)time(NULL) + exp_time,rest_api_separator, (char*)g_uname); } else { snprintf(new_uname,sizeof(new_uname),"%lu", (unsigned long)time(NULL) + exp_time); } STRCPY(g_uname,new_uname); } { u08bits hmac[MAXSHASIZE]; unsigned int hmac_len; switch(shatype) { case SHATYPE_SHA256: hmac_len = SHA256SIZEBYTES; break; default: hmac_len = SHA1SIZEBYTES; }; hmac[0]=0; if(stun_calculate_hmac(g_uname, strlen((char*)g_uname), (u08bits*)g_auth_secret, strlen(g_auth_secret), hmac, &hmac_len, shatype)>=0) { size_t pwd_length = 0; char *pwd = base64_encode(hmac,hmac_len,&pwd_length); if(pwd) { if(pwd_length>0) { ns_bcopy(pwd,g_upwd,pwd_length); g_upwd[pwd_length]=0; } } free(pwd); } } } if(is_TCP_relay()) { dont_fragment = 0; no_rtcp = 1; c2c = 1; use_tcp = 1; do_not_use_channel = 1; } if(port == 0) { if(use_secure) port = DEFAULT_STUN_TLS_PORT; else port = DEFAULT_STUN_PORT; } if (clmessage_length < (int) sizeof(message_info)) clmessage_length = (int) sizeof(message_info); const int max_header = 100; if(clmessage_length > (int)(STUN_BUFFER_SIZE-max_header)) { fprintf(stderr,"Message length was corrected to %d\n",(STUN_BUFFER_SIZE-max_header)); clmessage_length = (int)(STUN_BUFFER_SIZE-max_header); } if (optind >= argc) { fprintf(stderr, "%s\n", Usage); exit(-1); } if (!c2c) { if (make_ioa_addr((const u08bits*) peer_address, peer_port, &peer_addr) < 0) return -1; if(peer_addr.ss.sa_family == AF_INET6) default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6; } /* SSL Init ==>> */ if(use_secure) { SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); const char *csuite = "ALL"; //"AES256-SHA" "DH" if(use_null_cipher) csuite = "eNULL"; else if(cipher_suite[0]) csuite=cipher_suite; if(use_tcp) { root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(SSLv3_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; #if defined(SSL_TXT_TLSV1_1) root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_1_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; #if defined(SSL_TXT_TLSV1_2) root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_2_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; #endif #endif } else { #if defined(TURN_NO_DTLS) fprintf(stderr,"ERROR: DTLS is not supported.\n"); exit(-1); #else if(OPENSSL_VERSION_NUMBER < 0x10000000L) { TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: OpenSSL version is rather old, DTLS may not be working correctly.\n"); } root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_client_method()); SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite); root_tls_ctx_num++; #endif } int sslind = 0; for(sslind = 0; sslind<root_tls_ctx_num; sslind++) { if(cert_file[0]) { if (!SSL_CTX_use_certificate_chain_file(root_tls_ctx[sslind], cert_file)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nERROR: no certificate found!\n"); exit(-1); } } if (!SSL_CTX_use_PrivateKey_file(root_tls_ctx[sslind], pkey_file, SSL_FILETYPE_PEM)) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nERROR: no private key found!\n"); exit(-1); } if(cert_file[0]) { if (!SSL_CTX_check_private_key(root_tls_ctx[sslind])) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nERROR: invalid private key!\n"); exit(-1); } } if (ca_cert_file[0]) { if (!SSL_CTX_load_verify_locations(root_tls_ctx[sslind], ca_cert_file, NULL )) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: cannot load CA from file: %s\n", ca_cert_file); } /* Set to require peer (client) certificate verification */ SSL_CTX_set_verify(root_tls_ctx[sslind], SSL_VERIFY_PEER, NULL ); /* Set the verification depth to 9 */ SSL_CTX_set_verify_depth(root_tls_ctx[sslind], 9); } else { SSL_CTX_set_verify(root_tls_ctx[sslind], SSL_VERIFY_NONE, NULL ); } if(!use_tcp) SSL_CTX_set_read_ahead(root_tls_ctx[sslind], 1); } } start_mclient(argv[optind], port, client_ifname, local_addr, messagenumber, mclient); return 0; }
HTTPScode https_init(const char *useragent, const char *cafile, const char *proxy) { X509_STORE *store; X509 *cert; BIO *bio; char *p; if ((ctx = calloc(1, sizeof(*ctx))) == NULL || (ctx->useragent = strdup(useragent)) == NULL) { ctx->errstr = strerror(errno); return (HTTPS_ERR_SYSTEM); } /* Initialize SSL context */ SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); /* XXX - ape openssl s_client -rand for testing on ancient systems */ if (!RAND_status()) { if ((p = getenv("RANDFILE")) != NULL) { RAND_load_file(p, 8192); } else { ctx->errstr = "No /dev/random, EGD, or $RANDFILE"; return (HTTPS_ERR_LIB); } } if ((ctx->ssl_ctx = SSL_CTX_new(TLSv1_client_method())) == NULL) { ctx->errstr = _SSL_strerror(); return (HTTPS_ERR_LIB); } /* Set up our CA cert */ if (cafile == NULL) { /* Load default CA cert from memory */ if ((bio = BIO_new_mem_buf((void *)CACERT_PEM, -1)) == NULL || (store = SSL_CTX_get_cert_store(ctx->ssl_ctx)) == NULL) { ctx->errstr = _SSL_strerror(); return (HTTPS_ERR_LIB); } while ((cert = PEM_read_bio_X509(bio, NULL, 0, NULL)) != NULL) { X509_STORE_add_cert(store, cert); X509_free(cert); } BIO_free_all(bio); SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, NULL); } else if (cafile[0] == '\0') { /* Skip verification */ SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_NONE, NULL); } else { /* Load CA cert from file */ if (!SSL_CTX_load_verify_locations(ctx->ssl_ctx, cafile, NULL)) { SSL_CTX_free(ctx->ssl_ctx); ctx->errstr = _SSL_strerror(); return (HTTPS_ERR_CLIENT); } SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, NULL); } /* Save our proxy config if any */ if ((p = getenv("http_proxy")) != NULL || (p = (char *)proxy) != NULL) { if (strstr(p, "://") != NULL) { if (strncmp(p, "http://", 7) != 0) { ctx->errstr = "http_proxy must be HTTP"; return (HTTPS_ERR_CLIENT); } p += 7; } p = strdup(p); if ((ctx->proxy = strchr(p, '@')) != NULL) { *ctx->proxy++ = '\0'; ctx->proxy_auth = p; } else { ctx->proxy = p; } strtok(ctx->proxy, "/"); if ((ctx->proxy_port = strchr(ctx->proxy, ':')) != NULL) { *ctx->proxy_port++ = '\0'; } else { ctx->proxy_port = "80"; } } /* Set HTTP parser callbacks */ ctx->parse_settings.on_body = __on_body; ctx->parse_settings.on_message_complete = __on_message_complete; signal(SIGPIPE, SIG_IGN); return (0); }
/* * This function loads all the client/CA certificates and CRLs. Setup the TLS * layer and do all necessary magic. */ static CURLcode cyassl_connect_step1(struct connectdata *conn, int sockindex) { struct SessionHandle *data = conn->data; struct ssl_connect_data* conssl = &conn->ssl[sockindex]; SSL_METHOD* req_method = NULL; void* ssl_sessionid = NULL; curl_socket_t sockfd = conn->sock[sockindex]; if(conssl->state == ssl_connection_complete) return CURLE_OK; /* CyaSSL doesn't support SSLv2 */ if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) { failf(data, "CyaSSL does not support SSLv2"); return CURLE_SSL_CONNECT_ERROR; } /* check to see if we've been told to use an explicit SSL/TLS version */ switch(data->set.ssl.version) { default: case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: infof(data, "CyaSSL cannot be configured to use TLS 1.0-1.2, " "TLS 1.0 is used exclusively\n"); req_method = TLSv1_client_method(); break; case CURL_SSLVERSION_TLSv1_0: req_method = TLSv1_client_method(); break; case CURL_SSLVERSION_TLSv1_1: req_method = TLSv1_1_client_method(); break; case CURL_SSLVERSION_TLSv1_2: req_method = TLSv1_2_client_method(); break; case CURL_SSLVERSION_SSLv3: req_method = SSLv3_client_method(); break; } if(!req_method) { failf(data, "SSL: couldn't create a method!"); return CURLE_OUT_OF_MEMORY; } if(conssl->ctx) SSL_CTX_free(conssl->ctx); conssl->ctx = SSL_CTX_new(req_method); if(!conssl->ctx) { failf(data, "SSL: couldn't create a context!"); return CURLE_OUT_OF_MEMORY; } #ifndef NO_FILESYSTEM /* load trusted cacert */ if(data->set.str[STRING_SSL_CAFILE]) { if(!SSL_CTX_load_verify_locations(conssl->ctx, data->set.str[STRING_SSL_CAFILE], data->set.str[STRING_SSL_CAPATH])) { if(data->set.ssl.verifypeer) { /* Fail if we insist on successfully verifying the server. */ failf(data,"error setting certificate verify locations:\n" " CAfile: %s\n CApath: %s", data->set.str[STRING_SSL_CAFILE]? data->set.str[STRING_SSL_CAFILE]: "none", data->set.str[STRING_SSL_CAPATH]? data->set.str[STRING_SSL_CAPATH] : "none"); return CURLE_SSL_CACERT_BADFILE; } else { /* Just continue with a warning if no strict certificate verification is required. */ infof(data, "error setting certificate verify locations," " continuing anyway:\n"); } } else { /* Everything is fine. */ infof(data, "successfully set certificate verify locations:\n"); } infof(data, " CAfile: %s\n" " CApath: %s\n", data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]: "none", data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]: "none"); } /* Load the client certificate, and private key */ if(data->set.str[STRING_CERT] && data->set.str[STRING_KEY]) { int file_type = do_file_type(data->set.str[STRING_CERT_TYPE]); if(SSL_CTX_use_certificate_file(conssl->ctx, data->set.str[STRING_CERT], file_type) != 1) { failf(data, "unable to use client certificate (no key or wrong pass" " phrase?)"); return CURLE_SSL_CONNECT_ERROR; } file_type = do_file_type(data->set.str[STRING_KEY_TYPE]); if(SSL_CTX_use_PrivateKey_file(conssl->ctx, data->set.str[STRING_KEY], file_type) != 1) { failf(data, "unable to set private key"); return CURLE_SSL_CONNECT_ERROR; } } #else if(CyaSSL_no_filesystem_verify(conssl->ctx)!= SSL_SUCCESS) { return CURLE_SSL_CONNECT_ERROR; } #endif /* NO_FILESYSTEM */ /* SSL always tries to verify the peer, this only says whether it should * fail to connect if the verification fails, or if it should continue * anyway. In the latter case the result of the verification is checked with * SSL_get_verify_result() below. */ SSL_CTX_set_verify(conssl->ctx, data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE, NULL); /* Let's make an SSL structure */ if(conssl->handle) SSL_free(conssl->handle); conssl->handle = SSL_new(conssl->ctx); if(!conssl->handle) { failf(data, "SSL: couldn't create a context (handle)!"); return CURLE_OUT_OF_MEMORY; } /* Check if there's a cached ID we can/should use here! */ if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) { /* we got a session id, use it! */ if(!SSL_set_session(conssl->handle, ssl_sessionid)) { failf(data, "SSL: SSL_set_session failed: %s", ERR_error_string(SSL_get_error(conssl->handle, 0),NULL)); return CURLE_SSL_CONNECT_ERROR; } /* Informational message */ infof (data, "SSL re-using session ID\n"); } /* pass the raw socket into the SSL layer */ if(!SSL_set_fd(conssl->handle, (int)sockfd)) { failf(data, "SSL: SSL_set_fd failed"); return CURLE_SSL_CONNECT_ERROR; } conssl->connecting_state = ssl_connect_2; return CURLE_OK; }
bool ssl_init () { SSL_METHOD *meth; if (ssl_ctx) /* The SSL has already been initialized. */ return true; /* Init the PRNG. If that fails, bail out. */ init_prng (); if (RAND_status () != 1) { logprintf (LOG_NOTQUIET, _("Could not seed PRNG; consider using --random-file.\n")); goto error; } SSL_library_init (); SSL_load_error_strings (); SSLeay_add_all_algorithms (); SSLeay_add_ssl_algorithms (); switch (opt.secure_protocol) { case secure_protocol_auto: meth = SSLv23_client_method (); break; case secure_protocol_sslv2: meth = SSLv2_client_method (); break; case secure_protocol_sslv3: meth = SSLv3_client_method (); break; case secure_protocol_tlsv1: meth = TLSv1_client_method (); break; default: abort (); } ssl_ctx = SSL_CTX_new (meth); if (!ssl_ctx) goto error; SSL_CTX_set_default_verify_paths (ssl_ctx); SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory); /* SSL_VERIFY_NONE instructs OpenSSL not to abort SSL_connect if the certificate is invalid. We verify the certificate separately in ssl_check_certificate, which provides much better diagnostics than examining the error stack after a failed SSL_connect. */ SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL); if (opt.cert_file) if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file, key_type_to_ssl_type (opt.cert_type)) != 1) goto error; if (opt.private_key) if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key, key_type_to_ssl_type (opt.private_key_type)) != 1) goto error; /* Since fd_write unconditionally assumes partial writes (and handles them correctly), allow them in OpenSSL. */ SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); /* The OpenSSL library can handle renegotiations automatically, so tell it to do so. */ SSL_CTX_set_mode (ssl_ctx, SSL_MODE_AUTO_RETRY); return true; error: if (ssl_ctx) SSL_CTX_free (ssl_ctx); print_errors (); return false; }
int MAIN(int argc, char **argv) { int off=0; SSL *con=NULL,*con2=NULL; X509_STORE *store = NULL; int s,k,width,state=0; char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL; int cbuf_len,cbuf_off; int sbuf_len,sbuf_off; fd_set readfds,writefds; short port=PORT; int full_log=1; char *host=SSL_HOST_NAME; char *cert_file=NULL,*key_file=NULL; int cert_format = FORMAT_PEM, key_format = FORMAT_PEM; char *passarg = NULL, *pass = NULL; X509 *cert = NULL; EVP_PKEY *key = NULL; char *CApath=NULL,*CAfile=NULL,*cipher=NULL; int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0; int crlf=0; int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending; SSL_CTX *ctx=NULL; int ret=1,in_init=1,i,nbio_test=0; int starttls_proto = PROTO_OFF; int prexit = 0, vflags = 0; SSL_METHOD *meth=NULL; #ifdef sock_type #undef sock_type #endif int sock_type=SOCK_STREAM; BIO *sbio; char *inrand=NULL; int mbuf_len=0; #ifndef OPENSSL_NO_ENGINE char *engine_id=NULL; ENGINE *e=NULL; #endif #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) struct timeval tv; #endif struct sockaddr peer; int peerlen = sizeof(peer); int enable_timeouts = 0 ; long mtu = 0; #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) meth=SSLv23_client_method(); #elif !defined(OPENSSL_NO_SSL3) meth=SSLv3_client_method(); #elif !defined(OPENSSL_NO_SSL2) meth=SSLv2_client_method(); #endif apps_startup(); c_Pause=0; c_quiet=0; c_ign_eof=0; c_debug=0; c_msg=0; c_showcerts=0; if (bio_err == NULL) bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; if ( ((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) || ((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) || ((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL)) { BIO_printf(bio_err,"out of memory\n"); goto end; } verify_depth=0; verify_error=X509_V_OK; #ifdef FIONBIO c_nbio=0; #endif argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-host") == 0) { if (--argc < 1) goto bad; host= *(++argv); } else if (strcmp(*argv,"-port") == 0) { if (--argc < 1) goto bad; port=atoi(*(++argv)); if (port == 0) goto bad; } else if (strcmp(*argv,"-connect") == 0) { if (--argc < 1) goto bad; if (!extract_host_port(*(++argv),&host,NULL,&port)) goto bad; } else if (strcmp(*argv,"-verify") == 0) { verify=SSL_VERIFY_PEER; if (--argc < 1) goto bad; verify_depth=atoi(*(++argv)); BIO_printf(bio_err,"verify depth is %d\n",verify_depth); } else if (strcmp(*argv,"-cert") == 0) { if (--argc < 1) goto bad; cert_file= *(++argv); } else if (strcmp(*argv,"-certform") == 0) { if (--argc < 1) goto bad; cert_format = str2fmt(*(++argv)); } else if (strcmp(*argv,"-crl_check") == 0) vflags |= X509_V_FLAG_CRL_CHECK; else if (strcmp(*argv,"-crl_check_all") == 0) vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; else if (strcmp(*argv,"-prexit") == 0) prexit=1; else if (strcmp(*argv,"-crlf") == 0) crlf=1; else if (strcmp(*argv,"-quiet") == 0) { c_quiet=1; c_ign_eof=1; } else if (strcmp(*argv,"-ign_eof") == 0) c_ign_eof=1; else if (strcmp(*argv,"-pause") == 0) c_Pause=1; else if (strcmp(*argv,"-debug") == 0) c_debug=1; #ifdef WATT32 else if (strcmp(*argv,"-wdebug") == 0) dbug_init(); #endif else if (strcmp(*argv,"-msg") == 0) c_msg=1; else if (strcmp(*argv,"-showcerts") == 0) c_showcerts=1; else if (strcmp(*argv,"-nbio_test") == 0) nbio_test=1; else if (strcmp(*argv,"-state") == 0) state=1; #ifndef OPENSSL_NO_SSL2 else if (strcmp(*argv,"-ssl2") == 0) meth=SSLv2_client_method(); #endif #ifndef OPENSSL_NO_SSL3 else if (strcmp(*argv,"-ssl3") == 0) meth=SSLv3_client_method(); #endif #ifndef OPENSSL_NO_TLS1 else if (strcmp(*argv,"-tls1") == 0) meth=TLSv1_client_method(); #endif #ifndef OPENSSL_NO_DTLS1 else if (strcmp(*argv,"-dtls1") == 0) { meth=DTLSv1_client_method(); sock_type=SOCK_DGRAM; } else if (strcmp(*argv,"-timeout") == 0) enable_timeouts=1; else if (strcmp(*argv,"-mtu") == 0) { if (--argc < 1) goto bad; mtu = atol(*(++argv)); } #endif else if (strcmp(*argv,"-bugs") == 0) bugs=1; else if (strcmp(*argv,"-keyform") == 0) { if (--argc < 1) goto bad; key_format = str2fmt(*(++argv)); } else if (strcmp(*argv,"-pass") == 0) { if (--argc < 1) goto bad; passarg = *(++argv); } else if (strcmp(*argv,"-key") == 0) { if (--argc < 1) goto bad; key_file= *(++argv); } else if (strcmp(*argv,"-reconnect") == 0) { reconnect=5; } else if (strcmp(*argv,"-CApath") == 0) { if (--argc < 1) goto bad; CApath= *(++argv); } else if (strcmp(*argv,"-CAfile") == 0) { if (--argc < 1) goto bad; CAfile= *(++argv); } else if (strcmp(*argv,"-no_tls1") == 0) off|=SSL_OP_NO_TLSv1; else if (strcmp(*argv,"-no_ssl3") == 0) off|=SSL_OP_NO_SSLv3; else if (strcmp(*argv,"-no_ssl2") == 0) off|=SSL_OP_NO_SSLv2; else if (strcmp(*argv,"-serverpref") == 0) off|=SSL_OP_CIPHER_SERVER_PREFERENCE; else if (strcmp(*argv,"-cipher") == 0) { if (--argc < 1) goto bad; cipher= *(++argv); } #ifdef FIONBIO else if (strcmp(*argv,"-nbio") == 0) { c_nbio=1; } #endif else if (strcmp(*argv,"-starttls") == 0) { if (--argc < 1) goto bad; ++argv; if (strcmp(*argv,"smtp") == 0) starttls_proto = PROTO_SMTP; else if (strcmp(*argv,"pop3") == 0) starttls_proto = PROTO_POP3; else if (strcmp(*argv,"imap") == 0) starttls_proto = PROTO_IMAP; else if (strcmp(*argv,"ftp") == 0) starttls_proto = PROTO_FTP; else goto bad; } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine_id = *(++argv); } #endif else if (strcmp(*argv,"-rand") == 0) { if (--argc < 1) goto bad; inrand= *(++argv); } else { BIO_printf(bio_err,"unknown option %s\n",*argv); badop=1; break; } argc--; argv++; } if (badop) { bad: sc_usage(); goto end; } OpenSSL_add_ssl_algorithms(); SSL_load_error_strings(); #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine_id, 1); #endif if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (key_file == NULL) key_file = cert_file; if (key_file) { key = load_key(bio_err, key_file, key_format, 0, pass, e, "client certificate private key file"); if (!key) { ERR_print_errors(bio_err); goto end; } } if (cert_file) { cert = load_cert(bio_err,cert_file,cert_format, NULL, e, "client certificate file"); if (!cert) { ERR_print_errors(bio_err); goto end; } } if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL && !RAND_status()) { BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n"); } if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); if (bio_c_out == NULL) { if (c_quiet && !c_debug && !c_msg) { bio_c_out=BIO_new(BIO_s_null()); } else { if (bio_c_out == NULL) bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE); } } ctx=SSL_CTX_new(meth); if (ctx == NULL) { ERR_print_errors(bio_err); goto end; } if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL|off); else SSL_CTX_set_options(ctx,off); /* DTLS: partial reads end up discarding unread UDP bytes :-( * Setting read ahead solves this problem. */ if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1); if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback); if (cipher != NULL) if(!SSL_CTX_set_cipher_list(ctx,cipher)) { BIO_printf(bio_err,"error setting cipher list\n"); ERR_print_errors(bio_err); goto end; } #if 0 else SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER")); #endif SSL_CTX_set_verify(ctx,verify,verify_callback); if (!set_cert_key_stuff(ctx,cert,key)) goto end; if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || (!SSL_CTX_set_default_verify_paths(ctx))) { /* BIO_printf(bio_err,"error setting default verify locations\n"); */ ERR_print_errors(bio_err); /* goto end; */ } store = SSL_CTX_get_cert_store(ctx); X509_STORE_set_flags(store, vflags); con=SSL_new(ctx); #ifndef OPENSSL_NO_KRB5 if (con && (con->kssl_ctx = kssl_ctx_new()) != NULL) { kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host); } #endif /* OPENSSL_NO_KRB5 */ /* SSL_set_cipher_list(con,"RC4-MD5"); */ re_start: if (init_client(&s,host,port,sock_type) == 0) { BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); SHUTDOWN(s); goto end; } BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s); #ifdef FIONBIO if (c_nbio) { unsigned long l=1; BIO_printf(bio_c_out,"turning on non blocking io\n"); if (BIO_socket_ioctl(s,FIONBIO,&l) < 0) { ERR_print_errors(bio_err); goto end; } } #endif if (c_Pause & 0x01) con->debug=1; if ( SSL_version(con) == DTLS1_VERSION) { struct timeval timeout; sbio=BIO_new_dgram(s,BIO_NOCLOSE); if (getsockname(s, &peer, (void *)&peerlen) < 0) { BIO_printf(bio_err, "getsockname:errno=%d\n", get_last_socket_error()); SHUTDOWN(s); goto end; } (void)BIO_ctrl_set_connected(sbio, 1, &peer); if ( enable_timeouts) { timeout.tv_sec = 0; timeout.tv_usec = DGRAM_RCV_TIMEOUT; BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); timeout.tv_sec = 0; timeout.tv_usec = DGRAM_SND_TIMEOUT; BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); } if ( mtu > 0) { SSL_set_options(con, SSL_OP_NO_QUERY_MTU); SSL_set_mtu(con, mtu); } else /* want to do MTU discovery */ BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); } else sbio=BIO_new_socket(s,BIO_NOCLOSE); if (nbio_test) { BIO *test; test=BIO_new(BIO_f_nbio_test()); sbio=BIO_push(test,sbio); } if (c_debug) { con->debug=1; BIO_set_callback(sbio,bio_dump_callback); BIO_set_callback_arg(sbio,(char *)bio_c_out); } if (c_msg) { SSL_set_msg_callback(con, msg_cb); SSL_set_msg_callback_arg(con, bio_c_out); } SSL_set_bio(con,sbio,sbio); SSL_set_connect_state(con); /* ok, lets connect */ width=SSL_get_fd(con)+1; read_tty=1; write_tty=0; tty_on=0; read_ssl=1; write_ssl=1; cbuf_len=0; cbuf_off=0; sbuf_len=0; sbuf_off=0; /* This is an ugly hack that does a lot of assumptions */ /* We do have to handle multi-line responses which may come in a single packet or not. We therefore have to use BIO_gets() which does need a buffering BIO. So during the initial chitchat we do push a buffering BIO into the chain that is removed again later on to not disturb the rest of the s_client operation. */ if (starttls_proto == PROTO_SMTP) { int foundit=0; BIO *fbio = BIO_new(BIO_f_buffer()); BIO_push(fbio, sbio); /* wait for multi-line response to end from SMTP */ do { mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ); } while (mbuf_len>3 && mbuf[3]=='-'); /* STARTTLS command requires EHLO... */ BIO_printf(fbio,"EHLO openssl.client.net\r\n"); (void)BIO_flush(fbio); /* wait for multi-line response to end EHLO SMTP response */ do { mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ); if (strstr(mbuf,"STARTTLS")) foundit=1; } while (mbuf_len>3 && mbuf[3]=='-'); (void)BIO_flush(fbio); BIO_pop(fbio); BIO_free(fbio); if (!foundit) BIO_printf(bio_err, "didn't found starttls in server response," " try anyway...\n"); BIO_printf(sbio,"STARTTLS\r\n"); BIO_read(sbio,sbuf,BUFSIZZ); } else if (starttls_proto == PROTO_POP3) { BIO_read(sbio,mbuf,BUFSIZZ); BIO_printf(sbio,"STLS\r\n"); BIO_read(sbio,sbuf,BUFSIZZ); } else if (starttls_proto == PROTO_IMAP) { int foundit=0; BIO *fbio = BIO_new(BIO_f_buffer()); BIO_push(fbio, sbio); BIO_gets(fbio,mbuf,BUFSIZZ); /* STARTTLS command requires CAPABILITY... */ BIO_printf(fbio,". CAPABILITY\r\n"); (void)BIO_flush(fbio); /* wait for multi-line CAPABILITY response */ do { mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ); if (strstr(mbuf,"STARTTLS")) foundit=1; } while (mbuf_len>3 && mbuf[0]!='.'); (void)BIO_flush(fbio); BIO_pop(fbio); BIO_free(fbio); if (!foundit) BIO_printf(bio_err, "didn't found STARTTLS in server response," " try anyway...\n"); BIO_printf(sbio,". STARTTLS\r\n"); BIO_read(sbio,sbuf,BUFSIZZ); } else if (starttls_proto == PROTO_FTP) { BIO *fbio = BIO_new(BIO_f_buffer()); BIO_push(fbio, sbio); /* wait for multi-line response to end from FTP */ do { mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ); } while (mbuf_len>3 && mbuf[3]=='-'); (void)BIO_flush(fbio); BIO_pop(fbio); BIO_free(fbio); BIO_printf(sbio,"AUTH TLS\r\n"); BIO_read(sbio,sbuf,BUFSIZZ); } for (;;) { FD_ZERO(&readfds); FD_ZERO(&writefds); if (SSL_in_init(con) && !SSL_total_renegotiations(con)) { in_init=1; tty_on=0; } else { tty_on=1; if (in_init) { in_init=0; print_stuff(bio_c_out,con,full_log); if (full_log > 0) full_log--; if (starttls_proto) { BIO_printf(bio_err,"%s",mbuf); /* We don't need to know any more */ starttls_proto = PROTO_OFF; } if (reconnect) { reconnect--; BIO_printf(bio_c_out,"drop connection and then reconnect\n"); SSL_shutdown(con); SSL_set_connect_state(con); SHUTDOWN(SSL_get_fd(con)); goto re_start; } } } ssl_pending = read_ssl && SSL_pending(con); if (!ssl_pending) { #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) if (tty_on) { if (read_tty) FD_SET(fileno(stdin),&readfds); if (write_tty) FD_SET(fileno(stdout),&writefds); } if (read_ssl) FD_SET(SSL_get_fd(con),&readfds); if (write_ssl) FD_SET(SSL_get_fd(con),&writefds); #else if(!tty_on || !write_tty) { if (read_ssl) FD_SET(SSL_get_fd(con),&readfds); if (write_ssl) FD_SET(SSL_get_fd(con),&writefds); } #endif /* printf("mode tty(%d %d%d) ssl(%d%d)\n", tty_on,read_tty,write_tty,read_ssl,write_ssl);*/ /* Note: under VMS with SOCKETSHR the second parameter * is currently of type (int *) whereas under other * systems it is (void *) if you don't have a cast it * will choke the compiler: if you do have a cast then * you can either go for (int *) or (void *). */ #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) /* Under Windows/DOS we make the assumption that we can * always write to the tty: therefore if we need to * write to the tty we just fall through. Otherwise * we timeout the select every second and see if there * are any keypresses. Note: this is a hack, in a proper * Windows application we wouldn't do this. */ i=0; if(!write_tty) { if(read_tty) { tv.tv_sec = 1; tv.tv_usec = 0; i=select(width,(void *)&readfds,(void *)&writefds, NULL,&tv); #if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS) if(!i && (!_kbhit() || !read_tty) ) continue; #else if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue; #endif } else i=select(width,(void *)&readfds,(void *)&writefds, NULL,NULL); } #elif defined(OPENSSL_SYS_NETWARE) if(!write_tty) { if(read_tty) { tv.tv_sec = 1; tv.tv_usec = 0; i=select(width,(void *)&readfds,(void *)&writefds, NULL,&tv); } else i=select(width,(void *)&readfds,(void *)&writefds, NULL,NULL); } #else i=select(width,(void *)&readfds,(void *)&writefds, NULL,NULL); #endif if ( i < 0) { BIO_printf(bio_err,"bad select %d\n", get_last_socket_error()); goto shut; /* goto end; */ } } if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds)) { k=SSL_write(con,&(cbuf[cbuf_off]), (unsigned int)cbuf_len); switch (SSL_get_error(con,k)) { case SSL_ERROR_NONE: cbuf_off+=k; cbuf_len-=k; if (k <= 0) goto end; /* we have done a write(con,NULL,0); */ if (cbuf_len <= 0) { read_tty=1; write_ssl=0; } else /* if (cbuf_len > 0) */ { read_tty=0; write_ssl=1; } break; case SSL_ERROR_WANT_WRITE: BIO_printf(bio_c_out,"write W BLOCK\n"); write_ssl=1; read_tty=0; break; case SSL_ERROR_WANT_READ: BIO_printf(bio_c_out,"write R BLOCK\n"); write_tty=0; read_ssl=1; write_ssl=0; break; case SSL_ERROR_WANT_X509_LOOKUP: BIO_printf(bio_c_out,"write X BLOCK\n"); break; case SSL_ERROR_ZERO_RETURN: if (cbuf_len != 0) { BIO_printf(bio_c_out,"shutdown\n"); goto shut; } else { read_tty=1; write_ssl=0; break; } case SSL_ERROR_SYSCALL: if ((k != 0) || (cbuf_len != 0)) { BIO_printf(bio_err,"write:errno=%d\n", get_last_socket_error()); goto shut; } else { read_tty=1; write_ssl=0; } break; case SSL_ERROR_SSL: ERR_print_errors(bio_err); goto shut; } } #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) /* Assume Windows/DOS can always write */ else if (!ssl_pending && write_tty) #else else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds)) #endif { #ifdef CHARSET_EBCDIC ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len); #endif i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len); if (i <= 0) { BIO_printf(bio_c_out,"DONE\n"); goto shut; /* goto end; */ } sbuf_len-=i;; sbuf_off+=i; if (sbuf_len <= 0) { read_ssl=1; write_tty=0; } } else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds)) { #ifdef RENEG { static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } } #endif #if 1 k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ ); #else /* Demo for pending and peek :-) */ k=SSL_read(con,sbuf,16); { char zbuf[10240]; printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240)); } #endif switch (SSL_get_error(con,k)) { case SSL_ERROR_NONE: if (k <= 0) goto end; sbuf_off=0; sbuf_len=k; read_ssl=0; write_tty=1; break; case SSL_ERROR_WANT_WRITE: BIO_printf(bio_c_out,"read W BLOCK\n"); write_ssl=1; read_tty=0; break; case SSL_ERROR_WANT_READ: BIO_printf(bio_c_out,"read R BLOCK\n"); write_tty=0; read_ssl=1; if ((read_tty == 0) && (write_ssl == 0)) write_ssl=1; break; case SSL_ERROR_WANT_X509_LOOKUP: BIO_printf(bio_c_out,"read X BLOCK\n"); break; case SSL_ERROR_SYSCALL: BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error()); goto shut; case SSL_ERROR_ZERO_RETURN: BIO_printf(bio_c_out,"closed\n"); goto shut; case SSL_ERROR_SSL: ERR_print_errors(bio_err); goto shut; /* break; */ } } #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) #if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS) else if (_kbhit()) #else else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) #endif #elif defined (OPENSSL_SYS_NETWARE) else if (_kbhit()) #else else if (FD_ISSET(fileno(stdin),&readfds)) #endif { if (crlf) { int j, lf_num; i=read(fileno(stdin),cbuf,BUFSIZZ/2); lf_num = 0; /* both loops are skipped when i <= 0 */ for (j = 0; j < i; j++) if (cbuf[j] == '\n') lf_num++; for (j = i-1; j >= 0; j--) { cbuf[j+lf_num] = cbuf[j]; if (cbuf[j] == '\n') { lf_num--; i++; cbuf[j+lf_num] = '\r'; } } assert(lf_num == 0); } else i=read(fileno(stdin),cbuf,BUFSIZZ); if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) { BIO_printf(bio_err,"DONE\n"); goto shut; } if ((!c_ign_eof) && (cbuf[0] == 'R')) { BIO_printf(bio_err,"RENEGOTIATING\n"); SSL_renegotiate(con); cbuf_len=0; } else { cbuf_len=i; cbuf_off=0; #ifdef CHARSET_EBCDIC ebcdic2ascii(cbuf, cbuf, i); #endif } write_ssl=1; read_tty=0; } } shut: SSL_shutdown(con); SHUTDOWN(SSL_get_fd(con)); ret=0; end: if(prexit) print_stuff(bio_c_out,con,1); if (con != NULL) SSL_free(con); if (con2 != NULL) SSL_free(con2); if (ctx != NULL) SSL_CTX_free(ctx); if (cert) X509_free(cert); if (key) EVP_PKEY_free(key); if (pass) OPENSSL_free(pass); if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); } if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); } if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); } if (bio_c_out != NULL) { BIO_free(bio_c_out); bio_c_out=NULL; } apps_shutdown(); OPENSSL_EXIT(ret); }
eventer_ssl_ctx_t * eventer_ssl_ctx_new(eventer_ssl_orientation_t type, const char *layer, const char *certificate, const char *key, const char *ca, const char *ciphers) { char ssl_ctx_key[SSL_CTX_KEYLEN]; eventer_ssl_ctx_t *ctx; const char *layer_str; char *ctx_layer, *opts; char *opts_fallback = DEFAULT_OPTS_STRING; time_t now; ctx = calloc(1, sizeof(*ctx)); if(!ctx) return NULL; layer_str = layer ? layer : DEFAULT_LAYER_STRING; ctx_layer = alloca(strlen(layer_str)+1); memcpy(ctx_layer, layer_str, strlen(layer_str)+1); opts = strchr(ctx_layer,':'); if(opts) *opts++ = '\0'; else { opts = alloca(strlen(opts_fallback)+1); memcpy(opts, opts_fallback, strlen(opts_fallback)+1); } now = time(NULL); ssl_ctx_key_write(ssl_ctx_key, sizeof(ssl_ctx_key), type, layer, certificate, key, ca, ciphers); ctx->ssl_ctx_cn = ssl_ctx_cache_get(ssl_ctx_key); if(ctx->ssl_ctx_cn) { if(now - ctx->ssl_ctx_cn->creation_time > ssl_ctx_cache_expiry || (now - ctx->ssl_ctx_cn->last_stat_time > ssl_ctx_cache_finfo_expiry && (validate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate) || validate_finfo(&ctx->ssl_ctx_cn->key_finfo, key) || validate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca) || (ctx->ssl_ctx_cn->last_stat_time = now) == 0))) { /* assignment */ ssl_ctx_cache_remove(ssl_ctx_key); ssl_ctx_cache_node_free(ctx->ssl_ctx_cn); ctx->ssl_ctx_cn = NULL; } } if(!ctx->ssl_ctx_cn) { char *part = NULL, *brkt = NULL; long ctx_options = 0; ssl_ctx_cache_node *existing_ctx_cn; ctx->ssl_ctx_cn = calloc(1, sizeof(*ctx->ssl_ctx_cn)); ctx->ssl_ctx_cn->key = strdup(ssl_ctx_key); ctx->ssl_ctx_cn->refcnt = 1; ctx->ssl_ctx_cn->creation_time = now; ctx->ssl_ctx_cn->last_stat_time = now; populate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate); populate_finfo(&ctx->ssl_ctx_cn->key_finfo, key); populate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca); ctx->ssl_ctx = NULL; if(0) ; #if defined(SSL_TXT_SSLV3) && defined(HAVE_SSLV3_SERVER) && defined(HAVE_SSLV3_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_SSLV3)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? SSLv3_server_method() : SSLv3_client_method()); #endif #if defined(SSL_TXT_SSLV2) && defined(HAVE_SSLV2_SERVER) && defined(HAVE_SSLV2_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_SSLV2)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? SSLv2_server_method() : SSLv2_client_method()); #endif #if defined(SSL_TXT_TLSV1) && defined(HAVE_TLSV1_SERVER) && defined(HAVE_TLSV1_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? TLSv1_server_method() : TLSv1_client_method()); #endif #if defined(SSL_TXT_TLSV1_1) && defined(HAVE_TLSV1_1_SERVER) && defined(HAVE_TLSV1_1_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_1)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? TLSv1_1_server_method() : TLSv1_1_client_method()); #endif #if defined(SSL_TXT_TLSV1_2) && defined(HAVE_TLSV1_2_SERVER) && defined(HAVE_TLSV1_2_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_2)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? TLSv1_2_server_method() : TLSv1_2_client_method()); #endif if(ctx->ssl_ctx == NULL) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? SSLv23_server_method() : SSLv23_client_method()); if(!ctx->ssl_ctx) goto bail; for(part = strtok_r(opts, ",", &brkt); part; part = strtok_r(NULL, ",", &brkt)) { char *optname = part; int neg = 0; if(*optname == '!') neg = 1, optname++; #define SETBITOPT(name, neg, opt) \ if(!strcasecmp(optname, name)) { \ if(neg) ctx_options &= ~(opt); \ else ctx_options |= (opt); \ } SETBITOPT("all", neg, SSL_OP_ALL) #ifdef SSL_TXT_SSLV2 else SETBITOPT(SSL_TXT_SSLV2, !neg, SSL_OP_NO_SSLv2) #endif #ifdef SSL_TXT_SSLV3 else SETBITOPT(SSL_TXT_SSLV3, !neg, SSL_OP_NO_SSLv3) #endif #ifdef SSL_TXT_TLSV1 else SETBITOPT(SSL_TXT_TLSV1, !neg, SSL_OP_NO_TLSv1) #endif #ifdef SSL_TXT_TLSV1_1 else SETBITOPT(SSL_TXT_TLSV1_1, !neg, SSL_OP_NO_TLSv1_1) #endif #ifdef SSL_TXT_TLSV1_2 else SETBITOPT(SSL_TXT_TLSV1_2, !neg, SSL_OP_NO_TLSv1_2) #endif #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE else SETBITOPT("cipher_server_preference", neg, SSL_OP_CIPHER_SERVER_PREFERENCE) #endif else { mtevL(mtev_error, "SSL layer part '%s' not understood.\n", optname); } } if (type == SSL_SERVER) SSL_CTX_set_session_id_context(ctx->ssl_ctx, (unsigned char *)EVENTER_SSL_DATANAME, sizeof(EVENTER_SSL_DATANAME)-1); #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; #endif #ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; #endif #ifdef SSL_OP_NO_COMPRESSION ctx_options |= SSL_OP_NO_COMPRESSION; #endif #ifdef SSL_OP_NO_TICKET ctx_options |= SSL_OP_NO_TICKET; #endif #ifdef SSL_OP_SINGLE_DH_USE ctx_options |= SSL_OP_SINGLE_DH_USE; #endif #ifdef SSL_OP_SINGLE_ECDH_USE ctx_options |= SSL_OP_SINGLE_ECDH_USE; #endif SSL_CTX_set_options(ctx->ssl_ctx, ctx_options); #ifdef SSL_MODE_RELEASE_BUFFERS SSL_CTX_set_mode(ctx->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); #endif if(certificate && SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, certificate) != 1) goto bail; if(key && SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx,key, SSL_FILETYPE_PEM) != 1) goto bail; if(ca) { STACK_OF(X509_NAME) *cert_stack; if(!SSL_CTX_load_verify_locations(ctx->ssl_ctx,ca,NULL) || (cert_stack = SSL_load_client_CA_file(ca)) == NULL) goto bail; SSL_CTX_set_client_CA_list(ctx->ssl_ctx, cert_stack); } SSL_CTX_set_cipher_list(ctx->ssl_ctx, ciphers ? ciphers : "DEFAULT"); SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, verify_cb); #ifndef OPENSSL_NO_EC #if defined(SSL_CTX_set_ecdh_auto) SSL_CTX_set_ecdh_auto(ctx->ssl_ctx, 1); #elif defined(NID_X9_62_prime256v1) EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); SSL_CTX_set_tmp_ecdh(ctx->ssl_ctx, ec_key); EC_KEY_free(ec_key); #endif #endif existing_ctx_cn = ssl_ctx_cache_set(ctx->ssl_ctx_cn); if(existing_ctx_cn != ctx->ssl_ctx_cn) { ssl_ctx_cache_node_free(ctx->ssl_ctx_cn); ctx->ssl_ctx_cn = existing_ctx_cn; } }