static int server_setup_sni(void) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; int testresult = 0; if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), TLS1_VERSION, 0, &sctx, &cctx, cert, privkey)) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL))) goto end; /* set SNI at server side */ SSL_set_tlsext_host_name(serverssl, host); if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) goto end; if (!TEST_ptr_null(SSL_get_servername(serverssl, TLSEXT_NAMETYPE_host_name))) { /* SNI should have been cleared during handshake */ goto end; } testresult = 1; end: SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); SSL_CTX_free(cctx); return testresult; }
SSL_CTX *hst_tls_init() { _HSTU("open"); SSL_load_error_strings(); SSL_library_init(); const SSL_METHOD *method = TLS_client_method(); return SSL_CTX_new(method); }
static CIPHERLIST_TEST_FIXTURE set_up(const char *const test_case_name) { CIPHERLIST_TEST_FIXTURE fixture; fixture.test_case_name = test_case_name; fixture.server = SSL_CTX_new(TLS_server_method()); fixture.client = SSL_CTX_new(TLS_client_method()); OPENSSL_assert(fixture.client != NULL && fixture.server != NULL); return fixture; }
static int execute_test(SSL_TEST_FIXTURE fixture) { int ret = 0; SSL_CTX *server_ctx = NULL, *server2_ctx = NULL, *client_ctx = NULL; SSL_TEST_CTX *test_ctx = NULL; HANDSHAKE_RESULT result; test_ctx = SSL_TEST_CTX_create(conf, fixture.test_app); if (test_ctx == NULL) goto err; #ifndef OPENSSL_NO_DTLS if (test_ctx->method == SSL_TEST_METHOD_DTLS) { server_ctx = SSL_CTX_new(DTLS_server_method()); if (test_ctx->servername_callback != SSL_TEST_SERVERNAME_CB_NONE) { server2_ctx = SSL_CTX_new(DTLS_server_method()); OPENSSL_assert(server2_ctx != NULL); } client_ctx = SSL_CTX_new(DTLS_client_method()); } #endif if (test_ctx->method == SSL_TEST_METHOD_TLS) { server_ctx = SSL_CTX_new(TLS_server_method()); if (test_ctx->servername_callback != SSL_TEST_SERVERNAME_CB_NONE) { server2_ctx = SSL_CTX_new(TLS_server_method()); OPENSSL_assert(server2_ctx != NULL); } client_ctx = SSL_CTX_new(TLS_client_method()); } OPENSSL_assert(server_ctx != NULL && client_ctx != NULL); OPENSSL_assert(CONF_modules_load(conf, fixture.test_app, 0) > 0); if (!SSL_CTX_config(server_ctx, "server") || !SSL_CTX_config(client_ctx, "client")) { goto err; } if (server2_ctx != NULL && !SSL_CTX_config(server2_ctx, "server2")) goto err; result = do_handshake(server_ctx, server2_ctx, client_ctx, test_ctx); ret = check_test(result, test_ctx); err: CONF_modules_unload(0); SSL_CTX_free(server_ctx); SSL_CTX_free(server2_ctx); SSL_CTX_free(client_ctx); SSL_TEST_CTX_free(test_ctx); if (ret != 1) ERR_print_errors_fp(stderr); return ret; }
int lws_tls_client_create_vhost_context(struct lws_vhost *vh, const struct lws_context_creation_info *info, const char *cipher_list, const char *ca_filepath, const char *cert_filepath, const char *private_key_filepath) { X509 *d2i_X509(X509 **cert, const unsigned char *buffer, long len); SSL_METHOD *method = (SSL_METHOD *)TLS_client_method(); unsigned long error; lws_filepos_t len; uint8_t *buf; if (!method) { error = ERR_get_error(); lwsl_err("problem creating ssl method %lu: %s\n", error, ERR_error_string(error, (char *)vh->context->pt[0].serv_buf)); return 1; } /* create context */ vh->tls.ssl_client_ctx = SSL_CTX_new(method); if (!vh->tls.ssl_client_ctx) { error = ERR_get_error(); lwsl_err("problem creating ssl context %lu: %s\n", error, ERR_error_string(error, (char *)vh->context->pt[0].serv_buf)); return 1; } if (!ca_filepath) return 0; if (alloc_file(vh->context, ca_filepath, &buf, &len)) { lwsl_err("Load CA cert file %s failed\n", ca_filepath); return 1; } vh->tls.x509_client_CA = d2i_X509(NULL, buf, len); free(buf); if (!vh->tls.x509_client_CA) { lwsl_err("client CA: x509 parse failed\n"); return 1; } if (!vh->tls.ssl_ctx) SSL_CTX_add_client_CA(vh->tls.ssl_client_ctx, vh->tls.x509_client_CA); else SSL_CTX_add_client_CA(vh->tls.ssl_ctx, vh->tls.x509_client_CA); lwsl_notice("client loaded CA for verification %s\n", ca_filepath); return 0; }
/* Initializes SSL and allocate global context SSL_context SYNOPSIS my_ssl_start mysql connection handle RETURN VALUES 0 success 1 error */ int ma_tls_start(char *errmsg, size_t errmsg_len) { int rc= 1; if (ma_tls_initialized) return 0; /* lock mutex to prevent multiple initialization */ pthread_mutex_init(&LOCK_openssl_config,MY_MUTEX_INIT_FAST); pthread_mutex_lock(&LOCK_openssl_config); #if OPENSSL_VERSION_NUMBER >= 0x10100000L OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); #else if (ssl_thread_init()) { strncpy(errmsg, "Not enough memory", errmsg_len); goto end; } 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(SSLv23_client_method()))) #endif { ma_tls_get_error(errmsg, errmsg_len); goto end; } #ifdef HAVE_TLS_SESSION_CACHE SSL_CTX_set_session_cache_mode(SSL_context, SSL_SESS_CACHE_CLIENT); ma_tls_sessions= (MA_SSL_SESSION *)calloc(1, sizeof(struct st_ma_tls_session) * ma_tls_session_cache_size); SSL_CTX_sess_set_new_cb(SSL_context, ma_tls_session_cb); SSL_CTX_sess_set_remove_cb(SSL_context, ma_tls_remove_session_cb); #endif disable_sigpipe(); #if OPENSSL_USE_BIOMETHOD memcpy(&ma_BIO_method, BIO_s_socket(), sizeof(BIO_METHOD)); ma_BIO_method.bread= ma_bio_read; ma_BIO_method.bwrite= ma_bio_write; #endif rc= 0; ma_tls_initialized= TRUE; end: pthread_mutex_unlock(&LOCK_openssl_config); return rc; }
//-------------------------------------------------------------------------------------------------- le_result_t secSocket_Init ( secSocket_Ctx_t** ctxPtr ///< [INOUT] Secure socket context pointer ) { // Check input parameter if (!ctxPtr) { LE_ERROR("Null pointer provided"); return LE_BAD_PARAMETER; } // Initialize the socket context pool if (!SocketCtxPoolRef) { SocketCtxPoolRef = le_mem_InitStaticPool(SocketCtxPool, MAX_SOCKET_NB, sizeof(OpensslCtx_t)); } // Check if the socket is already initialized OpensslCtx_t* contextPtr = GetContext(*ctxPtr); if ((contextPtr) && (contextPtr->isInit)) { LE_ERROR("Socket context already initialized"); return LE_FAULT; } // Alloc memory from pool contextPtr = le_mem_TryAlloc(SocketCtxPoolRef); if (NULL == contextPtr) { LE_ERROR("Unable to allocate a socket context from pool"); return LE_FAULT; } // Set the magic number contextPtr->magicNb = OPENSSL_MAGIC_NUMBER; // Initialize OpenSSL library and setup SSL pointers #if OPENSSL_VERSION_NUMBER < 0x10100000L SSL_library_init(); contextPtr->sslCtxPtr = SSL_CTX_new(TLSv1_client_method()); #else OPENSSL_init_ssl(0, NULL); contextPtr->sslCtxPtr = SSL_CTX_new(TLS_client_method()); #endif contextPtr->isInit = true; *ctxPtr = (secSocket_Ctx_t*)contextPtr; return LE_OK; }
static CIPHERLIST_TEST_FIXTURE *set_up(const char *const test_case_name) { CIPHERLIST_TEST_FIXTURE *fixture; if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture)))) return NULL; fixture->test_case_name = test_case_name; if (!TEST_ptr(fixture->server = SSL_CTX_new(TLS_server_method())) || !TEST_ptr(fixture->client = SSL_CTX_new(TLS_client_method()))) { tear_down(fixture); return NULL; } return fixture; }
/*@C PetscSSLInitializeContext - Set up an SSL context suitable for initiating HTTPS requests. Output Parameter: . octx - the SSL_CTX to be passed to PetscHTTPSConnect Level: advanced If PETSc was ./configure -with-ssl-certificate requires the user have created a self-signed certificate with $ saws/CA.pl -newcert (using the passphrase of password) $ cat newkey.pem newcert.pem > sslclient.pem and put the resulting file in either the current directory (with the application) or in the home directory. This seems kind of silly but it was all I could figure out. .seealso: PetscSSLDestroyContext(), PetscHTTPSConnect(), PetscHTTPSRequest() @*/ PetscErrorCode PetscSSLInitializeContext(SSL_CTX **octx) { SSL_CTX *ctx; #if defined(PETSC_USE_SSL_CERTIFICATE) char keyfile[PETSC_MAX_PATH_LEN]; PetscBool exists; PetscErrorCode ierr; #endif PetscFunctionBegin; if (!bio_err){ SSL_library_init(); SSL_load_error_strings(); bio_err = BIO_new_fp(stderr,BIO_NOCLOSE); } /* Set up a SIGPIPE handler */ signal(SIGPIPE,sigpipe_handle); /* suggested at https://mta.openssl.org/pipermail/openssl-dev/2015-May/001449.html */ #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) ctx = SSL_CTX_new(TLS_client_method()); #else ctx = SSL_CTX_new(SSLv23_client_method()); #endif SSL_CTX_set_mode(ctx,SSL_MODE_AUTO_RETRY); #if defined(PETSC_USE_SSL_CERTIFICATE) /* Locate keyfile */ ierr = PetscStrcpy(keyfile,"sslclient.pem");CHKERRQ(ierr); ierr = PetscTestFile(keyfile,'r',&exists);CHKERRQ(ierr); if (!exists) { ierr = PetscGetHomeDirectory(keyfile,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); ierr = PetscStrcat(keyfile,"/");CHKERRQ(ierr); ierr = PetscStrcat(keyfile,"sslclient.pem");CHKERRQ(ierr); ierr = PetscTestFile(keyfile,'r',&exists);CHKERRQ(ierr); if (!exists) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate sslclient.pem file in current directory or home directory"); } /* Load our keys and certificates*/ if (!(SSL_CTX_use_certificate_chain_file(ctx,keyfile))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot read certificate file"); SSL_CTX_set_default_passwd_cb(ctx,password_cb); if (!(SSL_CTX_use_PrivateKey_file(ctx,keyfile,SSL_FILETYPE_PEM))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot read key file"); #endif *octx = ctx; PetscFunctionReturn(0); }
static const SSL_METHOD *tls1_get_client_method(int ver) { if (ver == TLS_ANY_VERSION) return TLS_client_method(); if (ver == TLS1_2_VERSION) return TLSv1_2_client_method(); if (ver == TLS1_1_VERSION) return TLSv1_1_client_method(); if (ver == TLS1_VERSION) return TLSv1_client_method(); #ifndef OPENSSL_NO_SSL3 if (ver == SSL3_VERSION) return (SSLv3_client_method()); #endif return NULL; }
static struct mailstream_ssl_data * ssl_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, #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) TLS_client_method(), #else /* Despite their name the SSLv23_*method() functions have nothing to do * with the availability of SSLv2 or SSLv3. What these functions do is * negotiate with the peer the highest available SSL/TLS protocol version * available. The name is as it is for historic reasons. This is a very * common confusion and is the main reason why these names have been * deprecated in the latest dev version of OpenSSL. */ SSLv23_client_method(), #endif callback, cb_data); }
noPollPtr ssl_context_creator (noPollCtx * ctx, noPollConn * conn, noPollConnOpts * opts, nopoll_bool is_client, noPollPtr user_data) { SSL_CTX * ssl_ctx; noPollConn * listener; /* very basic context creation using default settings provided * by OpenSSL */ if (is_client) { #if OPENSSL_VERSION_NUMBER < 0x10100000L return SSL_CTX_new (TLSv1_client_method ()); #else return SSL_CTX_new (TLS_client_method ()); #endif } /* end if */ /* get the ssl context */ #if OPENSSL_VERSION_NUMBER < 0x10100000L ssl_ctx = SSL_CTX_new (TLSv1_server_method ()); #else ssl_ctx = SSL_CTX_new (TLS_server_method ()); #endif /* get a reference to the listener */ listener = nopoll_conn_get_listener (conn); if (nopoll_cmp ("1239", nopoll_conn_port (listener))) { printf ("ACCEPTED ssl connection on port: %s (for conn %p)\n", nopoll_conn_port (listener), conn); /* ok, especiall case where we require a certain * certificate from renote side */ if (SSL_CTX_load_verify_locations (ssl_ctx, "client-side-cert-auth-cacert.crt", NULL) != 1) { printf ("ERROR: unable to add ca certificate...\n"); } /* make server to ask for a certificate to the client * .... and verify it */ SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); } /* end if */ printf ("RETURNING: ssl context reference %p\n", ssl_ctx); return ssl_ctx; }
/* 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); }
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; }
/* * Custom call back tests. * Test 0: callbacks in TLSv1.2 * Test 1: callbacks in TLSv1.2 with SNI */ static int test_custom_exts(int tst) { SSL_CTX *cctx = NULL, *sctx = NULL, *sctx2 = NULL; SSL *clientssl = NULL, *serverssl = NULL; int testresult = 0; static int server = 1; static int client = 0; SSL_SESSION *sess = NULL; /* Reset callback counters */ clntaddcb = clntparsecb = srvaddcb = srvparsecb = 0; snicb = 0; if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx, &cctx, cert, privkey)) { printf("Unable to create SSL_CTX pair\n"); goto end; } if (tst == 1 && !create_ssl_ctx_pair(TLS_server_method(), NULL, &sctx2, NULL, cert, privkey)) { printf("Unable to create SSL_CTX pair (2)\n"); goto end; } /* Create a client side custom extension */ if (!SSL_CTX_add_client_custom_ext(cctx, TEST_EXT_TYPE1, add_cb, free_cb, &client, parse_cb, &client)) { printf("Unable to add client custom extension\n"); goto end; } /* Should not be able to add duplicates */ if (SSL_CTX_add_client_custom_ext(cctx, TEST_EXT_TYPE1, add_cb, free_cb, &client, parse_cb, &client)) { printf("Unexpected success adding duplicate extension\n"); goto end; } /* Create a server side custom extension */ if (!SSL_CTX_add_server_custom_ext(sctx, TEST_EXT_TYPE1, add_cb, free_cb, &server, parse_cb, &server)) { printf("Unable to add server custom extension\n"); goto end; } if (sctx2 != NULL && !SSL_CTX_add_server_custom_ext(sctx2, TEST_EXT_TYPE1, add_cb, free_cb, &server, parse_cb, &server)) { printf("Unable to add server custom extension for SNI\n"); goto end; } /* Should not be able to add duplicates */ if (SSL_CTX_add_server_custom_ext(sctx, TEST_EXT_TYPE1, add_cb, free_cb, &server, parse_cb, &server)) { printf("Unexpected success adding duplicate extension (2)\n"); goto end; } if (tst == 1) { /* Set up SNI */ if (!SSL_CTX_set_tlsext_servername_callback(sctx, sni_cb) || !SSL_CTX_set_tlsext_servername_arg(sctx, sctx2)) { printf("Cannot set SNI callbacks\n"); goto end; } } if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL) || !create_ssl_connection(serverssl, clientssl)) { printf("Cannot create SSL connection\n"); goto end; } if (clntaddcb != 1 || clntparsecb != 1 || srvaddcb != 1 || srvparsecb != 1 || (tst != 1 && snicb != 0) || (tst == 1 && snicb != 1)) { printf("Incorrect callback counts\n"); goto end; } sess = SSL_get1_session(clientssl); SSL_shutdown(clientssl); SSL_shutdown(serverssl); SSL_free(serverssl); SSL_free(clientssl); serverssl = clientssl = NULL; if (tst == 1) { /* We don't bother with the resumption aspects for this test */ testresult = 1; goto end; } if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL) || !SSL_set_session(clientssl, sess) || !create_ssl_connection(serverssl, clientssl)) { printf("Cannot create resumption connection\n"); goto end; } /* * For a resumed session we expect to add the ClientHello extension but we * should ignore it on the server side. */ if (clntaddcb != 2 || clntparsecb != 1 || srvaddcb != 1 || srvparsecb != 1) { printf("Incorrect resumption callback counts\n"); goto end; } testresult = 1; end: SSL_SESSION_free(sess); SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx2); SSL_CTX_free(sctx); SSL_CTX_free(cctx); return testresult; }
net_socketSSL_t* net_socketSSL_connect(const char* addr, const char* port, int type) { assert(addr); assert(port); int socktype; if((type >= NET_SOCKETSSL_TCP) && (type <= NET_SOCKETSSL_TCP_BUFFERED)) { socktype = SOCK_STREAM; } else { LOGE("invalid type=%i", type); return NULL; } net_socketSSL_t* self; self = (net_socketSSL_t*) malloc(sizeof(net_socketSSL_t)); if(self == NULL) { LOGE("malloc failed"); return NULL; } // SIGPIPE causes the process to exit for broken streams // but we want to receive EPIPE instead signal(SIGPIPE, SIG_IGN); if(type == NET_SOCKETSSL_TCP_BUFFERED) { self->buffer = (unsigned char*) malloc(NET_SOCKETSSL_BUFSIZE* sizeof(unsigned char)); if(self->buffer == NULL) { LOGE("malloc failed"); goto fail_buffer; } } else { self->buffer = NULL; } self->len = 0; // for HTTP snprintf(self->host, 256, "%s:%s", addr, port); // init SSL ctx #if NET_SOCKET_USE_OPENSSL_1_1 self->ctx = SSL_CTX_new(TLS_client_method()); #else // app should call SSL_library_init(); prior to creating any // OpenSSL sockets with the old API self->ctx = SSL_CTX_new(SSLv23_client_method()); #endif if(self->ctx == NULL) { LOGE("SSL_CTX_new failed"); goto fail_ctx; } self->method = NET_SOCKETSSL_METHOD_CLIENT; if(SSL_CTX_load_verify_locations(self->ctx, "ca_cert.pem", NULL) != 1) { LOGE("SSL_CTX_load_verify_locations failed"); goto fail_load_verify; } #if NET_SOCKET_USE_OPENSSL_1_1 if(SSL_CTX_set_default_verify_file(self->ctx) != 1) { LOGE("SSL_CTX_set_default_verify_file failed"); goto fail_set_default_verify_file; } #endif if(SSL_CTX_use_certificate_file(self->ctx, "client_cert.pem", SSL_FILETYPE_PEM) != 1) { LOGE("SSL_CTX_use_certificate_file failed"); goto fail_use_cert; } if(SSL_CTX_use_PrivateKey_file(self->ctx, "client_key.pem", SSL_FILETYPE_PEM) != 1) { LOGE("SSL_CTX_use_PrivateKey_file failed"); goto fail_use_priv; } if(SSL_CTX_check_private_key(self->ctx) != 1) { LOGE("SSL_CTX_check_private_key failed"); goto fail_check_priv; } SSL_CTX_set_mode(self->ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_verify(self->ctx, SSL_VERIFY_PEER, NULL); SSL_CTX_set_verify_depth(self->ctx, 1); struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = socktype; struct addrinfo* info; if(getaddrinfo(addr, port, &hints, &info) != 0) { LOGD("getaddrinfo addr=%s, port=%s, failed", addr, port); goto fail_getaddrinfo; } struct addrinfo* i = info; self->sockfd = -1; while(i) { self->sockfd = socket(i->ai_family, i->ai_socktype, i->ai_protocol); if(self->sockfd == -1) { LOGD("socket failed"); i = i->ai_next; continue; } if((type == NET_SOCKETSSL_TCP_NODELAY) || (type == NET_SOCKETSSL_TCP_BUFFERED)) { int yes = 1; if(setsockopt(self->sockfd, IPPROTO_TCP, TCP_NODELAY, (const void*) &yes, sizeof(int)) == -1) { LOGD("setsockopt TCP_NODELAY failed"); } } if(net_socketSSL_connectTimeout(self, i) == 0) { close(self->sockfd); self->sockfd = -1; i = i->ai_next; continue; } break; } freeaddrinfo(info); if(self->sockfd == -1) { LOGD("socket failed"); goto fail_socket; } self->error = 0; self->connected = 1; self->type = type; // success return self; // failure fail_socket: fail_getaddrinfo: fail_check_priv: fail_use_priv: fail_use_cert: #if NET_SOCKET_USE_OPENSSL_1_1 fail_set_default_verify_file: #endif fail_load_verify: SSL_CTX_free(self->ctx); fail_ctx: free(self->buffer); fail_buffer: free(self); return 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; }
static int test_tlsext_status_type(void) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; int testresult = 0; STACK_OF(OCSP_RESPID) *ids = NULL; OCSP_RESPID *id = NULL; BIO *certbio = NULL; if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx, &cctx, cert, privkey)) { printf("Unable to create SSL_CTX pair\n"); return 0; } if (SSL_CTX_get_tlsext_status_type(cctx) != -1) { printf("Unexpected initial value for " "SSL_CTX_get_tlsext_status_type()\n"); goto end; } /* First just do various checks getting and setting tlsext_status_type */ clientssl = SSL_new(cctx); if (SSL_get_tlsext_status_type(clientssl) != -1) { printf("Unexpected initial value for SSL_get_tlsext_status_type()\n"); goto end; } if (!SSL_set_tlsext_status_type(clientssl, TLSEXT_STATUSTYPE_ocsp)) { printf("Unexpected fail for SSL_set_tlsext_status_type()\n"); goto end; } if (SSL_get_tlsext_status_type(clientssl) != TLSEXT_STATUSTYPE_ocsp) { printf("Unexpected result for SSL_get_tlsext_status_type()\n"); goto end; } SSL_free(clientssl); clientssl = NULL; if (!SSL_CTX_set_tlsext_status_type(cctx, TLSEXT_STATUSTYPE_ocsp)) { printf("Unexpected fail for SSL_CTX_set_tlsext_status_type()\n"); goto end; } if (SSL_CTX_get_tlsext_status_type(cctx) != TLSEXT_STATUSTYPE_ocsp) { printf("Unexpected result for SSL_CTX_get_tlsext_status_type()\n"); goto end; } clientssl = SSL_new(cctx); if (SSL_get_tlsext_status_type(clientssl) != TLSEXT_STATUSTYPE_ocsp) { printf("Unexpected result for SSL_get_tlsext_status_type() (test 2)\n"); goto end; } SSL_free(clientssl); clientssl = NULL; /* * Now actually do a handshake and check OCSP information is exchanged and * the callbacks get called */ SSL_CTX_set_tlsext_status_cb(cctx, ocsp_client_cb); SSL_CTX_set_tlsext_status_arg(cctx, &cdummyarg); SSL_CTX_set_tlsext_status_cb(sctx, ocsp_server_cb); SSL_CTX_set_tlsext_status_arg(sctx, &cdummyarg); if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) { printf("Unable to create SSL objects\n"); goto end; } if (!create_ssl_connection(serverssl, clientssl)) { printf("Unable to create SSL connection\n"); goto end; } if (!ocsp_client_called || !ocsp_server_called) { printf("OCSP callbacks not called\n"); goto end; } SSL_free(serverssl); SSL_free(clientssl); serverssl = NULL; clientssl = NULL; /* Try again but this time force the server side callback to fail */ ocsp_client_called = 0; ocsp_server_called = 0; cdummyarg = 0; if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) { printf("Unable to create SSL objects\n"); goto end; } /* This should fail because the callback will fail */ if (create_ssl_connection(serverssl, clientssl)) { printf("Unexpected success creating the connection\n"); goto end; } if (ocsp_client_called || ocsp_server_called) { printf("OCSP callbacks successfully called unexpectedly\n"); goto end; } SSL_free(serverssl); SSL_free(clientssl); serverssl = NULL; clientssl = NULL; /* * This time we'll get the client to send an OCSP_RESPID that it will * accept. */ ocsp_client_called = 0; ocsp_server_called = 0; cdummyarg = 2; if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) { printf("Unable to create SSL objects\n"); goto end; } /* * We'll just use any old cert for this test - it doesn't have to be an OCSP * specific one. We'll use the server cert. */ certbio = BIO_new_file(cert, "r"); if (certbio == NULL) { printf("Can't load the certificate file\n"); goto end; } id = OCSP_RESPID_new(); ids = sk_OCSP_RESPID_new_null(); ocspcert = PEM_read_bio_X509(certbio, NULL, NULL, NULL); if (id == NULL || ids == NULL || ocspcert == NULL || !OCSP_RESPID_set_by_key(id, ocspcert) || !sk_OCSP_RESPID_push(ids, id)) { printf("Unable to set OCSP_RESPIDs\n"); goto end; } id = NULL; SSL_set_tlsext_status_ids(clientssl, ids); /* Control has been transferred */ ids = NULL; BIO_free(certbio); certbio = NULL; if (!create_ssl_connection(serverssl, clientssl)) { printf("Unable to create SSL connection\n"); goto end; } if (!ocsp_client_called || !ocsp_server_called) { printf("OCSP callbacks not called\n"); goto end; } testresult = 1; end: SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); SSL_CTX_free(cctx); sk_OCSP_RESPID_pop_free(ids, OCSP_RESPID_free); OCSP_RESPID_free(id); BIO_free(certbio); X509_free(ocspcert); ocspcert = NULL; return testresult; }
static int test_set_sigalgs(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; int testresult = 0; const sigalgs_list *curr; int testctx; /* Should never happen */ if ((size_t)idx >= OSSL_NELEM(testsigalgs) * 2) return 0; testctx = ((size_t)idx < OSSL_NELEM(testsigalgs)); curr = testctx ? &testsigalgs[idx] : &testsigalgs[idx - OSSL_NELEM(testsigalgs)]; if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx, &cctx, cert, privkey)) { printf("Unable to create SSL_CTX pair\n"); return 0; } if (testctx) { int ret; if (curr->list != NULL) ret = SSL_CTX_set1_sigalgs(cctx, curr->list, curr->listlen); else ret = SSL_CTX_set1_sigalgs_list(cctx, curr->liststr); if (!ret) { if (curr->valid) printf("Unexpected failure setting sigalgs in SSL_CTX (%d)\n", idx); else testresult = 1; goto end; } if (!curr->valid) { printf("Unexpected success setting sigalgs in SSL_CTX (%d)\n", idx); goto end; } } if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) { printf("Unable to create SSL objects\n"); goto end; } if (!testctx) { int ret; if (curr->list != NULL) ret = SSL_set1_sigalgs(clientssl, curr->list, curr->listlen); else ret = SSL_set1_sigalgs_list(clientssl, curr->liststr); if (!ret) { if (curr->valid) printf("Unexpected failure setting sigalgs in SSL (%d)\n", idx); else testresult = 1; goto end; } if (!curr->valid) { printf("Unexpected success setting sigalgs in SSL (%d)\n", idx); goto end; } } if (curr->connsuccess != create_ssl_connection(serverssl, clientssl)) { printf("Unexpected return value creating SSL connection (%d)\n", idx); goto end; } testresult = 1; end: SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); SSL_CTX_free(cctx); return testresult; }
int main(int argc, char **argv) { BIO *sbio = NULL, *out = NULL; int i, len, rv; char tmpbuf[1024]; SSL_CTX *ctx = NULL; SSL_CONF_CTX *cctx = NULL; SSL *ssl = NULL; CONF *conf = NULL; STACK_OF(CONF_VALUE) *sect = NULL; CONF_VALUE *cnf; const char *connect_str = "localhost:4433"; long errline = -1; ERR_load_crypto_strings(); ERR_load_SSL_strings(); SSL_library_init(); conf = NCONF_new(NULL); if (NCONF_load(conf, "connect.cnf", &errline) <= 0) { if (errline <= 0) fprintf(stderr, "Error processing config file\n"); else fprintf(stderr, "Error on line %ld\n", errline); goto end; } sect = NCONF_get_section(conf, "default"); if (sect == NULL) { fprintf(stderr, "Error retrieving default section\n"); goto end; } ctx = SSL_CTX_new(TLS_client_method()); cctx = SSL_CONF_CTX_new(); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { cnf = sk_CONF_VALUE_value(sect, i); rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value); if (rv > 0) continue; if (rv != -2) { fprintf(stderr, "Error processing %s = %s\n", cnf->name, cnf->value); ERR_print_errors_fp(stderr); goto end; } if (strcmp(cnf->name, "Connect") == 0) { connect_str = cnf->value; } else { fprintf(stderr, "Unknown configuration option %s\n", cnf->name); goto end; } } if (!SSL_CONF_CTX_finish(cctx)) { fprintf(stderr, "Finish error\n"); ERR_print_errors_fp(stderr); goto err; } /* * We'd normally set some stuff like the verify paths and * mode here * because as things stand this will connect to * any server whose * certificate is signed by any CA. */ sbio = BIO_new_ssl_connect(ctx); BIO_get_ssl(sbio, &ssl); if (!ssl) { fprintf(stderr, "Can't locate SSL pointer\n"); goto end; } /* Don't want any retries */ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* We might want to do other things with ssl here */ BIO_set_conn_hostname(sbio, connect_str); out = BIO_new_fp(stdout, BIO_NOCLOSE); if (BIO_do_connect(sbio) <= 0) { fprintf(stderr, "Error connecting to server\n"); ERR_print_errors_fp(stderr); goto end; } if (BIO_do_handshake(sbio) <= 0) { fprintf(stderr, "Error establishing SSL connection\n"); ERR_print_errors_fp(stderr); goto end; } /* Could examine ssl here to get connection info */ BIO_puts(sbio, "GET / HTTP/1.0\n\n"); for (;;) { len = BIO_read(sbio, tmpbuf, 1024); if (len <= 0) break; BIO_write(out, tmpbuf, len); } end: SSL_CONF_CTX_free(cctx); BIO_free_all(sbio); BIO_free(out); NCONF_free(conf); return 0; }
int rb_setup_ssl_server(const char *certfile, const char *keyfile, const char *dhfile, const char *cipher_list) { const char librb_ciphers[] = "kEECDH+HIGH:kEDH+HIGH:HIGH:!aNULL"; #ifdef LRB_HAVE_TLS_SET_CURVES const char librb_curves[] = "P-521:P-384:P-256"; #endif if(certfile == NULL) { rb_lib_log("rb_setup_ssl_server: No certificate file"); return 0; } if(keyfile == NULL) keyfile = certfile; if(cipher_list == NULL) cipher_list = librb_ciphers; if (ssl_server_ctx) SSL_CTX_free(ssl_server_ctx); if (ssl_client_ctx) SSL_CTX_free(ssl_client_ctx); #ifdef LRB_HAVE_TLS_METHOD_API ssl_server_ctx = SSL_CTX_new(TLS_server_method()); ssl_client_ctx = SSL_CTX_new(TLS_client_method()); #else ssl_server_ctx = SSL_CTX_new(SSLv23_server_method()); ssl_client_ctx = SSL_CTX_new(SSLv23_client_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())); return 0; } if(ssl_client_ctx == NULL) { rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s", get_ssl_error(ERR_get_error())); return 0; } #ifndef LRB_HAVE_TLS_METHOD_API SSL_CTX_set_options(ssl_server_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); SSL_CTX_set_options(ssl_client_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); #endif #ifdef SSL_OP_SINGLE_DH_USE SSL_CTX_set_options(ssl_server_ctx, SSL_OP_SINGLE_DH_USE); #endif #ifdef SSL_OP_SINGLE_ECDH_USE SSL_CTX_set_options(ssl_server_ctx, SSL_OP_SINGLE_ECDH_USE); #endif #ifdef SSL_OP_NO_TICKET SSL_CTX_set_options(ssl_server_ctx, SSL_OP_NO_TICKET); SSL_CTX_set_options(ssl_client_ctx, SSL_OP_NO_TICKET); #endif #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE SSL_CTX_set_options(ssl_server_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); #endif 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); #ifdef LRB_HAVE_TLS_SET_CURVES SSL_CTX_set1_curves_list(ssl_server_ctx, librb_curves); #endif #ifdef LRB_HAVE_TLS_ECDH_AUTO SSL_CTX_set_ecdh_auto(ssl_server_ctx, 1); #endif /* * Set manual ECDHE curve on OpenSSL 1.0.0 & 1.0.1, but make sure it's actually available */ #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && (OPENSSL_VERSION_NUMBER < 0x10002000L) && !defined(OPENSSL_NO_ECDH) 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 SSL_CTX_set_cipher_list(ssl_server_ctx, cipher_list); SSL_CTX_set_cipher_list(ssl_client_ctx, cipher_list); if(!SSL_CTX_use_certificate_chain_file(ssl_server_ctx, certfile) || !SSL_CTX_use_certificate_chain_file(ssl_client_ctx, certfile)) { rb_lib_log("rb_setup_ssl_server: Error loading certificate file [%s]: %s", certfile, get_ssl_error(ERR_get_error())); return 0; } if(!SSL_CTX_use_PrivateKey_file(ssl_server_ctx, keyfile, SSL_FILETYPE_PEM) || !SSL_CTX_use_PrivateKey_file(ssl_client_ctx, keyfile, SSL_FILETYPE_PEM)) { rb_lib_log("rb_setup_ssl_server: Error loading keyfile [%s]: %s", keyfile, get_ssl_error(ERR_get_error())); return 0; } if(dhfile != NULL) { /* DH parameters aren't necessary, but they are nice..if they didn't pass one..that is their problem */ FILE *fp = fopen(dhfile, "r"); DH *dh = NULL; if(fp == NULL) { rb_lib_log("rb_setup_ssl_server: Error loading DH params file [%s]: %s", dhfile, strerror(errno)); } else if(PEM_read_DHparams(fp, &dh, NULL, NULL) == NULL) { rb_lib_log("rb_setup_ssl_server: Error loading DH params file [%s]: %s", dhfile, get_ssl_error(ERR_get_error())); fclose(fp); } else { SSL_CTX_set_tmp_dh(ssl_server_ctx, dh); DH_free(dh); fclose(fp); } } return 1; }
void Context::createSSLContext() { if (SSLManager::isFIPSEnabled()) { _pSSLContext = SSL_CTX_new(TLSv1_method()); } else { switch (_usage) { case CLIENT_USE: #if OPENSSL_VERSION_NUMBER >= 0x10100000L _pSSLContext = SSL_CTX_new(TLS_client_method()); #else _pSSLContext = SSL_CTX_new(SSLv23_client_method()); #endif break; case SERVER_USE: #if OPENSSL_VERSION_NUMBER >= 0x10100000L _pSSLContext = SSL_CTX_new(TLS_server_method()); #else _pSSLContext = SSL_CTX_new(SSLv23_server_method()); #endif break; #if defined(SSL_OP_NO_TLSv1) && !defined(OPENSSL_NO_TLS1) case TLSV1_CLIENT_USE: _pSSLContext = SSL_CTX_new(TLSv1_client_method()); break; case TLSV1_SERVER_USE: _pSSLContext = SSL_CTX_new(TLSv1_server_method()); break; #endif #if defined(SSL_OP_NO_TLSv1_1) && !defined(OPENSSL_NO_TLS1) /* SSL_OP_NO_TLSv1_1 is defined in ssl.h if the library version supports TLSv1.1. * OPENSSL_NO_TLS1 is defined in opensslconf.h or on the compiler command line * if TLS1.x was removed at OpenSSL library build time via Configure options. */ case TLSV1_1_CLIENT_USE: _pSSLContext = SSL_CTX_new(TLSv1_1_client_method()); break; case TLSV1_1_SERVER_USE: _pSSLContext = SSL_CTX_new(TLSv1_1_server_method()); break; #endif #if defined(SSL_OP_NO_TLSv1_2) && !defined(OPENSSL_NO_TLS1) case TLSV1_2_CLIENT_USE: _pSSLContext = SSL_CTX_new(TLSv1_2_client_method()); break; case TLSV1_2_SERVER_USE: _pSSLContext = SSL_CTX_new(TLSv1_2_server_method()); break; #endif default: throw Poco::InvalidArgumentException("Invalid or unsupported usage"); } } if (!_pSSLContext) { unsigned long err = ERR_get_error(); throw SSLException("Cannot create SSL_CTX object", ERR_error_string(err, 0)); } SSL_CTX_set_default_passwd_cb(_pSSLContext, &SSLManager::privateKeyPassphraseCallback); Utility::clearErrorStack(); SSL_CTX_set_options(_pSSLContext, SSL_OP_ALL); }
static int test_large_message_tls(void) { return execute_test_large_message(TLS_server_method(), TLS_client_method(), 0); }
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. * * OpenSSL 1.1.0-dev deprecates SSLv23_client_method() in favour of * TLS_client_method(), with the change in question signalled via a new * TLS_ANY_VERSION macro. */ ERR_clear_error(); #if OPENSSL_VERSION_NUMBER >= 0x10100000L && defined(TLS_ANY_VERSION) client_ctx = SSL_CTX_new(TLS_client_method()); #else client_ctx = SSL_CTX_new(SSLv23_client_method()); #endif if (client_ctx == 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 int test_large_message_tls_read_ahead(void) { return execute_test_large_message(TLS_server_method(), TLS_client_method(), 1); }
as_status as_tls_context_setup(as_config_tls* tlscfg, as_tls_context* ctx, as_error* errp) { // Clear the destination, in case we don't make it. ctx->ssl_ctx = NULL; ctx->pkey = NULL; ctx->cert_blacklist = NULL; ctx->log_session_info = tlscfg->log_session_info; ctx->for_login_only = tlscfg->for_login_only; as_tls_check_init(); pthread_mutex_init(&ctx->lock, NULL); if (tlscfg->cert_blacklist) { ctx->cert_blacklist = cert_blacklist_read(tlscfg->cert_blacklist); if (! ctx->cert_blacklist) { as_tls_context_destroy(ctx); return as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR, "Failed to read certificate blacklist: %s", tlscfg->cert_blacklist); } } uint16_t protocols = AS_TLS_PROTOCOL_NONE; as_status status = protocols_parse(tlscfg, &protocols, errp); if (status != AEROSPIKE_OK) { as_tls_context_destroy(ctx); return status; } const SSL_METHOD* method = NULL; // If the selected protocol set is a single protocol we can use a specific method. if (protocols == AS_TLS_PROTOCOL_TLSV1) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L method = TLS_client_method(); #else method = TLSv1_client_method(); #endif } else if (protocols == AS_TLS_PROTOCOL_TLSV1_1) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L method = TLS_client_method(); #else method = TLSv1_1_client_method(); #endif } else if (protocols == AS_TLS_PROTOCOL_TLSV1_2) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L method = TLS_client_method(); #else method = TLSv1_2_client_method(); #endif } else { // Multiple protocols are enabled, use a flexible method. #if OPENSSL_VERSION_NUMBER >= 0x10100000L method = TLS_client_method(); #else method = SSLv23_client_method(); #endif } ctx->ssl_ctx = SSL_CTX_new(method); if (ctx->ssl_ctx == NULL) { as_tls_context_destroy(ctx); unsigned long errcode = ERR_get_error(); char errbuf[1024]; ERR_error_string_n(errcode, errbuf, sizeof(errbuf)); return as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR, "Failed to create new TLS context: %s", errbuf); } /* always disable SSLv2, as per RFC 6176 */ SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2); SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv3); // Turn off non-enabled protocols. if (! (protocols & AS_TLS_PROTOCOL_TLSV1)) { SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1); } if (! (protocols & AS_TLS_PROTOCOL_TLSV1_1)) { SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_1); } if (! (protocols & AS_TLS_PROTOCOL_TLSV1_2)) { SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_2); } if (tlscfg->cafile || tlscfg->capath) { int rv = SSL_CTX_load_verify_locations(ctx->ssl_ctx, tlscfg->cafile, tlscfg->capath); if (rv != 1) { as_tls_context_destroy(ctx); char errbuf[1024]; unsigned long errcode = ERR_get_error(); if (errcode != 0) { ERR_error_string_n(errcode, errbuf, sizeof(errbuf)); return as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR, "Failed to load CAFile: %s", errbuf); } return as_error_set_message(errp, AEROSPIKE_ERR_TLS_ERROR, "Unknown failure loading CAFile"); } } if (tlscfg->certfile) { int rv = SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, tlscfg->certfile); if (rv != 1) { // We seem to be seeing this bug: // https://groups.google.com/ // forum/#!topic/mailing.openssl.users/nRvRzmKnEQA // If the rv is not 1 check the error stack; if it doesn't have an // error assume we are OK. // unsigned long errcode = ERR_peek_error(); if (errcode != SSL_ERROR_NONE) { // There *was* an error after all. as_tls_context_destroy(ctx); unsigned long errcode = ERR_get_error(); char errbuf[1024]; ERR_error_string_n(errcode, errbuf, sizeof(errbuf)); return as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR, "SSL_CTX_use_certificate_chain_file failed: %s", errbuf); } } } if (tlscfg->keyfile) { bool ok = false; FILE *fh = fopen(tlscfg->keyfile, "r"); if (fh == NULL) { as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR, "failed to open key file %s: %s", tlscfg->keyfile, strerror(errno)); } else { EVP_PKEY *pkey = PEM_read_PrivateKey(fh, NULL, password_cb, tlscfg->keyfile_pw); if (pkey == NULL) { unsigned long errcode = ERR_get_error(); if (ERR_GET_REASON(errcode) == PEM_R_BAD_PASSWORD_READ) { if (tlscfg->keyfile_pw == NULL) { as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR, "key file %s requires a password", tlscfg->keyfile); } else { as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR, "password for key file %s too long", tlscfg->keyfile); } } else if (ERR_GET_REASON(errcode) == EVP_R_BAD_DECRYPT) { as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR, "invalid password for key file %s", tlscfg->keyfile); } else { char errbuf[1024]; ERR_error_string_n(errcode, errbuf, sizeof(errbuf)); as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR, "PEM_read_PrivateKey failed: %s", errbuf); } } else { ctx->pkey = pkey; SSL_CTX_use_PrivateKey(ctx->ssl_ctx, pkey); ok = true; } fclose(fh); } if (!ok) { as_tls_context_destroy(ctx); return AEROSPIKE_ERR_TLS_ERROR; } } if (tlscfg->cipher_suite) { int rv = SSL_CTX_set_cipher_list(ctx->ssl_ctx, tlscfg->cipher_suite); if (rv != 1) { as_tls_context_destroy(ctx); return as_error_set_message(errp, AEROSPIKE_ERR_TLS_ERROR, "no compatible cipher found"); } // It's bogus that we have to create an SSL just to get the // cipher list, but SSL_CTX_get_ciphers doesn't appear to // exist ... SSL* ssl = SSL_new(ctx->ssl_ctx); for (int prio = 0; true; ++prio) { char const * cipherstr = SSL_get_cipher_list(ssl, prio); if (!cipherstr) { break; } as_log_info("cipher %d: %s", prio+1, cipherstr); } SSL_free(ssl); } if (tlscfg->crl_check || tlscfg->crl_check_all) { X509_VERIFY_PARAM* param = X509_VERIFY_PARAM_new(); unsigned long flags = X509_V_FLAG_CRL_CHECK; if (tlscfg->crl_check_all) { flags |= X509_V_FLAG_CRL_CHECK_ALL; } X509_VERIFY_PARAM_set_flags(param, flags); SSL_CTX_set1_param(ctx->ssl_ctx, param); X509_VERIFY_PARAM_free(param); } SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, verify_callback); manage_sigpipe(); return AEROSPIKE_OK; }
static int execute_test_session(SSL_SESSION_TEST_FIXTURE fix) { SSL_CTX *sctx = NULL, *cctx = NULL; SSL *serverssl1 = NULL, *clientssl1 = NULL; SSL *serverssl2 = NULL, *clientssl2 = NULL; #ifndef OPENSSL_NO_TLS1_1 SSL *serverssl3 = NULL, *clientssl3 = NULL; #endif SSL_SESSION *sess1 = NULL, *sess2 = NULL; int testresult = 0; if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx, &cctx, cert, privkey)) { printf("Unable to create SSL_CTX pair\n"); return 0; } #ifndef OPENSSL_NO_TLS1_2 /* Only allow TLS1.2 so we can force a connection failure later */ SSL_CTX_set_min_proto_version(cctx, TLS1_2_VERSION); #endif /* Set up session cache */ if (fix.use_ext_cache) { SSL_CTX_sess_set_new_cb(cctx, new_session_cb); SSL_CTX_sess_set_remove_cb(cctx, remove_session_cb); } if (fix.use_int_cache) { /* Also covers instance where both are set */ SSL_CTX_set_session_cache_mode(cctx, SSL_SESS_CACHE_CLIENT); } else { SSL_CTX_set_session_cache_mode(cctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE); } if (!create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1, NULL, NULL)) { printf("Unable to create SSL objects\n"); goto end; } if (!create_ssl_connection(serverssl1, clientssl1)) { printf("Unable to create SSL connection\n"); goto end; } sess1 = SSL_get1_session(clientssl1); if (sess1 == NULL) { printf("Unexpected NULL session\n"); goto end; } if (fix.use_int_cache && SSL_CTX_add_session(cctx, sess1)) { /* Should have failed because it should already be in the cache */ printf("Unexpected success adding session to cache\n"); goto end; } if (fix.use_ext_cache && (new_called != 1 || remove_called != 0)) { printf("Session not added to cache\n"); goto end; } if (!create_ssl_objects(sctx, cctx, &serverssl2, &clientssl2, NULL, NULL)) { printf("Unable to create second SSL objects\n"); goto end; } if (!create_ssl_connection(serverssl2, clientssl2)) { printf("Unable to create second SSL connection\n"); goto end; } sess2 = SSL_get1_session(clientssl2); if (sess2 == NULL) { printf("Unexpected NULL session from clientssl2\n"); goto end; } if (fix.use_ext_cache && (new_called != 2 || remove_called != 0)) { printf("Remove session callback unexpectedly called\n"); goto end; } /* * This should clear sess2 from the cache because it is a "bad" session. See * SSL_set_session() documentation. */ if (!SSL_set_session(clientssl2, sess1)) { printf("Unexpected failure setting session\n"); goto end; } if (fix.use_ext_cache && (new_called != 2 || remove_called != 1)) { printf("Failed to call callback to remove session\n"); goto end; } if (SSL_get_session(clientssl2) != sess1) { printf("Unexpected session found\n"); goto end; } if (fix.use_int_cache) { if (!SSL_CTX_add_session(cctx, sess2)) { /* * Should have succeeded because it should not already be in the cache */ printf("Unexpected failure adding session to cache\n"); goto end; } if (!SSL_CTX_remove_session(cctx, sess2)) { printf("Unexpected failure removing session from cache\n"); goto end; } /* This is for the purposes of internal cache testing...ignore the * counter for external cache */ if (fix.use_ext_cache) remove_called--; } /* This shouldn't be in the cache so should fail */ if (SSL_CTX_remove_session(cctx, sess2)) { printf("Unexpected success removing session from cache\n"); goto end; } if (fix.use_ext_cache && (new_called != 2 || remove_called != 2)) { printf("Failed to call callback to remove session #2\n"); goto end; } #if !defined(OPENSSL_NO_TLS1_1) && !defined(OPENSSL_NO_TLS1_2) /* Force a connection failure */ SSL_CTX_set_max_proto_version(sctx, TLS1_1_VERSION); if (!create_ssl_objects(sctx, cctx, &serverssl3, &clientssl3, NULL, NULL)) { printf("Unable to create third SSL objects\n"); goto end; } if (!SSL_set_session(clientssl3, sess1)) { printf("Unable to set session for third connection\n"); goto end; } /* This should fail because of the mismatched protocol versions */ if (create_ssl_connection(serverssl3, clientssl3)) { printf("Unable to create third SSL connection\n"); goto end; } /* We should have automatically removed the session from the cache */ if (fix.use_ext_cache && (new_called != 2 || remove_called != 3)) { printf("Failed to call callback to remove session #2\n"); goto end; } if (fix.use_int_cache && !SSL_CTX_add_session(cctx, sess2)) { /* * Should have succeeded because it should not already be in the cache */ printf("Unexpected failure adding session to cache #2\n"); goto end; } #endif testresult = 1; end: SSL_free(serverssl1); SSL_free(clientssl1); SSL_free(serverssl2); SSL_free(clientssl2); #ifndef OPENSSL_NO_TLS1_1 SSL_free(serverssl3); SSL_free(clientssl3); #endif SSL_SESSION_free(sess1); SSL_SESSION_free(sess2); /* * Check if we need to remove any sessions up-refed for the external cache */ if (new_called >= 1) SSL_SESSION_free(sess1); if (new_called >= 2) SSL_SESSION_free(sess2); SSL_CTX_free(sctx); SSL_CTX_free(cctx); return testresult; }
int main(int argc, char *argv[]) { const char *hostport = HOSTPORT; const char *CAfile = CAFILE; char *hostname; char *cp; BIO *out = NULL; char buf[1024 * 10], *p; SSL_CTX *ssl_ctx = NULL; SSL *ssl; BIO *ssl_bio; int i, len, off, ret = EXIT_FAILURE; if (argc > 1) hostport = argv[1]; if (argc > 2) CAfile = argv[2]; hostname = OPENSSL_strdup(hostport); if ((cp = strchr(hostname, ':')) != NULL) *cp = 0; #ifdef WATT32 dbug_init(); sock_init(); #endif ssl_ctx = SSL_CTX_new(TLS_client_method()); /* Enable trust chain verification */ SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); SSL_CTX_load_verify_locations(ssl_ctx, CAfile, NULL); /* Lets make a SSL structure */ ssl = SSL_new(ssl_ctx); SSL_set_connect_state(ssl); /* Enable peername verification */ if (SSL_set1_host(ssl, hostname) <= 0) goto err; /* Use it inside an SSL BIO */ ssl_bio = BIO_new(BIO_f_ssl()); BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE); /* Lets use a connect BIO under the SSL BIO */ out = BIO_new(BIO_s_connect()); BIO_set_conn_hostname(out, hostport); BIO_set_nbio(out, 1); out = BIO_push(ssl_bio, out); p = "GET / HTTP/1.0\r\n\r\n"; len = strlen(p); off = 0; for (;;) { i = BIO_write(out, &(p[off]), len); if (i <= 0) { if (BIO_should_retry(out)) { fprintf(stderr, "write DELAY\n"); sleep(1); continue; } else { goto err; } } off += i; len -= i; if (len <= 0) break; } for (;;) { i = BIO_read(out, buf, sizeof(buf)); if (i == 0) break; if (i < 0) { if (BIO_should_retry(out)) { fprintf(stderr, "read DELAY\n"); sleep(1); continue; } goto err; } fwrite(buf, 1, i, stdout); } ret = EXIT_SUCCESS; goto done; err: if (ERR_peek_error() == 0) { /* system call error */ fprintf(stderr, "errno=%d ", errno); perror("error"); } else { ERR_print_errors_fp(stderr); } done: BIO_free_all(out); SSL_CTX_free(ssl_ctx); return ret; }
int s_time_main(int argc, char **argv) { char buf[1024 * 8]; SSL *scon = NULL; SSL_CTX *ctx = NULL; const SSL_METHOD *meth = NULL; char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *ciphersuites = NULL; char *www_path = NULL; char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog; double totalTime = 0.0; int noCApath = 0, noCAfile = 0; int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs = 0; long bytes_read = 0, finishtime = 0; OPTION_CHOICE o; int max_version = 0, ver, buf_len; size_t buf_size; meth = TLS_client_method(); prog = opt_init(argc, argv, s_time_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(s_time_options); ret = 0; goto end; case OPT_CONNECT: host = opt_arg(); break; case OPT_REUSE: perform = 2; break; case OPT_NEW: perform = 1; break; case OPT_VERIFY: if (!opt_int(opt_arg(), &verify_args.depth)) goto opthelp; BIO_printf(bio_err, "%s: verify depth is %d\n", prog, verify_args.depth); break; case OPT_CERT: certfile = opt_arg(); break; case OPT_NAMEOPT: if (!set_nameopt(opt_arg())) goto end; break; case OPT_KEY: keyfile = opt_arg(); break; case OPT_CAPATH: CApath = opt_arg(); break; case OPT_CAFILE: CAfile = opt_arg(); break; case OPT_NOCAPATH: noCApath = 1; break; case OPT_NOCAFILE: noCAfile = 1; break; case OPT_CIPHER: cipher = opt_arg(); break; case OPT_CIPHERSUITES: ciphersuites = opt_arg(); break; case OPT_BUGS: st_bugs = 1; break; case OPT_TIME: if (!opt_int(opt_arg(), &maxtime)) goto opthelp; break; case OPT_WWW: www_path = opt_arg(); buf_size = strlen(www_path) + fmt_http_get_cmd_size; if (buf_size > sizeof(buf)) { BIO_printf(bio_err, "%s: -www option is too long\n", prog); goto end; } break; case OPT_SSL3: max_version = SSL3_VERSION; break; } } argc = opt_num_rest(); if (argc != 0) goto opthelp; if (cipher == NULL) cipher = getenv("SSL_CIPHER"); if ((ctx = SSL_CTX_new(meth)) == NULL) goto end; SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_quiet_shutdown(ctx, 1); if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0) goto end; if (st_bugs) SSL_CTX_set_options(ctx, SSL_OP_ALL); if (cipher != NULL && !SSL_CTX_set_cipher_list(ctx, cipher)) goto end; if (ciphersuites != NULL && !SSL_CTX_set_ciphersuites(ctx, ciphersuites)) goto end; if (!set_cert_stuff(ctx, certfile, keyfile)) goto end; if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) { ERR_print_errors(bio_err); goto end; } if (!(perform & 1)) goto next; printf("Collecting connection statistics for %d seconds\n", maxtime); /* Loop and time how long it takes to make connections */ bytes_read = 0; finishtime = (long)time(NULL) + maxtime; tm_Time_F(START); for (;;) { if (finishtime < (long)time(NULL)) break; if ((scon = doConnection(NULL, host, ctx)) == NULL) goto end; if (www_path != NULL) { buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path); if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) goto end; while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) bytes_read += i; } SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); BIO_closesocket(SSL_get_fd(scon)); nConn += 1; if (SSL_session_reused(scon)) { ver = 'r'; } else { ver = SSL_version(scon); if (ver == TLS1_VERSION) ver = 't'; else if (ver == SSL3_VERSION) ver = '3'; else ver = '*'; } fputc(ver, stdout); fflush(stdout); SSL_free(scon); scon = NULL; } totalTime += tm_Time_F(STOP); /* Add the time for this iteration */ i = (int)((long)time(NULL) - finishtime + maxtime); printf ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn / totalTime), bytes_read); printf ("%d connections in %ld real seconds, %ld bytes read per connection\n", nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn); /* * Now loop and time connections using the same session id over and over */ next: if (!(perform & 2)) goto end; printf("\n\nNow timing with session id reuse.\n"); /* Get an SSL object so we can reuse the session id */ if ((scon = doConnection(NULL, host, ctx)) == NULL) { BIO_printf(bio_err, "Unable to get connection\n"); goto end; } if (www_path != NULL) { buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path); if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) goto end; while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) continue; } SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); BIO_closesocket(SSL_get_fd(scon)); nConn = 0; totalTime = 0.0; finishtime = (long)time(NULL) + maxtime; printf("starting\n"); bytes_read = 0; tm_Time_F(START); for (;;) { if (finishtime < (long)time(NULL)) break; if ((doConnection(scon, host, ctx)) == NULL) goto end; if (www_path != NULL) { buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path); if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) goto end; while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) bytes_read += i; } SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); BIO_closesocket(SSL_get_fd(scon)); nConn += 1; if (SSL_session_reused(scon)) { ver = 'r'; } else { ver = SSL_version(scon); if (ver == TLS1_VERSION) ver = 't'; else if (ver == SSL3_VERSION) ver = '3'; else ver = '*'; } fputc(ver, stdout); fflush(stdout); } totalTime += tm_Time_F(STOP); /* Add the time for this iteration */ printf ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn / totalTime), bytes_read); printf ("%d connections in %ld real seconds, %ld bytes read per connection\n", nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn); ret = 0; end: SSL_free(scon); SSL_CTX_free(ctx); return ret; }
BOOL connect_ssl(int sockfd, const char* ca_crt_root, const char* ca_crt_client, const char* ca_password, const char* ca_key_client, SSL** pp_ssl, SSL_CTX** pp_ssl_ctx) { SSL_METHOD* meth = NULL; #if OPENSSL_VERSION_NUMBER >= 0x010100000L meth = (SSL_METHOD*)TLS_client_method(); #else meth = (SSL_METHOD*)SSLv23_client_method(); #endif /* OPENSSL_VERSION_NUMBER */ *pp_ssl_ctx = SSL_CTX_new(meth); if(!*pp_ssl_ctx) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_CTX_new: %s\n", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl3; } if(ca_crt_root && ca_crt_client && ca_password && ca_key_client) { SSL_CTX_load_verify_locations(*pp_ssl_ctx, ca_crt_root, NULL); if(SSL_CTX_use_certificate_file(*pp_ssl_ctx, ca_crt_client, SSL_FILETYPE_PEM) <= 0) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl2; } SSL_CTX_set_default_passwd_cb_userdata(*pp_ssl_ctx, (char*)ca_password); if(SSL_CTX_use_PrivateKey_file(*pp_ssl_ctx, ca_key_client, SSL_FILETYPE_PEM) <= 0) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl2; } if(!SSL_CTX_check_private_key(*pp_ssl_ctx)) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl2; } } *pp_ssl = SSL_new(*pp_ssl_ctx); if(!*pp_ssl) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_new: %s\n", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl2; } if(SSL_set_fd(*pp_ssl, sockfd) <= 0) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_set_fd: %s\n", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl1; } if(SSL_connect(*pp_ssl) <= 0) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_connect: %s\n", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl1; } return TRUE; clean_ssl1: if(*pp_ssl) { SSL_free(*pp_ssl); *pp_ssl = NULL; } clean_ssl2: if(*pp_ssl_ctx) { SSL_CTX_free(*pp_ssl_ctx); *pp_ssl_ctx = NULL; } clean_ssl3: return FALSE; }