/* Initialize the library */ static void tls_init(int verify) { if(_tlsctx) { TLSERROR("Library is already initialized!"); return; } SSL_load_error_strings(); SSL_library_init(); _tlsctx = SSL_CTX_new(TLSv1_method()); if(!_tlsctx) TLSERROR("Couldn't create TLS object.\n"); else { OPENSSLCHECK(SSL_CTX_set_quiet_shutdown(_tlsctx, 1)); OPENSSLCHECK(SSL_CTX_set_info_callback(_tlsctx, NULL)); OPENSSLCHECK(SSL_CTX_load_verify_locations(ctx, CAfile, CApath)); OPENSSLCHECK(SSL_CTX_set_default_verify_paths()); if(verify == GGZ_TLS_VERIFY_PEER) SSL_CTX_set_verify(_tlsctx, SSL_VERIFY_PEER, tls_verify); else SSL_CTX_set_verify(_tlsctx, SSL_VERIFY_NONE, NULL); } openssllist = ggz_list_create(NULL, NULL, NULL, GGZ_LIST_ALLOW_DUPS); }
wi_socket_tls_t * wi_socket_tls_init_with_type(wi_socket_tls_t *tls, wi_socket_tls_type_t type) { SSL_METHOD *method; switch(type) { default: case WI_SOCKET_TLS_CLIENT: method = TLSv1_client_method(); break; case WI_SOCKET_TLS_SERVER: method = TLSv1_server_method(); break; } tls->ssl_ctx = SSL_CTX_new(method); if(!tls->ssl_ctx) { wi_error_set_openssl_error(); wi_release(NULL); return NULL; } SSL_CTX_set_mode(tls->ssl_ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_quiet_shutdown(tls->ssl_ctx, 1); return tls; }
static CURLcode sslctxfun(CURL * curl, void * sslctx, void * parm) { sslctxparm * p = (sslctxparm *) parm; SSL_CTX * ctx = (SSL_CTX *) sslctx ; fprintf(stderr,"sslctxfun start curl=%p ctx=%p parm=%p\n", (void *)curl,(void *)ctx,(void *)p); SSL_CTX_set_quiet_shutdown(ctx,1); SSL_CTX_set_cipher_list(ctx,"RC4-MD5"); SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); /* one might assume that the cert validaton would not fail when setting this, but it still does, see the error handling in the call back */ SSL_CTX_set_verify_depth(ctx,0); SSL_CTX_set_verify(ctx,SSL_VERIFY_NONE,ZERO_NULL); #if OPENSSL_VERSION_NUMBER<0x00907000L /* in newer openssl versions we can set a parameter for the call back. */ fprintf(stderr,"This version %s of openssl does not support a parm," " setting global one\n", OPENSSL_VERSION_TEXT); /* this is only done to support 0.9.6 version */ globalparm = parm; /* in 0.9.6 the parm is not taken */ #endif SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm); fprintf(stderr,"sslctxfun end\n"); return CURLE_OK ; }
static CURLcode sslctxfun( CURL * curl, void * sslctx, void * parm ) { sslctxparm * p = (sslctxparm *) parm; SSL_CTX * ctx = (SSL_CTX *) sslctx ; if ( !SSL_CTX_use_certificate( ctx,p->usercert ) ) { BIO_printf( p->errorbio, "SSL_CTX_use_certificate problem\n" ); goto err; } if ( !SSL_CTX_use_PrivateKey( ctx,p->pkey ) ) { BIO_printf( p->errorbio, "SSL_CTX_use_PrivateKey\n" ); goto err; } if ( !SSL_CTX_check_private_key( ctx ) ) { BIO_printf( p->errorbio, "SSL_CTX_check_private_key\n" ); goto err; } SSL_CTX_set_quiet_shutdown( ctx,1 ); SSL_CTX_set_cipher_list( ctx,"RC4-MD5" ); SSL_CTX_set_mode( ctx, SSL_MODE_AUTO_RETRY ); X509_STORE_add_cert( ctx->cert_store,sk_X509_value( p->ca,sk_X509_num( p->ca ) - 1 ) ); SSL_CTX_set_verify_depth( ctx,2 ); SSL_CTX_set_verify( ctx,SSL_VERIFY_PEER,NULL ); SSL_CTX_set_cert_verify_callback( ctx, ssl_app_verify_callback, parm ); return CURLE_OK ; err: ERR_print_errors( p->errorbio ); return CURLE_SSL_CERTPROBLEM; }
int CSSLContext::AddContext(int iVerifyMode, LPCTSTR lpszPemCertFile, LPCTSTR lpszPemKeyFile, LPCTSTR lpszKeyPasswod, LPCTSTR lpszCAPemCertFileOrPath) { int iIndex = -1; SSL_CTX* sslCtx = SSL_CTX_new(SSLv23_method()); SSL_CTX_set_quiet_shutdown(sslCtx, 1); SSL_CTX_set_verify(sslCtx, iVerifyMode, nullptr); SSL_CTX_set_cipher_list(sslCtx, "ALL:!aNULL:!eNULL"); if(m_enSessionMode == SSL_SM_SERVER) { static volatile ULONG s_session_id_context = 0; ULONG session_id_context = ::InterlockedIncrement(&s_session_id_context); SSL_CTX_set_session_id_context(sslCtx, (BYTE*)&session_id_context, sizeof(session_id_context)); } if(!LoadCertAndKey(sslCtx, iVerifyMode, lpszPemCertFile, lpszPemKeyFile, lpszKeyPasswod, lpszCAPemCertFileOrPath)) SSL_CTX_free(sslCtx); else { iIndex = (int)m_lsSslCtxs.size(); m_lsSslCtxs.push_back(sslCtx); } return iIndex; }
static int openssl_ssl_ctx_quiet_shutdown(lua_State*L) { SSL_CTX* s = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx"); if (lua_isnoneornil(L, 2)) { int m = SSL_CTX_get_quiet_shutdown(s); lua_pushinteger(L, m); return 1; } else { int m = luaL_checkint(L, 2); SSL_CTX_set_quiet_shutdown(s, m); return 0; } };
int _openssl_env_init(openssl_env *env, char *engine, int server) { /* * Create an OpenSSL environment (method and context). * If ``server'' is 1, the environment is that of a SSL * server. */ const long options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION; env->meth = SSLv23_method(); env->ctx = SSL_CTX_new(env->meth); SSL_CTX_set_options(env->ctx, options); if (_options.sslciphers) { SSL_CTX_set_cipher_list(env->ctx, _options.sslciphers); } #ifdef HAVE_OPENSSL_ENGINE if (engine) { retry: if ((env->engine = ENGINE_by_id(engine)) == NULL) { fprintf(stderr,"invalid engine \"%s\"\n", engine); ENGINE_free(env->engine); engine = "openssl"; goto retry; } if (!ENGINE_set_default(env->engine, ENGINE_METHOD_ALL)) { fprintf(stderr,"can't use that engine\n"); ENGINE_free(env->engine); engine = "openssl"; goto retry; } } #endif #ifdef HAVE_OPENSSL_ENGINE SSL_CTX_set_app_data(env->ctx, env); #endif if (server) { SSL_CTX_set_options(env->ctx, SSL_OP_SINGLE_DH_USE); SSL_CTX_set_session_cache_mode(env->ctx, SSL_SESS_CACHE_OFF); SSL_CTX_set_quiet_shutdown(env->ctx, 1); } return 1; }
bool init_ssl (void) { SSL_CTX_set_quiet_shutdown (ACE_SSL_Context::instance ()->context(), 1); SSL_CTX_set_options (ACE_SSL_Context::instance ()->context(), SSL_OP_SINGLE_DH_USE); SSL_CTX_set_tmp_dh_callback (ACE_SSL_Context::instance ()->context (), tmp_dh_callback); if (SSL_CTX_set_cipher_list (ACE_SSL_Context::instance ()->context (), "ADH")) { return true; } else { ACE_DEBUG ((LM_ERROR, ACE_TEXT ("SSL_CTX_set_cipher_list failed\n"))); return false; } }
/** * Create a new SSL context. */ struct ssl_context_handle* net_ssl_context_create(const char* tls_version, const char* tls_ciphersuite) { struct net_context_openssl* ctx = (struct net_context_openssl*) hub_malloc_zero(sizeof(struct net_context_openssl)); const SSL_METHOD* ssl_method = get_ssl_method(tls_version); if (!ssl_method) { hub_free(ctx); return 0; } ctx->ssl = SSL_CTX_new(ssl_method); /* Disable SSLv2 */ SSL_CTX_set_options(ctx->ssl, SSL_OP_NO_SSLv2); // FIXME: Why did we need this again? SSL_CTX_set_quiet_shutdown(ctx->ssl, 1); #ifdef SSL_OP_NO_COMPRESSION /* Disable compression */ LOG_TRACE("Disabling SSL compression."); /* "CRIME" attack */ SSL_CTX_set_options(ctx->ssl, SSL_OP_NO_COMPRESSION); #endif /* Set preferred cipher suite */ if (SSL_CTX_set_cipher_list(ctx->ssl, tls_ciphersuite) != 1) { LOG_ERROR("Unable to set cipher suite."); SSL_CTX_free(ctx->ssl); hub_free(ctx); return 0; } return (struct ssl_context_handle*) ctx; }
SSL_CTX *dtls_setup_ssl_server (void) { SSL_METHOD *meth = NULL; SSL_CTX *ctx = NULL; int s_server_verify = SSL_VERIFY_CLIENT_ONCE; //SSL_VERIFY_NONE; if (!dtls_bio_err) { SSL_library_init (); ERR_clear_error (); SSL_load_error_strings (); OpenSSL_add_all_algorithms (); dtls_bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); } meth = DTLSv1_server_method (); // Support DTLS v1 server - Datagram TLS - requires openSSL > v0.9.8 ctx = SSL_CTX_new (meth); // New SSL CTX object as Framework to establish new SSL connections if (NULL == ctx) { dtls_report_berr ("%s: %s(): ERROR: SSL_ctx_new - DTLSv1_server_method\n", __FILE__, __func__); } SSL_CTX_set_quiet_shutdown (ctx, 1); if (!SSL_CTX_use_certificate_chain_file (ctx, DTLS_CERT)) { dtls_destroy_ctx (ctx); dtls_report_berr ("Error loading the file \"%s\" - %s\n", DTLS_CERT, strerror (errno)); } // SSL_CTX_set_default_passwd_cb (ctx, dtls_password_cb); if (!SSL_CTX_use_PrivateKey_file (ctx, DTLS_KEY_CERT, SSL_FILETYPE_PEM)) { dtls_destroy_ctx (ctx); dtls_report_berr ("Error loading the private key from the file \"%s\" - %s\n", DTLS_KEY_CERT, strerror (errno)); } if (!SSL_CTX_check_private_key (ctx)) { dtls_destroy_ctx (ctx); dtls_report_berr ("%s: %s(): Private key does not match the certificate\n", __FILE__, __func__); } if (!SSL_CTX_load_verify_locations (ctx, DTLS_CA_CERT, 0)) { dtls_destroy_ctx (ctx); dtls_report_berr ("Error loading the CA file - %s\n", strerror (errno)); } dtls_generate_rsa_key (ctx); // SSL_CTX_set_verify_depth (ctx, 2); SSL_CTX_set_verify(ctx, s_server_verify, dtls_verify_callback); SSL_CTX_set_options (ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2); SSL_CTX_set_session_id_context (ctx, "dtls-example", strlen ("dtls-example")); #ifdef DEBUG SSL_CTX_set_info_callback (ctx, dtls_info_callback); #endif SSL_CTX_set_read_ahead (ctx, 1); // Specific for DTLS return ctx; }
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; }
static void setup_ssl(tcptest_t *item) { static int ssl_init_complete = 0; struct servent *sp; char portinfo[100]; X509 *peercert; char *certcn, *certstart, *certend; int err; strbuffer_t *sslinfo; char msglin[2048]; item->sslrunning = 1; if (!ssl_init_complete) { /* Setup entropy */ if (RAND_status() != 1) { char path[PATH_MAX]; /* Path for the random file */ /* load entropy from files */ RAND_load_file(RAND_file_name(path, sizeof (path)), -1); /* load entropy from egd sockets */ RAND_egd("/var/run/egd-pool"); RAND_egd("/dev/egd-pool"); RAND_egd("/etc/egd-pool"); RAND_egd("/var/spool/prngd/pool"); /* shuffle $RANDFILE (or ~/.rnd if unset) */ RAND_write_file(RAND_file_name(path, sizeof (path))); if (RAND_status() != 1) { errprintf("Failed to find enough entropy on your system"); item->errcode = CONTEST_ESSL; return; } } SSL_load_error_strings(); SSL_library_init(); ssl_init_complete = 1; } if (item->sslctx == NULL) { switch (item->ssloptions->sslversion) { case SSLVERSION_V2: item->sslctx = SSL_CTX_new(SSLv2_client_method()); break; case SSLVERSION_V3: item->sslctx = SSL_CTX_new(SSLv3_client_method()); break; case SSLVERSION_TLS1: item->sslctx = SSL_CTX_new(TLSv1_client_method()); break; default: item->sslctx = SSL_CTX_new(SSLv23_client_method()); break; } if (!item->sslctx) { char sslerrmsg[256]; ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("Cannot create SSL context - IP %s, service %s: %s\n", inet_ntoa(item->addr.sin_addr), item->svcinfo->svcname, sslerrmsg); item->sslrunning = 0; item->errcode = CONTEST_ESSL; return; } /* Workaround SSL bugs */ SSL_CTX_set_options(item->sslctx, SSL_OP_ALL); SSL_CTX_set_quiet_shutdown(item->sslctx, 1); /* Limit set of ciphers, if user wants to */ if (item->ssloptions->cipherlist) SSL_CTX_set_cipher_list(item->sslctx, item->ssloptions->cipherlist); if (item->ssloptions->clientcert) { int status; char certfn[PATH_MAX]; SSL_CTX_set_default_passwd_cb(item->sslctx, cert_password_cb); SSL_CTX_set_default_passwd_cb_userdata(item->sslctx, item); sprintf(certfn, "%s/certs/%s", xgetenv("XYMONHOME"), item->ssloptions->clientcert); status = SSL_CTX_use_certificate_chain_file(item->sslctx, certfn); if (status == 1) { status = SSL_CTX_use_PrivateKey_file(item->sslctx, certfn, SSL_FILETYPE_PEM); } if (status != 1) { char sslerrmsg[256]; ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("Cannot load SSL client certificate/key %s: %s\n", item->ssloptions->clientcert, sslerrmsg); item->sslrunning = 0; item->errcode = CONTEST_ESSL; return; } } } if (item->ssldata == NULL) { item->ssldata = SSL_new(item->sslctx); if (!item->ssldata) { char sslerrmsg[256]; ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("SSL_new failed - IP %s, service %s: %s\n", inet_ntoa(item->addr.sin_addr), item->svcinfo->svcname, sslerrmsg); item->sslrunning = 0; SSL_CTX_free(item->sslctx); item->errcode = CONTEST_ESSL; return; } /* Verify that the client certificate is working */ if (item->ssloptions->clientcert) { X509 *x509; x509 = SSL_get_certificate(item->ssldata); if(x509 != NULL) { EVP_PKEY *pktmp = X509_get_pubkey(x509); EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(item->ssldata)); EVP_PKEY_free(pktmp); } if (!SSL_CTX_check_private_key(item->sslctx)) { errprintf("Private/public key mismatch for certificate %s\n", item->ssloptions->clientcert); item->sslrunning = 0; item->errcode = CONTEST_ESSL; return; } } /* SSL setup is done. Now attach the socket FD to the SSL protocol handler */ if (SSL_set_fd(item->ssldata, item->fd) != 1) { char sslerrmsg[256]; ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("Could not initiate SSL on connection - IP %s, service %s: %s\n", inet_ntoa(item->addr.sin_addr), item->svcinfo->svcname, sslerrmsg); item->sslrunning = 0; SSL_free(item->ssldata); SSL_CTX_free(item->sslctx); item->errcode = CONTEST_ESSL; return; } } sp = getservbyport(item->addr.sin_port, "tcp"); if (sp) { sprintf(portinfo, "%s (%d/tcp)", sp->s_name, item->addr.sin_port); } else { sprintf(portinfo, "%d/tcp", item->addr.sin_port); } if ((err = SSL_connect(item->ssldata)) != 1) { char sslerrmsg[256]; switch (SSL_get_error (item->ssldata, err)) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: item->sslrunning = SSLSETUP_PENDING; break; case SSL_ERROR_SYSCALL: ERR_error_string(ERR_get_error(), sslerrmsg); /* Filter out the bogus SSL error */ if (strstr(sslerrmsg, "error:00000000:") == NULL) { errprintf("IO error in SSL_connect to %s on host %s: %s\n", portinfo, inet_ntoa(item->addr.sin_addr), sslerrmsg); } item->errcode = CONTEST_ESSL; item->sslrunning = 0; SSL_free(item->ssldata); SSL_CTX_free(item->sslctx); break; case SSL_ERROR_SSL: ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("Unspecified SSL error in SSL_connect to %s on host %s: %s\n", portinfo, inet_ntoa(item->addr.sin_addr), sslerrmsg); item->errcode = CONTEST_ESSL; item->sslrunning = 0; SSL_free(item->ssldata); SSL_CTX_free(item->sslctx); break; default: ERR_error_string(ERR_get_error(), sslerrmsg); errprintf("Unknown error %d in SSL_connect to %s on host %s: %s\n", err, portinfo, inet_ntoa(item->addr.sin_addr), sslerrmsg); item->errcode = CONTEST_ESSL; item->sslrunning = 0; SSL_free(item->ssldata); SSL_CTX_free(item->sslctx); break; } return; } /* If we get this far, the SSL handshake has completed. So grab the certificate */ peercert = SSL_get_peer_certificate(item->ssldata); if (!peercert) { errprintf("Cannot get peer certificate for %s on host %s\n", portinfo, inet_ntoa(item->addr.sin_addr)); item->errcode = CONTEST_ESSL; item->sslrunning = 0; SSL_free(item->ssldata); SSL_CTX_free(item->sslctx); return; } sslinfo = newstrbuffer(0); certcn = X509_NAME_oneline(X509_get_subject_name(peercert), NULL, 0); certstart = strdup(xymon_ASN1_UTCTIME(X509_get_notBefore(peercert))); certend = strdup(xymon_ASN1_UTCTIME(X509_get_notAfter(peercert))); snprintf(msglin, sizeof(msglin), "Server certificate:\n\tsubject:%s\n\tstart date: %s\n\texpire date:%s\n", certcn, certstart, certend); addtobuffer(sslinfo, msglin); item->certsubject = strdup(certcn); item->certexpires = sslcert_expiretime(certend); xfree(certcn); xfree(certstart); xfree(certend); X509_free(peercert); /* We list the available ciphers in the SSL cert data */ { int i; STACK_OF(SSL_CIPHER) *sk; addtobuffer(sslinfo, "\nAvailable ciphers:\n"); sk = SSL_get_ciphers(item->ssldata); for (i=0; i<sk_SSL_CIPHER_num(sk); i++) { int b1, b2; char *cph; b1 = SSL_CIPHER_get_bits(sk_SSL_CIPHER_value(sk,i), &b2); cph = SSL_CIPHER_get_name(sk_SSL_CIPHER_value(sk,i)); snprintf(msglin, sizeof(msglin), "Cipher %d: %s (%d bits)\n", i, cph, b1); addtobuffer(sslinfo, msglin); if ((item->mincipherbits == 0) || (b1 < item->mincipherbits)) item->mincipherbits = b1; } } item->certinfo = grabstrbuffer(sslinfo); }
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, *www_path = NULL; char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog; double totalTime = 0.0; int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs = 0, ver; long bytes_read = 0, finishtime = 0; OPTION_CHOICE o; #ifdef OPENSSL_SYS_WIN32 int exitNow = 0; /* Set when it's time to exit main */ #endif meth = TLS_client_method(); verify_depth = 0; verify_error = X509_V_OK; 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_depth)) goto opthelp; BIO_printf(bio_err, "%s: verify depth is %d\n", prog, verify_depth); break; case OPT_CERT: certfile = opt_arg(); break; case OPT_KEY: keyfile = opt_arg(); break; case OPT_CAPATH: CApath = opt_arg(); break; case OPT_CAFILE: CAfile = opt_arg(); break; case OPT_CIPHER: cipher = 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(); if (strlen(www_path) > MYBUFSIZ - 100) { BIO_printf(bio_err, "%s: -www option too long\n", prog); goto end; } break; case OPT_SSL3: #ifndef OPENSSL_NO_SSL3 meth = SSLv3_client_method(); #endif break; } } argc = opt_num_rest(); argv = opt_rest(); if (cipher == NULL) cipher = getenv("SSL_CIPHER"); if (cipher == NULL) { BIO_printf(bio_err, "No CIPHER specified\n"); goto end; } if ((ctx = SSL_CTX_new(meth)) == NULL) goto end; SSL_CTX_set_quiet_shutdown(ctx, 1); if (st_bugs) SSL_CTX_set_options(ctx, SSL_OP_ALL); if (!SSL_CTX_set_cipher_list(ctx, cipher)) goto end; if (!set_cert_stuff(ctx, certfile, keyfile)) goto end; if (!ctx_set_verify_locations(ctx, CAfile, CApath)) { 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; #ifdef WIN32_STUFF if (flushWinMsgs(0) == -1) goto end; if (waitingToDie || exitNow) /* we're dead */ goto end; #endif if ((scon = doConnection(NULL, host, ctx)) == NULL) goto end; if (www_path != NULL) { BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", www_path); if (SSL_write(scon, buf, strlen(buf)) <= 0) goto end; while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) bytes_read += i; } #ifdef NO_SHUTDOWN SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); #else SSL_shutdown(scon); #endif SHUTDOWN2(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) { BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", www_path); if (SSL_write(scon, buf, strlen(buf)) <= 0) goto end; while (SSL_read(scon, buf, sizeof(buf)) > 0) continue; } #ifdef NO_SHUTDOWN SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); #else SSL_shutdown(scon); #endif SHUTDOWN2(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; #ifdef WIN32_STUFF if (flushWinMsgs(0) == -1) goto end; if (waitingToDie || exitNow) /* we're dead */ goto end; #endif if ((doConnection(scon, host, ctx)) == NULL) goto end; if (www_path) { BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", www_path); if (SSL_write(scon, buf, strlen(buf)) <= 0) goto end; while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) bytes_read += i; } #ifdef NO_SHUTDOWN SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); #else SSL_shutdown(scon); #endif SHUTDOWN2(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); }
/*********************************************************************** * MAIN - main processing area for client * real name depends on MONOLITH */ int s_time_main(int argc, char **argv) { double totalTime = 0.0; int nConn = 0; SSL *scon = NULL; long finishtime = 0; int ret = 1, i; char buf[1024 * 8]; int ver; s_time_meth = SSLv23_client_method(); verify_depth = 0; verify_error = X509_V_OK; memset(&s_time_config, 0, sizeof(s_time_config)); s_time_config.host = SSL_CONNECT_NAME; s_time_config.maxtime = SECONDS; s_time_config.perform = 3; s_time_config.verify = SSL_VERIFY_NONE; s_time_config.verify_depth = -1; if (options_parse(argc, argv, s_time_options, NULL, NULL) != 0) { s_time_usage(); goto end; } if (s_time_config.verify_depth >= 0) { s_time_config.verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; verify_depth = s_time_config.verify_depth; BIO_printf(bio_err, "verify depth is %d\n", verify_depth); } if (s_time_config.www_path != NULL && strlen(s_time_config.www_path) > MYBUFSIZ - 100) { BIO_printf(bio_err, "-www option too long\n"); goto end; } if ((tm_ctx = SSL_CTX_new(s_time_meth)) == NULL) return (1); SSL_CTX_set_quiet_shutdown(tm_ctx, 1); if (s_time_config.bugs) SSL_CTX_set_options(tm_ctx, SSL_OP_ALL); if (s_time_config.cipher != NULL) { if (!SSL_CTX_set_cipher_list(tm_ctx, s_time_config.cipher)) { BIO_printf(bio_err, "error setting cipher list\n"); ERR_print_errors(bio_err); goto end; } } if (!set_cert_stuff(tm_ctx, s_time_config.certfile, s_time_config.keyfile)) goto end; if ((!SSL_CTX_load_verify_locations(tm_ctx, s_time_config.CAfile, s_time_config.CApath)) || (!SSL_CTX_set_default_verify_paths(tm_ctx))) { /* * BIO_printf(bio_err,"error setting default verify * locations\n"); */ ERR_print_errors(bio_err); /* goto end; */ } if (!(s_time_config.perform & 1)) goto next; printf("Collecting connection statistics for %d seconds\n", s_time_config.maxtime); /* Loop and time how long it takes to make connections */ bytes_read = 0; finishtime = (long) time(NULL) + s_time_config.maxtime; tm_Time_F(START); for (;;) { if (finishtime < (long) time(NULL)) break; if ((scon = doConnection(NULL)) == NULL) goto end; if (s_time_config.www_path != NULL) { int retval = snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", s_time_config.www_path); if ((size_t)retval >= sizeof buf) { fprintf(stderr, "URL too long\n"); goto end; } SSL_write(scon, buf, strlen(buf)); while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) bytes_read += i; } #ifdef NO_SHUTDOWN SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); #else SSL_shutdown(scon); #endif shutdown(SSL_get_fd(scon), SHUT_RDWR); close(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 if (ver == SSL2_VERSION) ver = '2'; 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 + s_time_config.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 + s_time_config.maxtime, bytes_read / nConn); /* * Now loop and time connections using the same session id over and * over */ next: if (!(s_time_config.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)) == NULL) { fprintf(stderr, "Unable to get connection\n"); goto end; } if (s_time_config.www_path != NULL) { int retval = snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", s_time_config.www_path); if ((size_t)retval >= sizeof buf) { fprintf(stderr, "URL too long\n"); goto end; } SSL_write(scon, buf, strlen(buf)); while (SSL_read(scon, buf, sizeof(buf)) > 0); } #ifdef NO_SHUTDOWN SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); #else SSL_shutdown(scon); #endif shutdown(SSL_get_fd(scon), SHUT_RDWR); close(SSL_get_fd(scon)); nConn = 0; totalTime = 0.0; finishtime = (long) time(NULL) + s_time_config.maxtime; printf("starting\n"); bytes_read = 0; tm_Time_F(START); for (;;) { if (finishtime < (long) time(NULL)) break; if ((doConnection(scon)) == NULL) goto end; if (s_time_config.www_path) { int retval = snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", s_time_config.www_path); if ((size_t)retval >= sizeof buf) { fprintf(stderr, "URL too long\n"); goto end; } SSL_write(scon, buf, strlen(buf)); while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) bytes_read += i; } #ifdef NO_SHUTDOWN SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); #else SSL_shutdown(scon); #endif shutdown(SSL_get_fd(scon), SHUT_RDWR); close(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 if (ver == SSL2_VERSION) ver = '2'; 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 + s_time_config.maxtime, bytes_read / nConn); ret = 0; end: if (scon != NULL) SSL_free(scon); if (tm_ctx != NULL) { SSL_CTX_free(tm_ctx); tm_ctx = NULL; } return (ret); }
extern "C" void CryptoNative_SslCtxSetQuietShutdown(SSL_CTX* ctx) { SSL_CTX_set_quiet_shutdown(ctx, 1); }
/* * Create Global context SSL and use it in every new session * * - Load the trusted CAs * - Load the Private key & the certificate * - Set the Context options & Verify options */ static SSL_CTX *init_tls_ctx(EAP_TLS_CONF *conf) { SSL_METHOD *meth; SSL_CTX *ctx; X509_STORE *certstore; int verify_mode = SSL_VERIFY_NONE; int ctx_options = 0; int type; /* * Add all the default ciphers and message digests * Create our context. */ SSL_library_init(); SSL_load_error_strings(); /* * SHA256 is in all versions of OpenSSL, but isn't * initialized by default. It's needed for WiMAX * certificates. */ #ifdef HAVE_OPENSSL_EVP_SHA256 EVP_add_digest(EVP_sha256()); #endif meth = TLSv1_method(); ctx = SSL_CTX_new(meth); /* * Identify the type of certificates that needs to be loaded */ if (conf->file_type) { type = SSL_FILETYPE_PEM; } else { type = SSL_FILETYPE_ASN1; } /* * Set the password to load private key */ if (conf->private_key_password) { #ifdef __APPLE__ /* * We don't want to put the private key password in eap.conf, so check * for our special string which indicates we should get the password * programmatically. */ const char* special_string = "Apple:UseCertAdmin"; if (strncmp(conf->private_key_password, special_string, strlen(special_string)) == 0) { char cmd[256]; const long max_password_len = 128; snprintf(cmd, sizeof(cmd) - 1, "/usr/sbin/certadmin --get-private-key-passphrase \"%s\"", conf->private_key_file); DEBUG2("rlm_eap: Getting private key passphrase using command \"%s\"", cmd); FILE* cmd_pipe = popen(cmd, "r"); if (!cmd_pipe) { radlog(L_ERR, "rlm_eap: %s command failed. Unable to get private_key_password", cmd); radlog(L_ERR, "rlm_eap: Error reading private_key_file %s", conf->private_key_file); return NULL; } free(conf->private_key_password); conf->private_key_password = malloc(max_password_len * sizeof(char)); if (!conf->private_key_password) { radlog(L_ERR, "rlm_eap: Can't malloc space for private_key_password"); radlog(L_ERR, "rlm_eap: Error reading private_key_file %s", conf->private_key_file); pclose(cmd_pipe); return NULL; } fgets(conf->private_key_password, max_password_len, cmd_pipe); pclose(cmd_pipe); /* Get rid of newline at end of password. */ conf->private_key_password[strlen(conf->private_key_password) - 1] = '\0'; DEBUG2("rlm_eap: Password from command = \"%s\"", conf->private_key_password); } #endif SSL_CTX_set_default_passwd_cb_userdata(ctx, conf->private_key_password); SSL_CTX_set_default_passwd_cb(ctx, cbtls_password); } /* * Load our keys and certificates * * If certificates are of type PEM then we can make use * of cert chain authentication using openssl api call * SSL_CTX_use_certificate_chain_file. Please see how * the cert chain needs to be given in PEM from * openSSL.org */ if (type == SSL_FILETYPE_PEM) { if (!(SSL_CTX_use_certificate_chain_file(ctx, conf->certificate_file))) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file); return NULL; } } else if (!(SSL_CTX_use_certificate_file(ctx, conf->certificate_file, type))) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error reading certificate file %s", conf->certificate_file); return NULL; } /* Load the CAs we trust */ if (conf->ca_file || conf->ca_path) { if (!SSL_CTX_load_verify_locations(ctx, conf->ca_file, conf->ca_path)) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error reading Trusted root CA list %s",conf->ca_file ); return NULL; } } if (conf->ca_file && *conf->ca_file) SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(conf->ca_file)); if (!(SSL_CTX_use_PrivateKey_file(ctx, conf->private_key_file, type))) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error reading private key file %s", conf->private_key_file); return NULL; } /* * Check if the loaded private key is the right one */ if (!SSL_CTX_check_private_key(ctx)) { radlog(L_ERR, "rlm_eap_tls: Private key does not match the certificate public key"); return NULL; } /* * Set ctx_options */ ctx_options |= SSL_OP_NO_SSLv2; ctx_options |= SSL_OP_NO_SSLv3; #ifdef SSL_OP_NO_TICKET ctx_options |= SSL_OP_NO_TICKET ; #endif /* * SSL_OP_SINGLE_DH_USE must be used in order to prevent * small subgroup attacks and forward secrecy. Always * using * * SSL_OP_SINGLE_DH_USE has an impact on the computer * time needed during negotiation, but it is not very * large. */ ctx_options |= SSL_OP_SINGLE_DH_USE; /* * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS to work around issues * in Windows Vista client. * http://www.openssl.org/~bodo/tls-cbc.txt * http://www.nabble.com/(RADIATOR)-Radiator-Version-3.16-released-t2600070.html */ ctx_options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; SSL_CTX_set_options(ctx, ctx_options); /* * TODO: Set the RSA & DH * SSL_CTX_set_tmp_rsa_callback(ctx, cbtls_rsa); * SSL_CTX_set_tmp_dh_callback(ctx, cbtls_dh); */ /* * set the message callback to identify the type of * message. For every new session, there can be a * different callback argument. * * SSL_CTX_set_msg_callback(ctx, cbtls_msg); */ /* Set Info callback */ SSL_CTX_set_info_callback(ctx, cbtls_info); /* * Callbacks, etc. for session resumption. */ if (conf->session_cache_enable) { SSL_CTX_sess_set_new_cb(ctx, cbtls_new_session); SSL_CTX_sess_set_get_cb(ctx, cbtls_get_session); SSL_CTX_sess_set_remove_cb(ctx, cbtls_remove_session); SSL_CTX_set_quiet_shutdown(ctx, 1); } /* * Check the certificates for revocation. */ #ifdef X509_V_FLAG_CRL_CHECK if (conf->check_crl) { certstore = SSL_CTX_get_cert_store(ctx); if (certstore == NULL) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error reading Certificate Store"); return NULL; } X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); } #endif /* * Set verify modes * Always verify the peer certificate */ verify_mode |= SSL_VERIFY_PEER; verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; verify_mode |= SSL_VERIFY_CLIENT_ONCE; SSL_CTX_set_verify(ctx, verify_mode, cbtls_verify); if (conf->verify_depth) { SSL_CTX_set_verify_depth(ctx, conf->verify_depth); } /* Load randomness */ if (!(RAND_load_file(conf->random_file, 1024*1024))) { radlog(L_ERR, "rlm_eap: SSL error %s", ERR_error_string(ERR_get_error(), NULL)); radlog(L_ERR, "rlm_eap_tls: Error loading randomness"); return NULL; } /* * Set the cipher list if we were told to */ if (conf->cipher_list) { if (!SSL_CTX_set_cipher_list(ctx, conf->cipher_list)) { radlog(L_ERR, "rlm_eap_tls: Error setting cipher list"); return NULL; } } /* * Setup session caching */ if (conf->session_cache_enable) { /* * Create a unique context Id per EAP-TLS configuration. */ if (conf->session_id_name) { snprintf(conf->session_context_id, sizeof(conf->session_context_id), "FreeRADIUS EAP-TLS %s", conf->session_id_name); } else { snprintf(conf->session_context_id, sizeof(conf->session_context_id), "FreeRADIUS EAP-TLS %p", conf); } /* * Cache it, and DON'T auto-clear it. */ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_AUTO_CLEAR); SSL_CTX_set_session_id_context(ctx, (unsigned char *) conf->session_context_id, (unsigned int) strlen(conf->session_context_id)); /* * Our timeout is in hours, this is in seconds. */ SSL_CTX_set_timeout(ctx, conf->session_timeout * 3600); /* * Set the maximum number of entries in the * session cache. */ SSL_CTX_sess_set_cache_size(ctx, conf->session_cache_size); } else { SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); } /* * Register the application indices. We can't use * hard-coded "0" and "1" as before, because we need to * set up a "free" handler for the cached session * information. */ if (eaptls_handle_idx < 0) { eaptls_handle_idx = SSL_get_ex_new_index(0, &eaptls_handle_idx, NULL, NULL, NULL); } if (eaptls_conf_idx < 0) { eaptls_conf_idx = SSL_get_ex_new_index(0, &eaptls_conf_idx, NULL, NULL, NULL); } if (eaptls_store_idx < 0) { eaptls_store_idx = SSL_get_ex_new_index(0, "eaptls_store_idx", NULL, NULL, NULL); } if (eaptls_session_idx < 0) { eaptls_session_idx = SSL_get_ex_new_index(0, &eaptls_session_idx, NULL, NULL, eaptls_session_free); } return ctx; }
int MAIN(int argc, char **argv) { double totalTime = 0.0; int nConn = 0; SSL *scon = NULL; long finishtime = 0; int ret = 1, i; char buf[1024 * 8]; int ver; apps_startup(); s_time_init(); if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); s_time_meth = SSLv23_client_method(); /* parse the command line arguments */ if (parseArgs(argc, argv) < 0) goto end; OpenSSL_add_ssl_algorithms(); if ((tm_ctx = SSL_CTX_new(s_time_meth)) == NULL) return (1); SSL_CTX_set_quiet_shutdown(tm_ctx, 1); if (st_bugs) SSL_CTX_set_options(tm_ctx, SSL_OP_ALL); if(!SSL_CTX_set_cipher_list(tm_ctx, tm_cipher)) goto end; if (!set_cert_stuff(tm_ctx, t_cert_file, t_key_file)) goto end; SSL_load_error_strings(); if ((!SSL_CTX_load_verify_locations(tm_ctx, CAfile, CApath)) || (!SSL_CTX_set_default_verify_paths(tm_ctx))) { /* * BIO_printf(bio_err,"error setting default verify locations\n"); */ ERR_print_errors(bio_err); /* goto end; */ } if (tm_cipher == NULL) tm_cipher = getenv("SSL_CIPHER"); if (tm_cipher == NULL) { fprintf(stderr, "No CIPHER specified\n"); } 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; #ifdef WIN32_STUFF if (flushWinMsgs(0) == -1) goto end; if (waitingToDie || exitNow) /* we're dead */ goto end; #endif if ((scon = doConnection(NULL)) == NULL) goto end; if (s_www_path != NULL) { BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", s_www_path); if(SSL_write(scon, buf, strlen(buf)) <= 0) goto end; while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) bytes_read += i; } #ifdef NO_SHUTDOWN SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); #else SSL_shutdown(scon); #endif SHUTDOWN2(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)) == NULL) { fprintf(stderr, "Unable to get connection\n"); goto end; } if (s_www_path != NULL) { BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", s_www_path); if(SSL_write(scon, buf, strlen(buf)) <= 0) goto end; while (SSL_read(scon, buf, sizeof(buf)) > 0) ; } #ifdef NO_SHUTDOWN SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); #else SSL_shutdown(scon); #endif SHUTDOWN2(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; #ifdef WIN32_STUFF if (flushWinMsgs(0) == -1) goto end; if (waitingToDie || exitNow) /* we're dead */ goto end; #endif if ((doConnection(scon)) == NULL) goto end; if (s_www_path) { BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", s_www_path); if(SSL_write(scon, buf, strlen(buf)) <= 0) goto end; while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) bytes_read += i; } #ifdef NO_SHUTDOWN SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); #else SSL_shutdown(scon); #endif SHUTDOWN2(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?nConn:1)); ret = 0; end: if (scon != NULL) SSL_free(scon); if (tm_ctx != NULL) { SSL_CTX_free(tm_ctx); tm_ctx = NULL; } apps_shutdown(); OPENSSL_EXIT(ret); }
int MaOpenSslConfig::start() { const SSL_METHOD *meth; char *hostName; if (keyFile == 0) { mprError(MPR_L, MPR_LOG, "OpenSSL: Cant start SSL: missing key file"); return MPR_ERR_CANT_INITIALIZE; } if (certFile == 0) { mprError(MPR_L, MPR_LOG, "OpenSSL: Cant start SSL: missing certificate file"); return MPR_ERR_CANT_INITIALIZE; } // // Depending on the order in the configuration file, we may get called // by sslModule::start() before OpenSslModule::start has run. So we // must initialize here. // openSslModule->start(); hostName = host->getName(); if (protocols == MPR_HTTP_PROTO_SSLV2) { meth = SSLv2_server_method(); } else { meth = SSLv23_server_method(); } context = SSL_CTX_new(meth); mprAssert(context); if (context == 0) { mprError(MPR_L, MPR_LOG, "OpenSSL: Unable to create SSL context"); return MPR_ERR_CANT_CREATE; } SSL_CTX_set_app_data(context, (void*) this); SSL_CTX_set_quiet_shutdown(context, 1); SSL_CTX_sess_set_cache_size(context, 512); // // Configure the certificate for this host // if (configureCertificates(context, keyFile, certFile) != 0) { SSL_CTX_free(context); context = 0; return MPR_ERR_CANT_INITIALIZE; } mprLog(4, "SSL: %s: Using ciphers %s\n", hostName, ciphers); SSL_CTX_set_cipher_list(context, ciphers); // // Configure the client verification certificate locations // if (verifyClient) { if (caFile == 0 && caPath == 0) { mprError(MPR_L, MPR_LOG, "OpenSSL: Must define CA certificates if using client verification"); SSL_CTX_free(context); context = 0; return MPR_ERR_BAD_STATE; } if (caFile || caPath) { if ((!SSL_CTX_load_verify_locations(context, caFile, caPath)) || (!SSL_CTX_set_default_verify_paths(context))) { mprError(MPR_L, MPR_LOG, "OpenSSL: Unable to set certificate locations"); SSL_CTX_free(context); context = 0; return MPR_ERR_CANT_ACCESS; } if (caFile) { STACK_OF(X509_NAME) *certNames; certNames = SSL_load_client_CA_file(caFile); if (certNames == 0) { } else { // // Define the list of CA certificates to send to the client // before they send their client certificate for validation // SSL_CTX_set_client_CA_list(context, certNames); } } } mprLog(4, "SSL: %s: is verifying client connections\n", hostName); if (caFile) { mprLog(4, "SSL: %s: Using certificates from %s\n", hostName, caFile); } else if (caPath) { mprLog(4, "SSL: %s: Using certificates from directory %s\n", hostName, caPath); } SSL_CTX_set_verify(context, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verifyX509Certificate); SSL_CTX_set_verify_depth(context, verifyDepth); } else { SSL_CTX_set_verify(context, SSL_VERIFY_NONE, verifyX509Certificate); } // // Define callbacks // SSL_CTX_set_tmp_rsa_callback(context, rsaCallback); SSL_CTX_set_tmp_dh_callback(context, dhCallback); // // Enable all buggy client work-arounds // SSL_CTX_set_options(context, SSL_OP_ALL); #ifdef SSL_OP_NO_TICKET SSL_CTX_set_options(context, SSL_OP_NO_TICKET); #endif #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION SSL_CTX_set_options(context, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); #endif SSL_CTX_set_mode(context, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_AUTO_RETRY); // // Select the required protocols // SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); if (!(protocols & MPR_HTTP_PROTO_SSLV3)) { SSL_CTX_set_options(context, SSL_OP_NO_SSLv3); mprLog(4, "SSL: %s: Disabling SSLv3\n", hostName); } if (!(protocols & MPR_HTTP_PROTO_TLSV1)) { SSL_CTX_set_options(context, SSL_OP_NO_TLSv1); mprLog(4, "SSL: %s: Disabling TLSv1\n", hostName); } // // Ensure we generate a new private key for each connection // SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE); // // Pre-generate some keys that are slow to compute // rsaKey512 = RSA_generate_key(512, RSA_F4, 0, 0); rsaKey1024 = RSA_generate_key(1024, RSA_F4, 0, 0); dhKey512 = get_dh512(); dhKey1024 = get_dh1024(); return 0; }
/* * Start up the SSL Context for the application, and start a listen on the * SSL port (usually 443, and defined by SSL_PORT) * Return 0 on success, -1 on failure. */ int websSSLOpen() { char *certFile, *keyFile, *CApath, *CAfile; SSL_METHOD *meth; /* * Install and initialize the SSL library */ apps_startup(); printf("ssl.c: SSL: Initializing SSL\n"); SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); /* * Important! Enable both SSL versions 2 and 3 */ meth = SSLv23_server_method(); sslctx = SSL_CTX_new(meth); if (sslctx == NULL) { printf("SSL: Unable to create SSL context!\n"); return -1; } /* * Adjust some SSL Context variables */ SSL_CTX_set_quiet_shutdown(sslctx, 1); SSL_CTX_set_options(sslctx, 0); SSL_CTX_sess_set_cache_size(sslctx, 128); /* * Set the certificate verification locations */ CApath = DEFAULT_CA_PATH; CAfile = DEFAULT_CA_FILE; if ((!SSL_CTX_load_verify_locations(sslctx, CAfile, CApath)) || (!SSL_CTX_set_default_verify_paths(sslctx))) { printf("SSL: Unable to set cert verification locations!\n"); websSSLClose(); return -1; } /* * Setting up certificates for the SSL server. * Set the certificate and key files for the SSL context. */ certFile = DEFAULT_CERT_FILE; keyFile = NULL; if (websSSLSetCertStuff(sslctx, certFile, keyFile) != 0) { websSSLClose(); return -1; } /* * Set the RSA callback for the SSL context */ SSL_CTX_set_tmp_rsa_callback(sslctx, websSSLTempRSACallback); /* * Set the verification callback for the SSL context */ SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, websSSLVerifyCallback); /* * Set the certificate authority list for the client */ SSL_CTX_set_client_CA_list(sslctx, SSL_load_client_CA_file(CAfile)); /* * Open the socket */ sslListenSock = socketOpenConnection(NULL, SSL_PORT, websSSLAccept, SOCKET_BLOCK); if (sslListenSock < 0) { trace(2, T("SSL: Unable to open SSL socket on port <%d>!\n"), SSL_PORT); return -1; } return 0; }