/* Init library and load specified certificate. * Establishes a SSL_ctx, to act as a template for * each connection */ static SSL_CTX * init_openssl() { SSL_library_init(); SSL_load_error_strings(); SSL_CTX *ctx = NULL; if (OPTIONS.ETYPE == ENC_TLS) ctx = SSL_CTX_new(TLSv1_server_method()); else if (OPTIONS.ETYPE == ENC_SSL) ctx = SSL_CTX_new(SSLv23_server_method()); else assert(OPTIONS.ETYPE == ENC_TLS || OPTIONS.ETYPE == ENC_SSL); SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); if (SSL_CTX_use_certificate_file(ctx, OPTIONS.CERT_FILE, SSL_FILETYPE_PEM) <= 0) ERR_print_errors_fp(stderr); if (SSL_CTX_use_RSAPrivateKey_file(ctx, OPTIONS.CERT_FILE, SSL_FILETYPE_PEM) <= 0) ERR_print_errors_fp(stderr); if (OPTIONS.CIPHER_SUITE) if (SSL_CTX_set_cipher_list(ctx, OPTIONS.CIPHER_SUITE) != 1) ERR_print_errors_fp(stderr); return ctx; }
void TlsThread::setup() { SSL_load_error_strings(); SSL_library_init(); ctx = ::SSL_CTX_new( SSLv23_server_method() ); int options = SSL_OP_ALL // also try to pick the same ciphers suites more often | SSL_OP_CIPHER_SERVER_PREFERENCE // and don't use SSLv2, even if the client wants to | SSL_OP_NO_SSLv2 ; SSL_CTX_set_options( ctx, options ); SSL_CTX_set_cipher_list( ctx, "kEDH:HIGH:!aNULL:!MD5" ); EString keyFile( Configuration::text( Configuration::TlsCertFile ) ); if ( keyFile.isEmpty() ) { keyFile = Configuration::compiledIn( Configuration::LibDir ); keyFile.append( "/automatic-key.pem" ); } keyFile = File::chrooted( keyFile ); if ( !SSL_CTX_use_certificate_chain_file( ctx, keyFile.cstr() ) || !SSL_CTX_use_RSAPrivateKey_file( ctx, keyFile.cstr(), SSL_FILETYPE_PEM ) ) log( "OpenSSL needs both the certificate and " "private key in this file: " + keyFile, Log::Disaster ); // we go on anyway; the disaster will take down the server in // a hurry. // we don't ask for a client cert SSL_CTX_set_verify( ctx, SSL_VERIFY_NONE, NULL ); }
boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file) { int connection_status; tls->ctx = SSL_CTX_new(SSLv23_server_method()); if (tls->ctx == NULL) { printf("SSL_CTX_new failed\n"); return false; } /* * We only want SSLv3 and TLSv1, so disable SSLv2. * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ SSL_CTX_set_options(tls->ctx, SSL_OP_NO_SSLv2); if (SSL_CTX_use_RSAPrivateKey_file(tls->ctx, privatekey_file, SSL_FILETYPE_PEM) <= 0) { printf("SSL_CTX_use_RSAPrivateKey_file failed\n"); return false; } tls->ssl = SSL_new(tls->ctx); if (tls->ssl == NULL) { printf("SSL_new failed\n"); return false; } if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0) { printf("SSL_use_certificate_file failed\n"); return false; } if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) { printf("SSL_set_fd failed\n"); return false; } connection_status = SSL_accept(tls->ssl); if (connection_status <= 0) { if (tls_print_error("SSL_accept", tls->ssl, connection_status)) return false; } printf("TLS connection accepted\n"); return true; }
as_status as_tls_config_reload(as_config_tls* tlscfg, as_tls_context* ctx, as_error *err) { if (ctx == NULL || ctx->ssl_ctx == NULL) { return as_error_update(err, AEROSPIKE_ERR_TLS_ERROR, "TLS not enabled"); } pthread_mutex_lock(&ctx->lock); if (tlscfg->certfile && SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, tlscfg->certfile) != 1 && ERR_peek_error() != SSL_ERROR_NONE) { pthread_mutex_unlock(&ctx->lock); char buff[1000]; ERR_error_string_n(ERR_get_error(), buff, sizeof(buff)); return as_error_update(err, AEROSPIKE_ERR_TLS_ERROR, "Failed to reload certificate file %s: %s", tlscfg->certfile, buff); } if (tlscfg->keyfile && SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx, tlscfg->keyfile, SSL_FILETYPE_PEM) != 1) { pthread_mutex_unlock(&ctx->lock); char buff[1000]; ERR_error_string_n(ERR_get_error(), buff, sizeof(buff)); return as_error_update(err, AEROSPIKE_ERR_TLS_ERROR, "Failed to reload private key file %s: %s", tlscfg->keyfile, buff); } if (tlscfg->cert_blacklist) { void *new_cbl = cert_blacklist_read(tlscfg->cert_blacklist); if (! new_cbl) { pthread_mutex_unlock(&ctx->lock); return as_error_update(err, AEROSPIKE_ERR_TLS_ERROR, "Failed to reload certificate blacklist %s", tlscfg->cert_blacklist); } cert_blacklist_destroy(ctx->cert_blacklist); ctx->cert_blacklist = new_cbl; } pthread_mutex_unlock(&ctx->lock); return AEROSPIKE_OK; }
::PmSockSSLContext* UtilMakeServerSSLCtx(const std::string& rPrivkeyPath, const char* const userLabel) { if (rPrivkeyPath.empty()) { const std::string errorMsg = std::string(__func__) + "ERROR: private key path string is empty"; UTIL_THROW_FATAL(userLabel, errorMsg.c_str()); } UtilPmSockSSLCtxRAII pmctx; pmctx.pCtx = UtilMakeSSLCtx(userLabel); struct ssl_ctx_st* opensslctx = PmSockSSLCtxPeekOpensslContext(pmctx.pCtx); assert(opensslctx); const char* ssl_func_name; ssl_func_name = "SSL_CTX_use_RSAPrivateKey_file()"; int sslres = SSL_CTX_use_RSAPrivateKey_file(opensslctx, rPrivkeyPath.c_str(), SSL_FILETYPE_PEM); if (1 == sslres) { ssl_func_name = "SSL_CTX_use_certificate_file()"; sslres = SSL_CTX_use_certificate_file(opensslctx, rPrivkeyPath.c_str(), SSL_FILETYPE_PEM); } if (1 == sslres) { ssl_func_name = "SSL_CTX_check_private_key()"; sslres = SSL_CTX_check_private_key(opensslctx); } if (sslres != 1) { unsigned long opensslErr = 0; std::ostringstream oss; oss << __func__ << ": ERROR: " << ssl_func_name; oss << "failed (privkeyPath=" << rPrivkeyPath << "): "; while ((opensslErr = ::ERR_get_error()) != 0) { char errText[120]; ///< openssl doc recommends 120 bytes ERR_error_string_n(opensslErr, errText, sizeof(errText)); oss << errText << "; "; } UTIL_THROW_FATAL(userLabel, oss.str().c_str()); } return pmctx.Release(); }//UtilMakeServerSSLCtx
void SSLContext::rsaPrivateKeyfile(const String &file, int type){ switch(type){ case KEYFILE_DEFAULT: if(!SSL_CTX_use_RSAPrivateKey_file((SSL_CTX *)ctx, file.toCharPtr(), X509_FILETYPE_DEFAULT)) throw KeyfileUnreadable(); break; case KEYFILE_ASN1: #ifdef USE_DEBUG debugmsgln(this, "Loading RSA private key file in ASN1 format"); #endif if(!SSL_CTX_use_RSAPrivateKey_file((SSL_CTX *)ctx, file.toCharPtr(), X509_FILETYPE_ASN1)) throw KeyfileUnreadable(); break; default: case KEYFILE_PEM: #ifdef USE_DEBUG debugmsgln(this, "Loading RSA private key file in PEM format"); #endif if(!SSL_CTX_use_RSAPrivateKey_file((SSL_CTX *)ctx, file.toCharPtr(), X509_FILETYPE_PEM)) throw KeyfileUnreadable(); break; } }
tbool tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file) { int connection_status; tls->ctx = SSL_CTX_new(TLSv1_server_method()); if (tls->ctx == NULL) { printf("SSL_CTX_new failed\n"); return false; } if (SSL_CTX_use_RSAPrivateKey_file(tls->ctx, privatekey_file, SSL_FILETYPE_PEM) <= 0) { printf("SSL_CTX_use_RSAPrivateKey_file failed\n"); return false; } tls->ssl = SSL_new(tls->ctx); if (tls->ssl == NULL) { printf("SSL_new failed\n"); return false; } if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0) { printf("SSL_use_certificate_file failed\n"); return false; } if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) { printf("SSL_set_fd failed\n"); return false; } connection_status = SSL_accept(tls->ssl); if (connection_status <= 0) { if (tls_print_error("SSL_accept", tls->ssl, connection_status)) return false; } printf("TLS connection accepted\n"); return true; }
PmSockSSLContext* UtilMakeServerSSLContext(const char * userLabel, const std::string& privateKeyPath) { //checks if private key is empty, we don't need this if (privateKeyPath.empty()) { UTIL_THROW_FATAL(userLabel, "ERROR: private key path string is empty"); } PmSockSSLCtxRAII pmContext; pmContext.pCtx_ = UtilMakeSSLContext(userLabel); //get the SSL_CTX out of palmsocket ssl context SSL_CTX* pOpenSSLContext = PmSockSSLCtxPeekOpensslContext(pmContext.pCtx_); assert(pOpenSSLContext); const char* ssl_func_name; ssl_func_name = "SSL_CTX_use_RSAPrivateKey_file()"; int sslres = SSL_CTX_use_RSAPrivateKey_file(pOpenSSLContext, privateKeyPath.c_str(), SSL_FILETYPE_PEM); if (1==sslres) { ssl_func_name = "SSL_CTX_use_certificate_file()"; sslres = SSL_CTX_use_certificate_file(pOpenSSLContext, privateKeyPath.c_str(), SSL_FILETYPE_PEM); } if (1==sslres) { ssl_func_name = "SSL_CTX_check_private_key()"; sslres = SSL_CTX_check_private_key(pOpenSSLContext); } if (sslres != 1) { unsigned long opensslErr = 0; std::ostringstream oss; oss << __func__ << ": ERROR: " << ssl_func_name; oss << " failed (privateKeyPath=" << privateKeyPath << "): "; while ((opensslErr = ::ERR_get_error()) != 0) { char errText[120]; ///< openssl doc recommends 120 bytes ERR_error_string_n(opensslErr, errText, sizeof(errText)); oss << errText << "; "; } UTIL_THROW_FATAL(userLabel, oss.str().c_str()); } return pmContext.Release(); }
/* Init library and load specified certificate. * Establishes a SSL_ctx, to act as a template for * each connection */ static SSL_CTX * init_openssl() { SSL_library_init(); SSL_load_error_strings(); SSL_CTX *ctx = NULL; long ssloptions = SSL_OP_NO_SSLv2 | SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION; if (OPTIONS.ETYPE == ENC_TLS) ctx = SSL_CTX_new(TLSv1_server_method()); else if (OPTIONS.ETYPE == ENC_SSL) ctx = SSL_CTX_new(SSLv23_server_method()); else assert(OPTIONS.ETYPE == ENC_TLS || OPTIONS.ETYPE == ENC_SSL); #ifdef SSL_OP_NO_COMPRESSION ssloptions |= SSL_OP_NO_COMPRESSION; #endif SSL_CTX_set_options(ctx, ssloptions); if (SSL_CTX_use_certificate_chain_file(ctx, OPTIONS.CERT_FILE) <= 0) { ERR_print_errors_fp(stderr); exit(1); } if (SSL_CTX_use_RSAPrivateKey_file(ctx, OPTIONS.CERT_FILE, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(1); } #ifndef OPENSSL_NO_DH init_dh(ctx, OPTIONS.CERT_FILE); #endif /* OPENSSL_NO_DH */ if (OPTIONS.CIPHER_SUITE) if (SSL_CTX_set_cipher_list(ctx, OPTIONS.CIPHER_SUITE) != 1) ERR_print_errors_fp(stderr); #ifdef USE_SHARED_CACHE if (OPTIONS.SHARED_CACHE) { if (shared_context_init(ctx, OPTIONS.SHARED_CACHE) < 0) { ERR("Unable to alloc memory for shared cache.\n"); exit(1); } } #endif return ctx; }
/* cr_load_certs : loads private key and certificates from files * if cert_file and key_file are NULL , the function will generate * a dynamic certificate and private key */ void cr_load_certs(SSL_CTX *ssl,u_char *cert_file,u_char *key_file) { X509 *cert = NULL; EVP_PKEY *pkey = NULL; if(cert_file == NULL || key_file == NULL) { /* generate a public certificate and a private key */ cr_make_cert(&cert,&pkey,2048,0,365); SSL_CTX_use_certificate(ssl, cert); SSL_CTX_use_PrivateKey(ssl, pkey); #ifdef CR_MK_CERT RSA_print_fp(stdout,pkey->pkey.rsa,0); X509_print_fp(stdout,cert); PEM_write_PrivateKey(stdout,pkey,NULL,NULL,0,NULL, NULL); PEM_write_X509(stdout,cert); #endif } else { if (SSL_CTX_use_certificate_file(ssl, (const char*)cert_file, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(3); } if (SSL_CTX_use_RSAPrivateKey_file(ssl, (const char*)key_file, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(4); } } if (!SSL_CTX_check_private_key(ssl)) { perrx("Private key does not match the certificate public key\n"); exit(5); } }
void OpenSSLBase::setClientCert( const std::string& clientKey, const std::string& clientCerts ) { m_clientKey = clientKey; m_clientCerts = clientCerts; if( !m_clientKey.empty() && !m_clientCerts.empty() ) { if( SSL_CTX_use_certificate_chain_file( m_ctx, m_clientCerts.c_str() ) != 1 ) { // FIXME } if( SSL_CTX_use_RSAPrivateKey_file( m_ctx, m_clientKey.c_str(), SSL_FILETYPE_PEM ) != 1 ) { // FIXME } } if ( SSL_CTX_check_private_key( m_ctx ) != 1 ) { // FIXME } }
static int load_certificate(struct openconnect_info *vpninfo) { if (!strncmp(vpninfo->sslkey, "pkcs11:", 7) || !strncmp(vpninfo->cert, "pkcs11:", 7)) { vpn_progress(vpninfo, PRG_ERR, _("This binary built without PKCS#11 support\n")); return -EINVAL; } vpn_progress(vpninfo, PRG_TRACE, _("Using certificate file %s\n"), vpninfo->cert); if (strncmp(vpninfo->cert, "keystore:", 9) && (vpninfo->cert_type == CERT_TYPE_PKCS12 || vpninfo->cert_type == CERT_TYPE_UNKNOWN)) { FILE *f; PKCS12 *p12; f = fopen(vpninfo->cert, "r"); if (!f) { vpn_progress(vpninfo, PRG_ERR, _("Failed to open certificate file %s: %s\n"), vpninfo->cert, strerror(errno)); return -ENOENT; } p12 = d2i_PKCS12_fp(f, NULL); fclose(f); if (p12) return load_pkcs12_certificate(vpninfo, p12); /* Not PKCS#12 */ if (vpninfo->cert_type == CERT_TYPE_PKCS12) { vpn_progress(vpninfo, PRG_ERR, _("Read PKCS#12 failed\n")); openconnect_report_ssl_errors(vpninfo); return -EINVAL; } /* Clear error and fall through to see if it's a PEM file... */ ERR_clear_error(); } /* It's PEM or TPM now, and either way we need to load the plain cert: */ #ifdef ANDROID_KEYSTORE if (!strncmp(vpninfo->cert, "keystore:", 9)) { BIO *b = BIO_from_keystore(vpninfo, vpninfo->cert); if (!b) return -EINVAL; vpninfo->cert_x509 = PEM_read_bio_X509_AUX(b, NULL, pem_pw_cb, vpninfo); BIO_free(b); if (!vpninfo->cert_x509) { vpn_progress(vpninfo, PRG_ERR, _("Failed to load X509 certificate from keystore\n")); openconnect_report_ssl_errors(vpninfo); return -EINVAL; } if (!SSL_CTX_use_certificate(vpninfo->https_ctx, vpninfo->cert_x509)) { vpn_progress(vpninfo, PRG_ERR, _("Failed to use X509 certificate from keystore\n")); openconnect_report_ssl_errors(vpninfo); X509_free(vpninfo->cert_x509); vpninfo->cert_x509 = NULL; return -EINVAL; } } else #endif /* ANDROID_KEYSTORE */ { if (!SSL_CTX_use_certificate_chain_file(vpninfo->https_ctx, vpninfo->cert)) { vpn_progress(vpninfo, PRG_ERR, _("Loading certificate failed\n")); openconnect_report_ssl_errors(vpninfo); return -EINVAL; } /* Ew, we can't get it back from the OpenSSL CTX in any sane fashion */ reload_pem_cert(vpninfo); } #ifdef ANDROID_KEYSTORE if (!strncmp(vpninfo->sslkey, "keystore:", 9)) { EVP_PKEY *key; BIO *b; again_android: b = BIO_from_keystore(vpninfo, vpninfo->sslkey); if (!b) return -EINVAL; key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, vpninfo); BIO_free(b); if (!key) { if (is_pem_password_error(vpninfo)) goto again_android; return -EINVAL; } if (!SSL_CTX_use_PrivateKey(vpninfo->https_ctx, key)) { vpn_progress(vpninfo, PRG_ERR, _("Failed to use private key from keystore\n")); EVP_PKEY_free(key); X509_free(vpninfo->cert_x509); vpninfo->cert_x509 = NULL; return -EINVAL; } return 0; } #endif /* ANDROID_KEYSTORE */ if (vpninfo->cert_type == CERT_TYPE_UNKNOWN) { FILE *f = fopen(vpninfo->sslkey, "r"); char buf[256]; if (!f) { vpn_progress(vpninfo, PRG_ERR, _("Failed to open private key file %s: %s\n"), vpninfo->cert, strerror(errno)); return -ENOENT; } buf[255] = 0; while (fgets(buf, 255, f)) { if (!strcmp(buf, "-----BEGIN TSS KEY BLOB-----\n")) { vpninfo->cert_type = CERT_TYPE_TPM; break; } else if (!strcmp(buf, "-----BEGIN RSA PRIVATE KEY-----\n") || !strcmp(buf, "-----BEGIN DSA PRIVATE KEY-----\n") || !strcmp(buf, "-----BEGIN ENCRYPTED PRIVATE KEY-----\n")) { vpninfo->cert_type = CERT_TYPE_PEM; break; } } fclose(f); if (vpninfo->cert_type == CERT_TYPE_UNKNOWN) { vpn_progress(vpninfo, PRG_ERR, _("Failed to identify private key type in '%s'\n"), vpninfo->sslkey); return -EINVAL; } } if (vpninfo->cert_type == CERT_TYPE_TPM) return load_tpm_certificate(vpninfo); /* Standard PEM certificate */ SSL_CTX_set_default_passwd_cb(vpninfo->https_ctx, pem_pw_cb); SSL_CTX_set_default_passwd_cb_userdata(vpninfo->https_ctx, vpninfo); again: if (!SSL_CTX_use_RSAPrivateKey_file(vpninfo->https_ctx, vpninfo->sslkey, SSL_FILETYPE_PEM)) { if (is_pem_password_error(vpninfo)) goto again; return -EINVAL; } return 0; }
boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file) { CryptoCert cert; long options = 0; int connection_status; tls->ctx = SSL_CTX_new(SSLv23_server_method()); if (tls->ctx == NULL) { printf("SSL_CTX_new failed\n"); return false; } /* * SSL_OP_NO_SSLv2: * * We only want SSLv3 and TLSv1, so disable SSLv2. * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ options |= SSL_OP_NO_SSLv2; /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; SSL_CTX_set_options(tls->ctx, options); if (SSL_CTX_use_RSAPrivateKey_file(tls->ctx, privatekey_file, SSL_FILETYPE_PEM) <= 0) { printf("SSL_CTX_use_RSAPrivateKey_file failed\n"); return false; } tls->ssl = SSL_new(tls->ctx); if (tls->ssl == NULL) { printf("SSL_new failed\n"); return false; } if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0) { printf("SSL_use_certificate_file failed\n"); return false; } cert = tls_get_certificate(tls, false); if (cert == NULL) { printf("tls_connect: tls_get_certificate failed to return the server certificate.\n"); return false; } if (!crypto_cert_get_public_key(cert, &tls->public_key)) { printf("tls_connect: crypto_cert_get_public_key failed to return the server public key.\n"); tls_free_certificate(cert); return false; } xfree(cert); if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) { printf("SSL_set_fd failed\n"); return false; } while (1) { connection_status = SSL_accept(tls->ssl); if (connection_status <= 0) { switch (SSL_get_error(tls->ssl, connection_status)) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: break; default: if (tls_print_error("SSL_accept", tls->ssl, connection_status)) return false; break; } } else { break; } } printf("TLS connection accepted\n"); return true; }
static void SSLInfoCallback(const SSL *s, int where, int ret) { #else static void SSLInfoCallback(SSL *s, int where, int ret) { #endif if(where & SSL_CB_LOOP) printf("SSL state (%s): %s\r\n", where & SSL_ST_CONNECT ? "connect" : where & SSL_ST_ACCEPT ? "accept" : "undefined", SSL_state_string_long(s)); else if(where & SSL_CB_ALERT) printf("SSL alert (%s): %s: %s\r\n", where & SSL_CB_READ ? "read" : "write", SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret)); else if(where==SSL_CB_HANDSHAKE_DONE) print_stats(); else if (where & SSL_CB_EXIT) { if (ret == 0) printf("%failed in %s\r\n", SSL_state_string_long(s)); } } #endif /*DEBUG_SSL*/ static void CDECL LockSSL(int iMode, int iType, const char* pszFileName, int iLine) { if(iMode & CRYPTO_LOCK) { #ifdef _WIN32 EnterCriticalSection(&lock); #else pthread_mutex_lock(&lock); #endif } else { if(iMode & CRYPTO_UNLOCK) { #ifdef _WIN32 LeaveCriticalSection(&lock); #else pthread_mutex_unlock(&lock); #endif } } } SSL_CTX* SSLMakeCtx(const SSLOptions& sslOpt, int iServer) { SSL_CTX* pSSLCtx; if(iServer) { pSSLCtx = SSL_CTX_new(SSLv23_server_method()); } else { pSSLCtx = SSL_CTX_new(SSLv23_client_method()); } if(!pSSLCtx) { SysLogMessage(LOG_LEV_ERROR, "Cannot create SSL context, ssl support is disabled\r\n"); return (NULL); } int iSSLOpt = SSL_OP_ALL; #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS iSSLOpt |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; #endif SSL_CTX_set_options(pSSLCtx, iSSLOpt); #if SSLEAY_VERSION_NUMBER >= 0x00906000L SSL_CTX_set_mode(pSSLCtx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); #endif /* OpenSSL-0.9.6 */ /* SSL_CTX_set_session_cache_mode(pSSLCtx, SSL_SESS_CACHE_OFF); */ SSL_CTX_set_session_cache_mode(pSSLCtx, SSL_SESS_CACHE_BOTH); SSL_CTX_sess_set_cache_size(pSSLCtx, 128); if(!sslOpt.pszCertFile) { SysLogMessage(LOG_LEV_ERROR, "Certificate file not found, ssl support is disabled\r\n"); SSL_CTX_free(pSSLCtx); return (NULL); } if(!SSL_CTX_use_certificate_chain_file(pSSLCtx, sslOpt.pszCertFile)) { SysLogMessage(LOG_LEV_ERROR, "Error reading certificate file: %s, ssl support is disabled\r\n", sslOpt.pszCertFile); SSL_CTX_free(pSSLCtx); return (NULL); } SSL_CTX_use_RSAPrivateKey_file(pSSLCtx, sslOpt.pszCertFile, SSL_FILETYPE_PEM); if(!SSL_CTX_check_private_key(pSSLCtx)) { SysLogMessage(LOG_LEV_ERROR, "Private key does not match the certificate, ssl support is disabled\r\n"); SSL_CTX_free(pSSLCtx); return (NULL); } #ifdef DEBUG_SSL SSL_CTX_set_info_callback(pSSLCtx, SSLInfoCallback); #endif if(!SSL_CTX_set_cipher_list(pSSLCtx, SSL_DEFAULT_CIPHER_LIST)) { SysLogMessage(LOG_LEV_ERROR, "Cannot set ciphers: %s, ssl support is disabled\r\n", SSL_DEFAULT_CIPHER_LIST); SSL_CTX_free(pSSLCtx); return (NULL); } return (pSSLCtx); }
eventer_ssl_ctx_t * eventer_ssl_ctx_new(eventer_ssl_orientation_t type, const char *layer, const char *certificate, const char *key, const char *ca, const char *ciphers) { char ssl_ctx_key[SSL_CTX_KEYLEN]; eventer_ssl_ctx_t *ctx; const char *layer_str; char *ctx_layer, *opts; char *opts_fallback = DEFAULT_OPTS_STRING; time_t now; ctx = calloc(1, sizeof(*ctx)); if(!ctx) return NULL; layer_str = layer ? layer : DEFAULT_LAYER_STRING; ctx_layer = alloca(strlen(layer_str)+1); memcpy(ctx_layer, layer_str, strlen(layer_str)+1); opts = strchr(ctx_layer,':'); if(opts) *opts++ = '\0'; else { opts = alloca(strlen(opts_fallback)+1); memcpy(opts, opts_fallback, strlen(opts_fallback)+1); } now = time(NULL); ssl_ctx_key_write(ssl_ctx_key, sizeof(ssl_ctx_key), type, layer, certificate, key, ca, ciphers); ctx->ssl_ctx_cn = ssl_ctx_cache_get(ssl_ctx_key); if(ctx->ssl_ctx_cn) { if(now - ctx->ssl_ctx_cn->creation_time > ssl_ctx_cache_expiry || (now - ctx->ssl_ctx_cn->last_stat_time > ssl_ctx_cache_finfo_expiry && (validate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate) || validate_finfo(&ctx->ssl_ctx_cn->key_finfo, key) || validate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca) || (ctx->ssl_ctx_cn->last_stat_time = now) == 0))) { /* assignment */ ssl_ctx_cache_remove(ssl_ctx_key); ssl_ctx_cache_node_free(ctx->ssl_ctx_cn); ctx->ssl_ctx_cn = NULL; } } if(!ctx->ssl_ctx_cn) { char *part = NULL, *brkt = NULL; long ctx_options = 0; ssl_ctx_cache_node *existing_ctx_cn; ctx->ssl_ctx_cn = calloc(1, sizeof(*ctx->ssl_ctx_cn)); ctx->ssl_ctx_cn->key = strdup(ssl_ctx_key); ctx->ssl_ctx_cn->refcnt = 1; ctx->ssl_ctx_cn->creation_time = now; ctx->ssl_ctx_cn->last_stat_time = now; populate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate); populate_finfo(&ctx->ssl_ctx_cn->key_finfo, key); populate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca); ctx->ssl_ctx = NULL; if(0) ; #if defined(SSL_TXT_SSLV3) && defined(HAVE_SSLV3_SERVER) && defined(HAVE_SSLV3_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_SSLV3)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? SSLv3_server_method() : SSLv3_client_method()); #endif #if defined(SSL_TXT_SSLV2) && defined(HAVE_SSLV2_SERVER) && defined(HAVE_SSLV2_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_SSLV2)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? SSLv2_server_method() : SSLv2_client_method()); #endif #if defined(SSL_TXT_TLSV1) && defined(HAVE_TLSV1_SERVER) && defined(HAVE_TLSV1_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? TLSv1_server_method() : TLSv1_client_method()); #endif #if defined(SSL_TXT_TLSV1_1) && defined(HAVE_TLSV1_1_SERVER) && defined(HAVE_TLSV1_1_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_1)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? TLSv1_1_server_method() : TLSv1_1_client_method()); #endif #if defined(SSL_TXT_TLSV1_2) && defined(HAVE_TLSV1_2_SERVER) && defined(HAVE_TLSV1_2_CLIENT) else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_2)) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? TLSv1_2_server_method() : TLSv1_2_client_method()); #endif if(ctx->ssl_ctx == NULL) ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ? SSLv23_server_method() : SSLv23_client_method()); if(!ctx->ssl_ctx) goto bail; for(part = strtok_r(opts, ",", &brkt); part; part = strtok_r(NULL, ",", &brkt)) { char *optname = part; int neg = 0; if(*optname == '!') neg = 1, optname++; #define SETBITOPT(name, neg, opt) \ if(!strcasecmp(optname, name)) { \ if(neg) ctx_options &= ~(opt); \ else ctx_options |= (opt); \ } SETBITOPT("all", neg, SSL_OP_ALL) #ifdef SSL_TXT_SSLV2 else SETBITOPT(SSL_TXT_SSLV2, !neg, SSL_OP_NO_SSLv2) #endif #ifdef SSL_TXT_SSLV3 else SETBITOPT(SSL_TXT_SSLV3, !neg, SSL_OP_NO_SSLv3) #endif #ifdef SSL_TXT_TLSV1 else SETBITOPT(SSL_TXT_TLSV1, !neg, SSL_OP_NO_TLSv1) #endif #ifdef SSL_TXT_TLSV1_1 else SETBITOPT(SSL_TXT_TLSV1_1, !neg, SSL_OP_NO_TLSv1_1) #endif #ifdef SSL_TXT_TLSV1_2 else SETBITOPT(SSL_TXT_TLSV1_2, !neg, SSL_OP_NO_TLSv1_2) #endif #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE else SETBITOPT("cipher_server_preference", neg, SSL_OP_CIPHER_SERVER_PREFERENCE) #endif else { mtevL(mtev_error, "SSL layer part '%s' not understood.\n", optname); } } if (type == SSL_SERVER) SSL_CTX_set_session_id_context(ctx->ssl_ctx, (unsigned char *)EVENTER_SSL_DATANAME, sizeof(EVENTER_SSL_DATANAME)-1); #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; #endif #ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; #endif #ifdef SSL_OP_NO_COMPRESSION ctx_options |= SSL_OP_NO_COMPRESSION; #endif #ifdef SSL_OP_NO_TICKET ctx_options |= SSL_OP_NO_TICKET; #endif #ifdef SSL_OP_SINGLE_DH_USE ctx_options |= SSL_OP_SINGLE_DH_USE; #endif #ifdef SSL_OP_SINGLE_ECDH_USE ctx_options |= SSL_OP_SINGLE_ECDH_USE; #endif SSL_CTX_set_options(ctx->ssl_ctx, ctx_options); #ifdef SSL_MODE_RELEASE_BUFFERS SSL_CTX_set_mode(ctx->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); #endif if(certificate && SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, certificate) != 1) goto bail; if(key && SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx,key, SSL_FILETYPE_PEM) != 1) goto bail; if(ca) { STACK_OF(X509_NAME) *cert_stack; if(!SSL_CTX_load_verify_locations(ctx->ssl_ctx,ca,NULL) || (cert_stack = SSL_load_client_CA_file(ca)) == NULL) goto bail; SSL_CTX_set_client_CA_list(ctx->ssl_ctx, cert_stack); } SSL_CTX_set_cipher_list(ctx->ssl_ctx, ciphers ? ciphers : "DEFAULT"); SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, verify_cb); #ifndef OPENSSL_NO_EC #if defined(SSL_CTX_set_ecdh_auto) SSL_CTX_set_ecdh_auto(ctx->ssl_ctx, 1); #elif defined(NID_X9_62_prime256v1) EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); SSL_CTX_set_tmp_ecdh(ctx->ssl_ctx, ec_key); EC_KEY_free(ec_key); #endif #endif existing_ctx_cn = ssl_ctx_cache_set(ctx->ssl_ctx_cn); if(existing_ctx_cn != ctx->ssl_ctx_cn) { ssl_ctx_cache_node_free(ctx->ssl_ctx_cn); ctx->ssl_ctx_cn = existing_ctx_cn; } }
void context_init(void) { /* init SSL */ int i; #if SSLEAY_VERSION_NUMBER >= 0x00907000L /* Load all bundled ENGINEs into memory and make them visible */ ENGINE_load_builtin_engines(); /* Register all of them for every algorithm they collectively implement */ ENGINE_register_all_complete(); #endif if(!init_prng()) log(LOG_INFO, "PRNG seeded successfully"); SSLeay_add_ssl_algorithms(); SSL_load_error_strings(); if(options.option.client) { ctx=SSL_CTX_new(SSLv3_client_method()); } else { /* Server mode */ ctx=SSL_CTX_new(SSLv23_server_method()); #ifndef NO_RSA SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb); #endif /* NO_RSA */ if(init_dh()) log(LOG_WARNING, "Diffie-Hellman initialization failed"); } if(options.ssl_options) { log(LOG_DEBUG, "Configuration SSL options: 0x%08lX", options.ssl_options); log(LOG_DEBUG, "SSL options set: 0x%08lX", SSL_CTX_set_options(ctx, options.ssl_options)); } #if SSLEAY_VERSION_NUMBER >= 0x00906000L SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); #endif /* OpenSSL-0.9.6 */ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH); SSL_CTX_set_timeout(ctx, options.session_timeout); if(options.option.cert) { if(!SSL_CTX_use_certificate_chain_file(ctx, options.cert)) { log(LOG_ERR, "Error reading certificate file: %s", options.cert); sslerror("SSL_CTX_use_certificate_chain_file"); exit(1); } log(LOG_DEBUG, "Certificate: %s", options.cert); log(LOG_DEBUG, "Key file: %s", options.key); #ifdef USE_WIN32 SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb); #endif for(i=0; i<3; i++) { #ifdef NO_RSA if(SSL_CTX_use_PrivateKey_file(ctx, options.key, SSL_FILETYPE_PEM)) #else /* NO_RSA */ if(SSL_CTX_use_RSAPrivateKey_file(ctx, options.key, SSL_FILETYPE_PEM)) #endif /* NO_RSA */ break; if(i<2 && ERR_GET_REASON(ERR_peek_error())==EVP_R_BAD_DECRYPT) { sslerror_stack(); /* dump the error stack */ log(LOG_ERR, "Wrong pass phrase: retrying"); continue; } #ifdef NO_RSA sslerror("SSL_CTX_use_PrivateKey_file"); #else /* NO_RSA */ sslerror("SSL_CTX_use_RSAPrivateKey_file"); #endif /* NO_RSA */ exit(1); } if(!SSL_CTX_check_private_key(ctx)) { sslerror("Private key does not match the certificate"); exit(1); } } verify_init(); /* Initialize certificate verification */ SSL_CTX_set_info_callback(ctx, info_callback); if(options.cipher_list) { if (!SSL_CTX_set_cipher_list(ctx, options.cipher_list)) { sslerror("SSL_CTX_set_cipher_list"); exit(1); } } }
int schannel_openssl_server_init(SCHANNEL_OPENSSL* context) { int status; long options = 0; //context->ctx = SSL_CTX_new(SSLv23_server_method()); context->ctx = SSL_CTX_new(TLSv1_server_method()); if (!context->ctx) { WLog_ERR(TAG, "SSL_CTX_new failed"); return -1; } /* * SSL_OP_NO_SSLv2: * * We only want SSLv3 and TLSv1, so disable SSLv2. * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ options |= SSL_OP_NO_SSLv2; /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; SSL_CTX_set_options(context->ctx, options); if (SSL_CTX_use_RSAPrivateKey_file(context->ctx, "/tmp/localhost.key", SSL_FILETYPE_PEM) <= 0) { WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed"); return -1; } context->ssl = SSL_new(context->ctx); if (!context->ssl) { WLog_ERR(TAG, "SSL_new failed"); return -1; } if (SSL_use_certificate_file(context->ssl, "/tmp/localhost.crt", SSL_FILETYPE_PEM) <= 0) { WLog_ERR(TAG, "SSL_use_certificate_file failed"); return -1; } context->bioRead = BIO_new(BIO_s_mem()); if (!context->bioRead) { WLog_ERR(TAG, "BIO_new failed"); return -1; } status = BIO_set_write_buf_size(context->bioRead, SCHANNEL_CB_MAX_TOKEN); context->bioWrite = BIO_new(BIO_s_mem()); if (!context->bioWrite) { WLog_ERR(TAG, "BIO_new failed"); return -1; } status = BIO_set_write_buf_size(context->bioWrite, SCHANNEL_CB_MAX_TOKEN); status = BIO_make_bio_pair(context->bioRead, context->bioWrite); SSL_set_bio(context->ssl, context->bioRead, context->bioWrite); context->ReadBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN); context->WriteBuffer = (BYTE*) malloc(SCHANNEL_CB_MAX_TOKEN); return 0; }
int APP_CC xrdp_tls_accept(struct xrdp_tls *self) { int connection_status; long options = 0; /** * SSL_OP_NO_SSLv2: * * We only want SSLv3 and TLSv1, so disable SSLv2. * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ options |= SSL_OP_NO_SSLv2; #if defined(SSL_OP_NO_COMPRESSION) /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; self->ctx = SSL_CTX_new(SSLv23_server_method()); /* set context options */ SSL_CTX_set_mode(self->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE); SSL_CTX_set_options(self->ctx, options); SSL_CTX_set_read_ahead(self->ctx, 1); if (self->ctx == NULL) { g_writeln("xrdp_tls_accept: SSL_CTX_new failed"); return 1; } if (SSL_CTX_use_RSAPrivateKey_file(self->ctx, self->key, SSL_FILETYPE_PEM) <= 0) { g_writeln("xrdp_tls_accept: SSL_CTX_use_RSAPrivateKey_file failed"); return 1; } self->ssl = SSL_new(self->ctx); if (self->ssl == NULL) { g_writeln("xrdp_tls_accept: SSL_new failed"); return 1; } if (SSL_use_certificate_file(self->ssl, self->cert, SSL_FILETYPE_PEM) <= 0) { g_writeln("xrdp_tls_accept: SSL_use_certificate_file failed"); return 1; } if (SSL_set_fd(self->ssl, self->trans->sck) < 1) { g_writeln("xrdp_tls_accept: SSL_set_fd failed"); return 1; } connection_status = SSL_accept(self->ssl); if (connection_status <= 0) { if (xrdp_tls_print_error("SSL_accept", self->ssl, connection_status)) { return 1; } } g_writeln("xrdp_tls_accept: TLS connection accepted"); return 0; }
int main(int argc, char *argv[]) { char *CApath = NULL, *CAfile = NULL; int badop = 0; int ret = 1; int client_auth = 0; int server_auth = 0; SSL_CTX *s_ctx = NULL; SSL_CTX *c_ctx = NULL; char *scert = TEST_SERVER_CERT; char *ccert = TEST_CLIENT_CERT; SSL_METHOD *ssl_method = SSLv23_method(); RAND_seed(rnd_seed, sizeof rnd_seed); if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); if (bio_stdout == NULL) bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE); argc--; argv++; while (argc >= 1) { if (sgx_strcmp(*argv, "-server_auth") == 0) server_auth = 1; else if (sgx_strcmp(*argv, "-client_auth") == 0) client_auth = 1; else if (sgx_strcmp(*argv, "-reconnect") == 0) reconnect = 1; else if (sgx_strcmp(*argv, "-stats") == 0) cache_stats = 1; else if (sgx_strcmp(*argv, "-ssl3") == 0) ssl_method = SSLv3_method(); else if (sgx_strcmp(*argv, "-ssl2") == 0) ssl_method = SSLv2_method(); else if (sgx_strcmp(*argv, "-CApath") == 0) { if (--argc < 1) goto bad; CApath = *(++argv); } else if (sgx_strcmp(*argv, "-CAfile") == 0) { if (--argc < 1) goto bad; CAfile = *(++argv); } else if (sgx_strcmp(*argv, "-cert") == 0) { if (--argc < 1) goto bad; scert = *(++argv); } else if (sgx_strcmp(*argv, "-ccert") == 0) { if (--argc < 1) goto bad; ccert = *(++argv); } else if (sgx_strcmp(*argv, "-threads") == 0) { if (--argc < 1) goto bad; thread_number = atoi(*(++argv)); if (thread_number == 0) thread_number = 1; if (thread_number > MAX_THREAD_NUMBER) thread_number = MAX_THREAD_NUMBER; } else if (sgx_strcmp(*argv, "-loops") == 0) { if (--argc < 1) goto bad; number_of_loops = atoi(*(++argv)); if (number_of_loops == 0) number_of_loops = 1; } else { fprintf(stderr, "unknown option %s\n", *argv); badop = 1; break; } argc--; argv++; } if (badop) { bad: sv_usage(); goto end; } if (cipher == NULL && OPENSSL_issetugid() == 0) cipher = getenv("SSL_CIPHER"); SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); c_ctx = SSL_CTX_new(ssl_method); s_ctx = SSL_CTX_new(ssl_method); if ((c_ctx == NULL) || (s_ctx == NULL)) { ERR_print_errors(bio_err); goto end; } SSL_CTX_set_session_cache_mode(s_ctx, SSL_SESS_CACHE_NO_AUTO_CLEAR | SSL_SESS_CACHE_SERVER); SSL_CTX_set_session_cache_mode(c_ctx, SSL_SESS_CACHE_NO_AUTO_CLEAR | SSL_SESS_CACHE_SERVER); if (!SSL_CTX_use_certificate_file(s_ctx, scert, SSL_FILETYPE_PEM)) { ERR_print_errors(bio_err); } else if (!SSL_CTX_use_RSAPrivateKey_file(s_ctx, scert, SSL_FILETYPE_PEM)) { ERR_print_errors(bio_err); goto end; } if (client_auth) { SSL_CTX_use_certificate_file(c_ctx, ccert, SSL_FILETYPE_PEM); SSL_CTX_use_RSAPrivateKey_file(c_ctx, ccert, SSL_FILETYPE_PEM); } if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) || (!SSL_CTX_set_default_verify_paths(s_ctx)) || (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) || (!SSL_CTX_set_default_verify_paths(c_ctx))) { fprintf(stderr, "SSL_load_verify_locations\n"); ERR_print_errors(bio_err); goto end; } if (client_auth) { fprintf(stderr, "client authentication\n"); SSL_CTX_set_verify(s_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); } if (server_auth) { fprintf(stderr, "server authentication\n"); SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER, verify_callback); } thread_setup(); do_threads(s_ctx, c_ctx); thread_cleanup(); end: if (c_ctx != NULL) { fprintf(stderr, "Client SSL_CTX stats then free it\n"); print_stats(stderr, c_ctx); SSL_CTX_free(c_ctx); } if (s_ctx != NULL) { fprintf(stderr, "Server SSL_CTX stats then free it\n"); print_stats(stderr, s_ctx); if (cache_stats) { fprintf(stderr, "-----\n"); lh_stats(SSL_CTX_sessions(s_ctx), stderr); fprintf(stderr, "-----\n"); /*- lh_node_stats(SSL_CTX_sessions(s_ctx),stderr); fprintf(stderr,"-----\n"); */ lh_node_usage_stats(SSL_CTX_sessions(s_ctx), stderr); fprintf(stderr, "-----\n"); } SSL_CTX_free(s_ctx); fprintf(stderr, "done free\n"); } exit(ret); return (0); }
int main ( int argc, char **argv ) { int status, length; io_channel chan; struct rpc_msg msg; char *CApath=NULL,*CAfile=NULL; int badop=0; int ret=1; int client_auth=0; int server_auth=0; SSL_CTX *s_ctx=NULL; /* * Confirm logical link with initiating client. */ LIB$INIT_TIMER(); status = SYS$ASSIGN ( &sysnet, &chan, 0, 0, 0 ); printf("status of assign to SYS$NET: %d\n", status ); /* * Initialize standard out and error files. */ if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE); if (bio_stdout == NULL) if ((bio_stdout=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_stdout,stdout,BIO_NOCLOSE); /* * get the preferred cipher list and other initialization */ if (cipher == NULL) cipher=getenv("SSL_CIPHER"); printf("cipher list: %s\n", cipher ? cipher : "{undefined}" ); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); /* DRM, this was the original, but there is no such thing as SSLv2() s_ctx=SSL_CTX_new(SSLv2()); */ s_ctx=SSL_CTX_new(SSLv2_server_method()); if (s_ctx == NULL) goto end; SSL_CTX_use_certificate_file(s_ctx,TEST_SERVER_CERT,SSL_FILETYPE_PEM); SSL_CTX_use_RSAPrivateKey_file(s_ctx,TEST_SERVER_CERT,SSL_FILETYPE_PEM); printf("Loaded server certificate: '%s'\n", TEST_SERVER_CERT ); /* * Take commands from client until bad status. */ LIB$SHOW_TIMER(); status = doit ( chan, s_ctx ); LIB$SHOW_TIMER(); /* * do final cleanup and exit. */ end: if (s_ctx != NULL) SSL_CTX_free(s_ctx); LIB$SHOW_TIMER(); return 1; }
void main () { int err; SSL_CTX* ctx; SSL* ssl; X509* client_cert; char* str; char buf [4096]; FILE* log; log = fopen ("/dev/console", "a"); CHK_NULL(log); fprintf (log, "inetdserv %ld\n", (long)getpid()); SSL_load_error_strings(); ctx = SSL_CTX_new (); CHK_NULL(ctx); err = SSL_CTX_use_RSAPrivateKey_file (ctx, KEYF, SSL_FILETYPE_PEM); CHK_SSL (err); err = SSL_CTX_use_certificate_file (ctx, CERTF, SSL_FILETYPE_PEM); CHK_SSL (err); /* inetd has already opened the TCP connection, so we can get right down to business. */ ssl = SSL_new (ctx); CHK_NULL(ssl); SSL_set_fd (ssl, fileno(stdin)); err = SSL_accept (ssl); CHK_SSL(err); /* Get the cipher - opt */ fprintf (log, "SSL connection using %s\n", SSL_get_cipher (ssl)); /* Get client's certificate (note: beware of dynamic allocation) - opt */ client_cert = SSL_get_peer_certificate (ssl); if (client_cert != NULL) { fprintf (log, "Client certificate:\n"); str = X509_NAME_oneline (X509_get_subject_name (client_cert)); CHK_NULL(str); fprintf (log, "\t subject: %s\n", str); OPENSSL_free (str); str = X509_NAME_oneline (X509_get_issuer_name (client_cert)); CHK_NULL(str); fprintf (log, "\t issuer: %s\n", str); OPENSSL_free (str); /* We could do all sorts of certificate verification stuff here before deallocating the certificate. */ X509_free (client_cert); } else fprintf (log, "Client doe not have certificate.\n"); /* ------------------------------------------------- */ /* DATA EXCHANGE: Receive message and send reply */ err = SSL_read (ssl, buf, sizeof(buf) - 1); CHK_SSL(err); buf[err] = '\0'; fprintf (log, "Got %d chars:'%s'\n", err, buf); err = SSL_write (ssl, "Loud and clear.", strlen("Loud and clear.")); CHK_SSL(err); /* Clean up. */ fclose (log); SSL_free (ssl); SSL_CTX_free (ctx); }