void SSLContext::switchCiphersIfTLS11( SSL* ssl, const std::string& tls11CipherString, const std::vector<std::pair<std::string, int>>& tls11AltCipherlist) { CHECK(!(tls11CipherString.empty() && tls11AltCipherlist.empty())) << "Shouldn't call if empty ciphers / alt ciphers"; if (TLS1_get_client_version(ssl) <= TLS1_VERSION) { // We only do this for TLS v 1.1 and later return; } const std::string* ciphers = &tls11CipherString; if (!tls11AltCipherlist.empty()) { if (!cipherListPicker_) { std::vector<int> weights; std::for_each( tls11AltCipherlist.begin(), tls11AltCipherlist.end(), [&](const std::pair<std::string, int>& e) { weights.push_back(e.second); }); cipherListPicker_.reset( new std::discrete_distribution<int>(weights.begin(), weights.end())); } auto rng = ThreadLocalPRNG(); auto index = (*cipherListPicker_)(rng); if ((size_t)index >= tls11AltCipherlist.size()) { LOG(ERROR) << "Trying to pick alt TLS11 cipher index " << index << ", but tls11AltCipherlist is of length " << tls11AltCipherlist.size(); } else { ciphers = &tls11AltCipherlist[index].first; } } // Prefer AES for TLS versions 1.1 and later since these are not // vulnerable to BEAST attacks on AES. Note that we're setting the // cipher list on the SSL object, not the SSL_CTX object, so it will // only last for this request. int rc = SSL_set_cipher_list(ssl, ciphers->c_str()); if ((rc == 0) || ERR_peek_error() != 0) { // This shouldn't happen since we checked for this when proxygen // started up. LOG(WARNING) << "ssl_cipher: No specified ciphers supported for switch"; SSL_set_cipher_list(ssl, providedCiphersString_.c_str()); } }
void QFrankSSL::VerbindungHerstellen(const QString &rechnername,const quint16 &port,const OpenMode &betriebsart) { if(!K_SSLStrukturAufbauen()) return; /*if(K_SSLStruktur==NULL) { #ifndef QT_NO_DEBUG qWarning("QFrankSSL VerbindungHerstellen: SSL Struktur nicht bereit"); #endif emit SSLFehler(K_KeineSSLStrukturText); return; }*/ /* setzen der zu benutzenden Verschlüsselungsalgorithmen Wichig ist, das die in ansteigener Reihenfolge übergeben werden!!!. */ if(K_OpenSSLMitBugs()) { K_AllesZuruecksetzen(); return; } if(SSL_set_cipher_list(K_SSLStruktur,K_VerfuegbareAlgorithmen.join(":").toAscii().constData())==0) { #ifndef QT_NO_DEBUG qCritical(qPrintable(trUtf8("QFrankSSL kein gültiger Verschlüsselungsalgorithmus angegeben","debug"))); #endif K_AllesZuruecksetzen(); //Liste löschen, da eh ungültig K_VerfuegbareAlgorithmen.clear(); emit SSLFehler(trUtf8("Gewünschter Verschlüsselungsalgorithmus wird von der aktuellen OpenSSL Bibliothek nicht unerstützt!")); return; } connectToHost(rechnername,port,betriebsart); }
int sycSSL_set_cipher_list(SSL *ssl, const char *str) { int result; Debug2("SSL_set_cipher_list(%p, \"%s\")", ssl, str); result = SSL_set_cipher_list(ssl, str); Debug1("SSL_set_cipher_list() -> %d", result); return result; }
static int openssl_iostream_set(struct ssl_iostream *ssl_io, const struct ssl_iostream_settings *set, const char **error_r) { const struct ssl_iostream_settings *ctx_set = ssl_io->ctx->set; int verify_flags; if (set->verbose) SSL_set_info_callback(ssl_io->ssl, openssl_info_callback); if (set->cipher_list != NULL && strcmp(ctx_set->cipher_list, set->cipher_list) != 0) { if (!SSL_set_cipher_list(ssl_io->ssl, set->cipher_list)) { *error_r = t_strdup_printf( "Can't set cipher list to '%s': %s", set->cipher_list, openssl_iostream_error()); return -1; } } if (set->protocols != NULL) { SSL_clear_options(ssl_io->ssl, OPENSSL_ALL_PROTOCOL_OPTIONS); SSL_set_options(ssl_io->ssl, openssl_get_protocol_options(set->protocols)); } if (set->cert != NULL && strcmp(ctx_set->cert, set->cert) != 0) { if (openssl_iostream_use_certificate(ssl_io, set->cert, error_r) < 0) return -1; } if (set->key != NULL && strcmp(ctx_set->key, set->key) != 0) { if (openssl_iostream_use_key(ssl_io, set, error_r) < 0) return -1; } if (set->verify_remote_cert) { if (ssl_io->ctx->client_ctx) verify_flags = SSL_VERIFY_NONE; else verify_flags = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; SSL_set_verify(ssl_io->ssl, verify_flags, openssl_iostream_verify_client_cert); } if (set->cert_username_field != NULL) { ssl_io->username_nid = OBJ_txt2nid(set->cert_username_field); if (ssl_io->username_nid == NID_undef) { *error_r = t_strdup_printf( "Invalid cert_username_field: %s", set->cert_username_field); return -1; } } else { ssl_io->username_nid = ssl_io->ctx->username_nid; } ssl_io->verbose = set->verbose; ssl_io->verbose_invalid_cert = set->verbose_invalid_cert || set->verbose; ssl_io->require_valid_cert = set->require_valid_cert; return 0; }
// XXX Clean up this function, we MUST handle all errors possible int krypt_set_rsa(krypt_t *kconn) { if (kconn->security_level == KRYPT_RSA) { jlog(L_NOTICE, "the security level is already set to RSA"); return 0; } SSL_set_cipher_list(kconn->ssl, "AES256-SHA"); // Load the trusted certificate store into our SSL_CTX SSL_CTX_set_cert_store(kconn->ctx, kconn->passport->trusted_authority); // Force the peer cert verifying + fail if no cert is sent by the peer SSL_set_verify(kconn->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); // Set the certificate and key SSL_use_certificate(kconn->ssl, kconn->passport->certificate); SSL_use_PrivateKey(kconn->ssl, kconn->passport->keyring); if (kconn->conn_type == KRYPT_SERVER) { jlog(L_NOTICE, "set verify"); // Change the session id to avoid resuming ADH session SSL_set_session_id_context(kconn->ssl, (void*)&s_server_auth_session_id_context, sizeof(s_server_auth_session_id_context)); } kconn->security_level = KRYPT_RSA; return 0; }
static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value) { int rv = 1; if (cctx->ctx) rv = SSL_CTX_set_cipher_list(cctx->ctx, value); if (cctx->ssl) rv = SSL_set_cipher_list(cctx->ssl, value); return rv > 0; }
static apr_status_t init_ssl(serv_ctx_t *serv_ctx) { ssl_context_t *ssl_ctx = serv_ctx->ssl_ctx; ssl_ctx->ssl = SSL_new(ssl_ctx->ctx); SSL_set_cipher_list(ssl_ctx->ssl, "ALL"); SSL_set_bio(ssl_ctx->ssl, ssl_ctx->bio, ssl_ctx->bio); return APR_SUCCESS; }
const char *dbapi_lookup(const char *key) { long res = 1; SSL_CTX* ctx = NULL; BIO *web = NULL, *out = NULL; SSL *ssl = NULL; const SSL_METHOD* method; char *token, *tmpout, *buf; int hlen=0, len=0, maxlen=2048; (void)SSL_library_init(); SSL_load_error_strings(); OPENSSL_config(NULL); method = SSLv23_method(); if(method==NULL) return NULL; ctx = SSL_CTX_new(method); if(ctx==NULL) return NULL; SSL_CTX_set_verify_depth(ctx, 4); SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1| SSL_OP_NO_COMPRESSION); web = BIO_new_ssl_connect(ctx); if(web==NULL) return NULL; res = BIO_set_conn_hostname(web, DB_API_SERVER); if(res!=1) return NULL; BIO_get_ssl(web, &ssl); if(ssl==NULL) return NULL; res = SSL_set_cipher_list(ssl, SECURE_CIPHER_LIST); if(res!=1) return NULL; res = SSL_set_tlsext_host_name(ssl, DB_API_HOST); if(res!=1) return NULL; out = BIO_new_fp(stdout, BIO_NOCLOSE); if(NULL==out) return NULL; res = BIO_do_connect(web); if(res!=1) return NULL; res = BIO_do_handshake(web); if(res!=1) return NULL; len=(60+strlen(key)+strlen(DB_API_HOST)+strlen(DB_API_AUTH)); char *request=malloc(sizeof(char)*(len+1)); snprintf(request,len, "GET %s HTTP/1.1\nHost: %s\nx-api-key: %s\nConnection: close\n\n", key, DB_API_HOST, DB_API_AUTH); request[len]='\0'; BIO_puts(web, request); BIO_puts(out, "\n"); buf = malloc(sizeof(char)*maxlen); do { char buff[1536] = {}; len=BIO_read(web, buff, sizeof(buff)); hlen+=len; if(hlen<maxlen&&len>0) strncat(buf,buff,len); } while (len>0 || BIO_should_retry(web)); buf[maxlen]='\0'; tmpout = malloc(sizeof(char)*(HASH_MAXLENGTH+1)); token = strtok(buf, "\n"); while (token) { snprintf(tmpout,HASH_MAXLENGTH,"%s",token); token = strtok(NULL, "\n"); } tmpout[strlen(tmpout)]='\0'; free(buf); free(request); if(out) BIO_free(out); if(web != NULL) BIO_free_all(web); if(NULL != ctx) SSL_CTX_free(ctx); return tmpout; }
int tls_connection_set_anon_dh(void *ssl_ctx, struct tls_connection *conn) { if (conn == NULL || conn->ssl == NULL) return -1; if (SSL_set_cipher_list(conn->ssl, "ADH-AES128-SHA") != 1) { wpa_printf(MSG_INFO, "TLS: Anon DH configuration failed - %s", ERR_error_string(ERR_get_error(), NULL)); return -1; } return 0; }
void conn_init(Conn *conn) { if (param.servers) { int len = strlen(srvcurrent); conn->hostname = srvcurrent; conn->hostname_len = len; conn->fqdname = conn->hostname; conn->fqdname_len = conn->hostname_len; srvcurrent += len + 1; if (srvcurrent >= srvend) srvcurrent = srvbase; } else if (param.server_name) { conn->hostname = param.server; conn->hostname_len = strlen(param.server); conn->fqdname = param.server_name; conn->fqdname_len = strlen(param.server_name); } else { conn->hostname = param.server; conn->hostname_len = strlen(param.server); conn->fqdname = conn->hostname; conn->fqdname_len = conn->hostname_len; } conn->port = param.port; conn->sd = -1; conn->myport = -1; conn->line.iov_base = conn->line_buf; #ifdef HAVE_SSL if (param.use_ssl) { conn->ssl = SSL_new(ssl_ctx); if (!conn->ssl) { ERR_print_errors_fp(stderr); exit(-1); } if (param.ssl_cipher_list) { /* set order of ciphers */ int ssl_err = SSL_set_cipher_list(conn->ssl, param.ssl_cipher_list); if (DBG > 2) fprintf(stderr, "core_ssl_connect: set_cipher_list returned %d\n", ssl_err); } } #endif }
void SSLContext::switchCiphersIfTLS11( SSL* ssl, const std::string& tls11CipherString) { CHECK(!tls11CipherString.empty()) << "Shouldn't call if empty alt ciphers"; if (TLS1_get_client_version(ssl) <= TLS1_VERSION) { // We only do this for TLS v 1.1 and later return; } // Prefer AES for TLS versions 1.1 and later since these are not // vulnerable to BEAST attacks on AES. Note that we're setting the // cipher list on the SSL object, not the SSL_CTX object, so it will // only last for this request. int rc = SSL_set_cipher_list(ssl, tls11CipherString.c_str()); if ((rc == 0) || ERR_peek_error() != 0) { // This shouldn't happen since we checked for this when proxygen // started up. LOG(WARNING) << "ssl_cipher: No specified ciphers supported for switch"; SSL_set_cipher_list(ssl, providedCiphersString_.c_str()); } }
struct sslbuffer_t *SSLBufferCreate(SSL_CTX *ctx, struct event_base *base) { struct sslbuffer_t *sslbuffer = NULL; SSL *ssl = NULL; struct buffer_t *write_buffer_1 = NULL; struct buffer_t *write_buffer_2 = NULL; sslbuffer = (struct sslbuffer_t *) malloc(sizeof(struct sslbuffer_t)); if (sslbuffer == NULL) goto Error; memset(sslbuffer, 0, sizeof(*sslbuffer)); sslbuffer->ctx = ctx; ssl = SSL_new(ctx); if (ssl == NULL) goto Error; SSL_set_cipher_list(ssl, CIPHER_LIST); sslbuffer->ssl = ssl; sslbuffer->base = base; write_buffer_1 = BufferCreate(256); if (write_buffer_1 == NULL) goto Error; sslbuffer->write_buffer_1 = write_buffer_1; write_buffer_2 = BufferCreate(256); if (write_buffer_2 == NULL) goto Error; sslbuffer->write_buffer_2 = write_buffer_2; sslbuffer->fl_connecting = 0; sslbuffer->fl_reading = 0; sslbuffer->fl_writing = 0; sslbuffer->fl_want_read = 0; sslbuffer->fl_want_write = 0; return sslbuffer; Error: if (write_buffer_2 != NULL) BufferDelete(write_buffer_2); if (write_buffer_1 != NULL) BufferDelete(write_buffer_1); if (ssl != NULL) SSL_free(ssl); free(sslbuffer); return NULL; }
bool tls_socket::set_hostname(const char* sAddr) { sock_closed = false; if(ctx == nullptr) { init_ctx(); if(ctx == nullptr) { print_error(); return false; } } if((bio = BIO_new_ssl_connect(ctx)) == nullptr) { print_error(); return false; } int flag = 1; /* If it fails, it fails, we won't loose too much sleep over it */ setsockopt(BIO_get_fd(bio, nullptr), IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); if(BIO_set_conn_hostname(bio, sAddr) != 1) { print_error(); return false; } BIO_get_ssl(bio, &ssl); if(ssl == nullptr) { print_error(); return false; } if(jconf::inst()->TlsSecureAlgos()) { if(SSL_set_cipher_list(ssl, "HIGH:!aNULL:!PSK:!SRP:!MD5:!RC4:!SHA1") != 1) { print_error(); return false; } } return true; }
void conn_init (Conn *conn) { conn->hostname = param.server; conn->hostname_len = strlen (param.server); conn->port = param.port; conn->sd = -1; conn->myport = -1; conn->line.iov_base = conn->line_buf; if (param.num_server_names) { conn->fqdname = param.server_names[param.next_server_name]; conn->fqdname_len = strlen (param.server_names[param.next_server_name]); param.next_server_name++; param.next_server_name %= param.num_server_names; } else { conn->fqdname = conn->hostname; conn->fqdname_len = conn->hostname_len; } #ifdef HAVE_SSL if (param.use_ssl) { conn->ssl = SSL_new (ssl_ctx); if (!conn->ssl) { ERR_print_errors_fp (stderr); exit (-1); } if (param.ssl_cipher_list) { /* set order of ciphers */ int ssl_err = SSL_set_cipher_list (conn->ssl, param.ssl_cipher_list); if (DBG > 2) fprintf (stderr, "core_ssl_connect: set_cipher_list returned %d\n", ssl_err); } } #endif }
SSL* init_ssl_with_cipher(SSL_CTX* ssl_ctx, const char* cipher_name) { SSL* ssl; ssl = SSL_new(ssl_ctx); if (!SSL_set_cipher_list(ssl, cipher_name)) { write_out(PRINT_ERROR, "Unable to initialize SSL with %s.", cipher_name); write_raise_level(); write_out(PRINT_ERROR, "Your version of OpenSSL may be outdated. Update OpenSSL and try again."); write_out(PRINT_ERROR, "If your version of OpenSSL is current, then %s cipher may have been disabled at compile time.", cipher_name); write_lower_level(); if (ssl) SSL_free(ssl); return 0; } return ssl; }
bool tls_socket::set_hostname(const char* sAddr) { if(ctx == nullptr) { init_ctx(); if(ctx == nullptr) { print_error(); return false; } } if((bio = BIO_new_ssl_connect(ctx)) == nullptr) { print_error(); return false; } if(BIO_set_conn_hostname(bio, sAddr) != 1) { print_error(); return false; } BIO_get_ssl(bio, &ssl); if(ssl == nullptr) { print_error(); return false; } if(jconf::inst()->TlsSecureAlgos()) { if(SSL_set_cipher_list(ssl, "HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4:!SHA1") != 1) { print_error(); return false; } } return true; }
static SSL * open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS) { SSL_CTX *ssl_ctx = NULL; SSL *ssl = NULL; int n, finished = 0; BIO *sbio; ssl_ctx = SSL_CTX_new (SSLv23_client_method ()); SSL_CTX_set_default_verify_paths (ssl_ctx); SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, &ssl_verify); ssl = SSL_new (ssl_ctx); /* TODO: finetune this list, take into account anonTLS bool */ SSL_set_cipher_list(ssl, "ALL"); SSL_set_fd (ssl, sockfd); SSL_CTX_set_app_data (ssl_ctx, client); do { n = SSL_connect(ssl); if (n != 1) { if (wait_for_data(ssl, n, 1) != 1) { finished = 1; if (ssl->ctx) SSL_CTX_free (ssl->ctx); SSL_free(ssl); SSL_shutdown (ssl); return NULL; } } } while( n != 1 && finished != 1 ); return ssl; }
int DoSSLClientNegotiation(STREAM *S, int Flags) { int result=FALSE; #ifdef HAVE_LIBSSL const SSL_METHOD *Method; SSL_CTX *ctx; SSL *ssl; //struct x509 *cert=NULL; char *ptr; if (S) { INTERNAL_SSL_INIT(); // SSL_load_ciphers(); Method=SSLv23_client_method(); ctx=SSL_CTX_new(Method); if (! ctx) HandleSSLError(); else { STREAM_INTERNAL_SSL_ADD_SECURE_KEYS(S,ctx); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, OpenSSLVerifyCallback); ssl=SSL_new(ctx); SSL_set_fd(ssl,S->in_fd); STREAMSetItem(S,"LIBUSEFUL-SSL-CTX",ssl); SSL_set_options(ssl, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2); //SSL_OP_NO_SSLv2, SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1 ptr=LibUsefulGetValue("SSL-Permitted-Ciphers"); if (ptr) SSL_set_cipher_list(ssl, ptr); result=SSL_connect(ssl); S->Flags|=SF_SSL; OpenSSLQueryCipher(S); OpenSSLVerifyCertificate(S); } } #endif return(result); }
/* Switch on a filedescriptor */ int ggz_tls_enable_fd(int fd, GGZTLSType mode, GGZTLSVerificationType verify) { int ret, ret2; STACK_OF(SSL_CIPHER) *stack; SSL_CIPHER *cipher; int bits; char *cipherlist; SSL *_tls; int _tls_active; struct list_entry *entry; _state = 1; _tls_active = 0; if((mode != GGZ_TLS_CLIENT) && (mode != GGZ_TLS_SERVER)) { TLSERROR("Wrong mode."); return 0; } if(!_tlsctx) tls_init(verify); _tls = SSL_new(_tlsctx); if(_tls) { cipherlist = NULL; stack = SSL_get_ciphers(_tls); while((cipher = (SSL_CIPHER*)sk_pop(stack)) != NULL) { printf("* Cipher: %s\n", SSL_CIPHER_get_name(cipher)); printf(" Bits: %i\n", SSL_CIPHER_get_bits(cipher, &bits)); printf(" Used bits: %i\n", bits); printf(" Version: %s\n", SSL_CIPHER_get_version(cipher)); printf(" Description: %s\n", SSL_CIPHER_description(cipher, NULL, 0)); if(cipherlist) { cipherlist = (char*)realloc(cipherlist, (strlen(cipherlist) + 1) + strlen(SSL_CIPHER_get_name(cipher)) + 1); strcat(cipherlist, ":"); strcat(cipherlist, SSL_CIPHER_get_name(cipher)); } else { cipherlist = (char*)malloc(strlen(SSL_CIPHER_get_name(cipher)) + 1); strcpy(cipherlist, SSL_CIPHER_get_name(cipher)); } } printf("Available ciphers: %s\n", cipherlist); ret = SSL_set_cipher_list(_tls, cipherlist); if(!ret) TLSERROR("Cipher selection failed."); ret = SSL_set_fd(_tls, fd); if(!ret) TLSERROR("Assignment to connection failed."); else { SSL_set_read_ahead(_tls, 1); if(mode == GGZ_TLS_SERVER) { tls_certkey(_tls); if(_state) { SSL_set_accept_state(_tls); ret = SSL_accept(_tls); } } else { SSL_set_connect_state(_tls); ret = SSL_connect(_tls); } if((ret != 1) || (!_state)) { printf("Ret: %i, State: %i\n", ret, _state); TLSERROR("Handshake failed."); ret2 = ERR_get_error(); printf("EXT: %s\n%s\n%s\n%s\n%s\n", tls_exterror(_tls, ret), ERR_error_string(ret2, NULL), ERR_lib_error_string(ret2), ERR_func_error_string(ret2), ERR_reason_error_string(ret2)); } else { printf(">>>>> Handshake successful.\n"); if((mode == GGZ_TLS_SERVER) || (verify == GGZ_TLS_VERIFY_NONE)) _tls_active = 1; else { printf(">>>>> Client side, thus checking Certificate.\n"); printf("Negotiated cipher: %s\n", SSL_get_cipher(_tls)); printf("Shared ciphers: %s\n", SSL_get_shared_ciphers(_tls, NULL, 0)); if(SSL_get_peer_certificate(_tls)) { if(SSL_get_verify_result(_tls) == X509_V_OK) { _tls_active = 1; } else { printf("Error code: %li\n", SSL_get_verify_result(_tls)); TLSERROR("Invalid certificate, or certificate is not self-signed."); } } else TLSERROR("Couldn't get certificate."); } } entry = (struct list_entry*)ggz_malloc(sizeof(struct list_entry)); entry->tls = _tls; entry->fd = fd; entry->active = _tls_active; ggz_list_insert(openssllist, entry); return 1; } } return 0; }
static int openssl_ssl_set(lua_State*L) { SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); int i; int top = lua_gettop(L); int ret = 1; for (i = 2; i <= top; i += 2) { const char* what = luaL_checklstring(L, i, NULL); if (strcmp(what, "fd") == 0) { ret = SSL_set_fd(s, luaL_checkint(L, i + 1)); } else if (strcmp(what, "rfd") == 0) { ret = SSL_set_wfd(s, luaL_checkint(L, i + 1)); } else if (strcmp(what, "wfd") == 0) { ret = SSL_set_wfd(s, luaL_checkint(L, i + 1)); } else if (strcmp(what, "client_CA") == 0) { X509* x = CHECK_OBJECT(i + 1, X509, "openssl.x509"); ret = SSL_add_client_CA(s, x); } else if (strcmp(what, "read_ahead") == 0) { int yes = auxiliar_checkboolean(L, i + 1); SSL_set_read_ahead(s, yes); } else if (strcmp(what, "cipher_list") == 0) { const char* list = lua_tostring(L, i + 1); ret = SSL_set_cipher_list(s, list); } else if (strcmp(what, "verify_depth") == 0) { int depth = luaL_checkint(L, i + 1); SSL_set_verify_depth(s, depth); } else if (strcmp(what, "purpose") == 0) { //FIX int purpose = luaL_checkint(L, i + 1); ret = SSL_set_purpose(s, purpose); } else if (strcmp(what, "trust") == 0) { //FIX int trust = luaL_checkint(L, i + 1); ret = SSL_set_trust(s, trust); } else if (strcmp(what, "verify_result") == 0) { int result = luaL_checkint(L, i + 1); SSL_set_verify_result(s, result); } else if (strcmp(what, "hostname") == 0) { const char* hostname = luaL_checkstring(L, i + 1); SSL_set_tlsext_host_name(s, hostname); } #if OPENSSL_VERSION_NUMBER > 0x10000000L else if (strcmp(what, "state") == 0) { int l = luaL_checkint(L, 2); SSL_set_state(s, l); } #endif else luaL_argerror(L, i, "don't understand"); if (ret != 1) return openssl_pushresult(L, ret); } return 0; }
/* Set certification stuff. */ static int my_ssl_set_certs(SSL *ssl) { int have_cert= 0; MYSQL *mysql; DBUG_ENTER("my_ssl_set_certs"); /* Make sure that ssl was allocated and ssl_system was initialized */ DBUG_ASSERT(ssl != NULL); DBUG_ASSERT(my_ssl_initialized == TRUE); /* get connection for current ssl */ mysql= (MYSQL *)SSL_get_app_data(ssl); /* add cipher */ if ((mysql->options.ssl_cipher && mysql->options.ssl_cipher[0] != 0) && SSL_set_cipher_list(ssl, mysql->options.ssl_cipher) == 0) goto error; /* set cert */ if (mysql->options.ssl_cert && mysql->options.ssl_cert[0] != 0) { if (SSL_CTX_use_certificate_chain_file(SSL_context, mysql->options.ssl_cert) <= 0) goto error; have_cert= 1; } /* set key */ if (mysql->options.ssl_key && mysql->options.ssl_key[0]) { if (SSL_CTX_use_PrivateKey_file(SSL_context, mysql->options.ssl_key, SSL_FILETYPE_PEM) <= 0) goto error; /* verify key */ if (have_cert && SSL_CTX_check_private_key(SSL_context) != 1) goto error; } /* ca_file and ca_path */ if (SSL_CTX_load_verify_locations(SSL_context, mysql->options.ssl_ca, mysql->options.ssl_capath) == 0) { if (mysql->options.ssl_ca || mysql->options.ssl_capath) goto error; if (SSL_CTX_set_default_verify_paths(SSL_context) == 0) goto error; } if (mysql->options.extension && (mysql->options.extension->ssl_crl || mysql->options.extension->ssl_crlpath)) { X509_STORE *certstore; if ((certstore= SSL_CTX_get_cert_store(SSL_context))) { if (X509_STORE_load_locations(certstore, mysql->options.ssl_ca, mysql->options.ssl_capath) == 0 || X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL) == 0) goto error; } } DBUG_RETURN(0); error: my_SSL_error(mysql); DBUG_RETURN(1); }
int main () { int err; int i; int s, AcceptSocket; #ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; #endif /* */ struct sockaddr_in service; pthread_t pid; size_t client_len; SSL_CTX *ctx; SSL *ssl; X509 *client_cert; char *str; char buf[1024]; SSL_METHOD *meth; //加载EVP cipher/digest算法 SSLeay_add_ssl_algorithms (); //加载crypto/ssl错误提示 SSL_load_error_strings (); //为服务器构造TLSv1 SSL_METHOD结构 meth = SSLv3_server_method (); //建立新的SSL上下文 ctx = SSL_CTX_new (meth); if (!ctx) { ERR_print_errors_fp (stderr); exit (2); } //加载可信任证书库: 为SSL_CTX对象提供一个默认的信任证书 if ((!SSL_CTX_load_verify_locations (ctx, CAFILE, NULL)) || (!SSL_CTX_set_default_verify_paths (ctx))) { printf ("error load verify locations.\n"); exit (1); } //加载服务器端证书 if (SSL_CTX_use_certificate_file (ctx, CERTF, SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp (stderr); exit (3); } //加载服务器私钥文件 if (SSL_CTX_use_PrivateKey_file_pass (ctx, KEYF, "123456") <= 0) { ERR_print_errors_fp (stderr); exit (4); } //验证私钥与证书是否一致 if (!SSL_CTX_check_private_key (ctx)) { fprintf (stderr, "Private key does not match the certificate public key\n"); exit (5); } s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE; SSL_CTX_set_verify (ctx, s_server_verify, verify_callback_server); //当需要客户端验证的时候,服务器把CAfile里面的可信任CA证书发往客户端。 SSL_CTX_set_client_CA_list (ctx, SSL_load_client_CA_file (CAFILE)); #ifdef _WIN32 wVersionRequested = MAKEWORD (2, 2); err = WSAStartup (wVersionRequested, &wsaData); if (err != 0) { printf ("err\n"); return -1; } #endif /* */ //首先建立连接 s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s < 0) return -1; service.sin_family = AF_INET; service.sin_addr.s_addr = INADDR_ANY; //inet_addr("127.0.0.1"); service.sin_port = htons (8888); if (bind (s, (struct sockaddr *) &service, sizeof (service)) < 0) { printf ("bind() failed.\n"); close (s); return -1; } if (listen (s, 1) < 0) printf ("Error listening on socket.\n"); printf ("recv .....\n"); //openssl是不支持多线程的,需要自己做加锁处理 //参见:http://blog.csdn.net/jaylong35/article/details/6988690 lock_cs = OPENSSL_malloc (CRYPTO_num_locks () * sizeof (pthread_mutex_t)); lock_count = OPENSSL_malloc (CRYPTO_num_locks () * sizeof (long)); for (i = 0; i < CRYPTO_num_locks (); i++) { lock_count[i] = 0; pthread_mutex_init (&(lock_cs[i]), NULL); } //通过这两个设置就可以解决HTTPS多线程请求出现crash的问题 CRYPTO_set_id_callback ((unsigned long (*)()) pthreads_thread_id); CRYPTO_set_locking_callback ((void (*)()) pthreads_locking_callback); while (1) { struct timeval tv; fd_set fdset; char *str = "JDDH-JDECC3-JDCIPH-JDMD"; tv.tv_sec = 1; tv.tv_usec = 0; FD_ZERO (&fdset); FD_SET (s, &fdset); select (s + 1, &fdset, NULL, NULL, (struct timeval *) &tv); if (FD_ISSET (s, &fdset)) { AcceptSocket = accept (s, NULL, NULL); ssl = SSL_new (ctx); //提交一份自己能够支持的加密方法的列表 //SSL_set_cipher_list(ssl,"ECDH-RSA-AES256-SHA"); SSL_set_cipher_list (ssl, "RC4-MD5"); CHK_NULL (ssl); //将SSL与socket进行关联 err = SSL_set_fd (ssl, AcceptSocket); if (err > 0) { err = pthread_create (&pid, NULL, &thread_main, (void *) ssl); pthread_detach (pid); } else continue; } } SSL_CTX_free (ctx); return 0; }
bool TlsSocket::Start() { #ifdef HAVE_LIBGNUTLS gnutls_certificate_credentials_t cred; m_retCode = gnutls_certificate_allocate_credentials(&cred); if (m_retCode != 0) { ReportError("Could not create TLS context"); return false; } m_context = cred; if (m_certFile && m_keyFile) { m_retCode = gnutls_certificate_set_x509_key_file((gnutls_certificate_credentials_t)m_context, m_certFile, m_keyFile, GNUTLS_X509_FMT_PEM); if (m_retCode != 0) { ReportError("Could not load certificate or key file"); Close(); return false; } } gnutls_session_t sess; m_retCode = gnutls_init(&sess, m_isClient ? GNUTLS_CLIENT : GNUTLS_SERVER); if (m_retCode != 0) { ReportError("Could not create TLS session"); Close(); return false; } m_session = sess; m_initialized = true; const char* priority = !m_cipher.Empty() ? m_cipher.Str() : "NORMAL"; m_retCode = gnutls_priority_set_direct((gnutls_session_t)m_session, priority, nullptr); if (m_retCode != 0) { ReportError("Could not select cipher for TLS"); Close(); return false; } if (m_host) { m_retCode = gnutls_server_name_set((gnutls_session_t)m_session, GNUTLS_NAME_DNS, m_host, m_host.Length()); if (m_retCode != 0) { ReportError("Could not set host name for TLS"); Close(); return false; } } m_retCode = gnutls_credentials_set((gnutls_session_t)m_session, GNUTLS_CRD_CERTIFICATE, (gnutls_certificate_credentials_t*)m_context); if (m_retCode != 0) { ReportError("Could not initialize TLS session"); Close(); return false; } gnutls_transport_set_ptr((gnutls_session_t)m_session, (gnutls_transport_ptr_t)(size_t)m_socket); m_retCode = gnutls_handshake((gnutls_session_t)m_session); if (m_retCode != 0) { ReportError("TLS handshake failed"); Close(); return false; } m_connected = true; return true; #endif /* HAVE_LIBGNUTLS */ #ifdef HAVE_OPENSSL m_context = SSL_CTX_new(SSLv23_method()); if (!m_context) { ReportError("Could not create TLS context"); return false; } if (m_certFile && m_keyFile) { if (SSL_CTX_use_certificate_chain_file((SSL_CTX*)m_context, m_certFile) != 1) { ReportError("Could not load certificate file"); Close(); return false; } if (SSL_CTX_use_PrivateKey_file((SSL_CTX*)m_context, m_keyFile, SSL_FILETYPE_PEM) != 1) { ReportError("Could not load key file"); Close(); return false; } } m_session = SSL_new((SSL_CTX*)m_context); if (!m_session) { ReportError("Could not create TLS session"); Close(); return false; } if (!m_cipher.Empty() && !SSL_set_cipher_list((SSL*)m_session, m_cipher)) { ReportError("Could not select cipher for TLS"); Close(); return false; } if (m_host && !SSL_set_tlsext_host_name((SSL*)m_session, m_host)) { ReportError("Could not set host name for TLS"); Close(); return false; } if (!SSL_set_fd((SSL*)m_session, m_socket)) { ReportError("Could not set the file descriptor for TLS"); Close(); return false; } int error_code = m_isClient ? SSL_connect((SSL*)m_session) : SSL_accept((SSL*)m_session); if (error_code < 1) { ReportError("TLS handshake failed"); Close(); return false; } m_connected = true; return true; #endif /* HAVE_OPENSSL */ }
MONO_API int mono_btls_ssl_set_cipher_list (MonoBtlsSsl *ptr, const char *str) { return SSL_set_cipher_list(ptr->ssl, str); }
/** * Sets the cipher function to use for a specific SSL session. * Server must invoke after have accepted the incoming connection. * When not invoked defaults to DES-CBC3-MD5 * Triple-DES (168-bit key) for data encryption; MD5 for message integrity */ int SSLWrapper_set_ssl_cipher(SSLWrapper *wrapper, const char *cipher) { return SSL_set_cipher_list(wrapper->ssl, cipher); }
int DoSSLServerNegotiation(STREAM *S, int Flags) { int result=FALSE; #ifdef HAVE_LIBSSL const SSL_METHOD *Method; SSL_CTX *ctx; SSL *ssl; char *ptr; if (S) { INTERNAL_SSL_INIT(); Method=SSLv23_server_method(); if (Method) { ctx=SSL_CTX_new(Method); if (ctx) { STREAM_INTERNAL_SSL_ADD_SECURE_KEYS(S,ctx); if (Flags & LU_SSL_PFS) { OpenSSLSetupDH(ctx); OpenSSLSetupECDH(ctx); } if (Flags & LU_SSL_VERIFY_PEER) { SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, OpenSSLVerifyCallback); SSL_CTX_set_verify_depth(ctx,1); } SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); ssl=SSL_new(ctx); SSL_set_options(ssl, SSL_OP_NO_SSLv2|SSL_OP_SINGLE_DH_USE|SSL_OP_CIPHER_SERVER_PREFERENCE); //SSL_OP_NO_SSLv2, SSL_OP_NO_SSLv3, SSL_OP_NO_TLSv1 SSL_set_fd(ssl,S->in_fd); STREAMSetItem(S,"LIBUSEFUL-SSL-CTX",ssl); ptr=LibUsefulGetValue("SSL-Permitted-Ciphers"); if (ptr) SSL_set_cipher_list(ssl, ptr); SSL_set_accept_state(ssl); result=SSL_accept(ssl); if (result == TRUE) { S->Flags|=SF_SSL; OpenSSLQueryCipher(S); if (Flags & SSL_VERIFY_PEER) OpenSSLVerifyCertificate(S); } else { result=SSL_get_error(ssl,result); result=ERR_get_error(); STREAMSetValue(S, "SSL-Error", ERR_error_string(result,NULL)); result=FALSE; } } } } #endif return(result); }
//设置使用的加密套件 bool CSSLClient::SSLSetCipher(const char *pCipherName) { if (!s_bHasInitial) { assert(false); printf("%s:%s:%d, s_bHasInitial=false\n", __FUNCTION__, __FILE__, __LINE__); return false; } if (NULL == s_SSLCTX) { assert(false); printf("%s:%s:%d, s_SSLCTX=NULL\n", __FUNCTION__, __FILE__, __LINE__); return false; } if (NULL == pCipherName) { assert(false); printf("%s:%s:%d, pCipherName = NULL\n", __FUNCTION__, __FILE__, __LINE__); return false; } //保存老的加密组建 const char *pOldCipher = SSL_get_cipher(m_pSSL); char *pOldCipherTemp = NULL; if (NULL != pOldCipher) { printf("%s:%s:%d, Old cipher=%s\n", __FUNCTION__, __FILE__, __LINE__, pOldCipher); unsigned long len = strlen(pOldCipher) + 10; pOldCipherTemp = new char [len]; if (NULL == pOldCipherTemp) { printf("%s:%s:%d, NEW %d char error\n", __FUNCTION__, __FILE__, __LINE__, len); return false; } else { memset(pOldCipherTemp, 0, len); memcpy(pOldCipherTemp, pOldCipher, strlen(pOldCipher)); } } bool bChanged = false; int retVal = SSL_set_cipher_list(m_pSSL, pCipherName); if (0 == retVal) { printf("%s:%s:%d, pCipherName=%s\n", __FUNCTION__, __FILE__, __LINE__, pCipherName); printf("%s:%s:%d, New cipher=%s\n", __FUNCTION__, __FILE__, __LINE__, SSL_get_cipher(m_pSSL)); bChanged = true; } else { SSL_set_cipher_list(m_pSSL, pOldCipherTemp); } if (NULL != pOldCipherTemp) { delete pOldCipherTemp; pOldCipherTemp = NULL; } return bChanged; }
bool start_client(void) { clear_console(); printf("\n\033[32m[WIFSS] Starting Client...\033[0m\n\n"); init_global_variables(); char address[BUFFER]; char *args[BUFFER]; int16_t nbArgs = -1; do { printf("-> Server IP: "); prompt_keyboard(address); free_args(args, &nbArgs); parse_command(address, args, &nbArgs); } while(nbArgs != 1); int32_t port; char portBuffer[BUFFER]; do { printf("-> Server Port: "); prompt_keyboard(portBuffer); free_args(args, &nbArgs); parse_command(portBuffer, args, &nbArgs); if(nbArgs == 1) { port = strtoul(args[0], NULL, 10); } else { port = -1; } } while(port < 0 || port > 65535); struct addrinfo *servinfo; struct addrinfo hints; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; int16_t status = getaddrinfo(address, args[0], &hints, &servinfo); if(status != 0) { fprintf(stderr, "\n\033[31m[WIFSS] An error occurred while trying to get some information about your host: %s.\033[0m\n\n", gai_strerror(status)); exit(EXIT_FAILURE); } char buffer[BUFFER]; // Some stuff to set a timeout on `connect` int16_t sock = -1; int8_t error = 0; socklen_t lenght = sizeof(error); int16_t nbFds = -1; fd_set readfds; do { for(struct addrinfo *tmp = servinfo; tmp != NULL; tmp = tmp->ai_next) { /* Only for previous iterations */ if(sock != -1 && close(sock) == -1) { fprintf(stderr, "\n\033[31m[WIFSS] An error occurred while closing a socket: %s.\033[0m\n\n", strerror(errno)); exit(EXIT_FAILURE); } /* ____________________________ */ sock = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol); if(sock == -1) { printf("\n\033[31m[WIFSS] Error while creating an endpoint for communication with server: %s.\033[0m\n\n", strerror(errno)); return false; } // Before the connection procedure, we'll set the socket as NON-BLOCKING fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, false) | O_NONBLOCK); // Let's launch the connection procedure connect(sock, tmp->ai_addr, tmp->ai_addrlen); if(errno != EINPROGRESS) { fprintf(stderr, "\n\033[31m[WIFSS] An error occurred while running the connection procedure to: "); print_endpoint(tmp); printf(" (%s).\033[0m\n\n", strerror(errno)); continue; } // Let's now set a watch dog of 3 seconds on it FD_ZERO(&readfds); FD_SET(sock, &readfds); nbFds = select(sock + 1, &readfds, NULL, NULL, &(struct timeval){3, 0}); if(nbFds == 0) { // The timeout has been elapsed... printf("\n\033[31m[WIFSS] Error while connecting to "); print_endpoint(tmp); printf(": timeout reached.\033[0m\n"); continue; } else if(nbFds == -1) { // Again ? An error occurred... fprintf(stderr, "\n\033[31m[WIFSS] An error occurred while waiting for the connection procedure ending: %s.\033[0m\n\n", strerror(errno)); exit(EXIT_FAILURE); } else { // Fetch the buffered SYNC data [see @server/commands.c] recv(sock, buffer, BUFFER, false); if(strcmp(buffer, CLIENT_SERVER_SYNC)) { printf("%s\n", buffer); exit(EXIT_FAILURE); } } // Two cases: The connection has been established OR a f*cking new error occurred (before the timeout !)... if(getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &lenght) != 0) { fprintf(stderr, "\n\033[31m[WIFSS] An error occurred while retrieving some information about the socket: %s.\033[0m\n\n", gai_strerror(status)); exit(EXIT_FAILURE); } if(error == 0) { // For the future, let's set again the socket as BLOCKING fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, false) ^ O_NONBLOCK); // SSL stuffs SSL *ssl = SSL_new(core_variables.ctx); if(ssl == NULL) { fprintf(stderr, "\n\n\033[31mSSL Error: Couldn\'t enable the SSL layer on the socket.\n\n"); exit(EXIT_FAILURE); } if(SSL_set_cipher_list(ssl, (const char *const)"HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4") != 1) { fprintf(stderr, "\n\n\033[31mSSL Error: Couldn\'t set the ciphers list.\n\n"); exit(EXIT_FAILURE); } SSL_set_fd(ssl, sock); if(SSL_connect(ssl) <= 0) { printf("\n\n\033[31m[WIFSS] Couldn\'t create a TLS tunnel with the host...\033[0m\n\n"); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } // SSL Verification + Certificate information if(SSL_get_verify_result(ssl) != X509_V_OK) { fprintf(stderr, "\n\n\033[31mSSL Error: The result got from SSL is not valid (is your certificate correct ?).\n\n"); exit(EXIT_FAILURE); } X509 *cert = SSL_get_peer_certificate(ssl); if(cert == NULL) { fprintf(stderr, "\n\n\033[31mSSL Error: No certificate was sent by server.\n\n"); exit(EXIT_FAILURE); } printf("\n\033[34m\tTLS cipher used for this connection: %s\n", SSL_get_cipher(ssl)); char *str = NULL; printf("\tServer certificate:\n"); str = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); printf("\t\tSubject: %s\n", (str != NULL ? str : "None")); OPENSSL_free(str); str = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); printf("\t\tIssuer : %s\033[0m\n", (str != NULL ? str : "None")); OPENSSL_free(str); X509_free(cert); // __________________________________________ core_variables.ssl = ssl; printf("\n\033[32m[WIFSS] Connected to "); print_endpoint(tmp); printf(".\033[0m\n"); strncpy(buffer, "", BUFFER); if(SSL_read(ssl, buffer, BUFFER) <= 0) { printf("\n\033[31m[WIFSS] Couldn\'t get your ID from server, exiting now.\033[0m\n\n"); exit(EXIT_FAILURE); } uint16_t idTemp = get_second_args_group_as_integer(buffer); printf("\n\033[32m[WIFSS] Your ID on the server is %d.\033[0m\n\n", idTemp); /* We save the ID of the client for the future */ core_variables.client_id = idTemp; break; } else { printf("\n\033[31m[WIFSS] Error while connecting to "); print_endpoint(tmp); printf(": %s.\033[0m\n", strerror(errno)); } } if(core_variables.client_id != -1) { // Yeah... We've to `break` the loop a second time break; } else { printf("\nWould you like to retry now ? (YES / no)\n\n"); if(!prompt_yes_no(buffer, args, &nbArgs)) { printf("\n"); return false; } } } while(true);
BOOL create_ssl(int sockfd, const char* ca_crt_root, const char* ca_crt_server, const char* ca_password, const char* ca_key_server, BOOL enableclientcacheck, SSL** pp_ssl, SSL_CTX** pp_ssl_ctx) { int ssl_rc = -1; BOOL b_ssl_accepted; X509* client_cert; SSL_METHOD* meth = NULL; #if OPENSSL_VERSION_NUMBER >= 0x010100000L meth = (SSL_METHOD*)TLS_server_method(); #else meth = (SSL_METHOD*)SSLv23_server_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_use_certificate_file: %s", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl3; } if(enableclientcacheck) { SSL_CTX_set_verify(*pp_ssl_ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); SSL_CTX_set_verify_depth(*pp_ssl_ctx, 4); } SSL_CTX_load_verify_locations(*pp_ssl_ctx, ca_crt_root, NULL); if(SSL_CTX_use_certificate_file(*pp_ssl_ctx, ca_crt_server, 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_ssl3; } SSL_CTX_set_default_passwd_cb_userdata(*pp_ssl_ctx, (char*)ca_password); if(SSL_CTX_use_PrivateKey_file(*pp_ssl_ctx, ca_key_server, 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_ssl3; } 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_ssl3; } ssl_rc = SSL_CTX_set_cipher_list(*pp_ssl_ctx, "ALL"); if(ssl_rc == 0) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_CTX_set_cipher_list: %s", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl3; } SSL_CTX_set_mode(*pp_ssl_ctx, SSL_MODE_AUTO_RETRY); *pp_ssl = SSL_new(*pp_ssl_ctx); if(!*pp_ssl) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_new: %s", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl2; } ssl_rc = SSL_set_fd(*pp_ssl, sockfd); if(ssl_rc == 0) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_set_fd: %s", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl2; } ssl_rc = SSL_set_cipher_list(*pp_ssl, "ALL"); if(ssl_rc == 0) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_set_cipher_list: %s", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl2; } ssl_rc = SSL_accept(*pp_ssl); if(ssl_rc < 0) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_accept: %s", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl2; } else if(ssl_rc = 0) { goto clean_ssl1; } b_ssl_accepted = TRUE; if(enableclientcacheck) { ssl_rc = SSL_get_verify_result(*pp_ssl); if(ssl_rc != X509_V_OK) { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_get_verify_result: %s", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl1; } } if(enableclientcacheck) { X509* client_cert; client_cert = SSL_get_peer_certificate(*pp_ssl); if (client_cert != NULL) { X509_free (client_cert); } else { CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME); uTrace.Write(Trace_Error, "SSL_get_peer_certificate: %s", ERR_error_string(ERR_get_error(),NULL)); goto clean_ssl1; } } return TRUE; clean_ssl1: if(*pp_ssl && b_ssl_accepted) { SSL_shutdown(*pp_ssl); b_ssl_accepted = FALSE; } clean_ssl2: if(*pp_ssl) { SSL_free(*pp_ssl); *pp_ssl = NULL; } clean_ssl3: if(*pp_ssl_ctx) { SSL_CTX_free(*pp_ssl_ctx); *pp_ssl_ctx = NULL; } return FALSE; }
int tds_ssl_init(TDSSOCKET *tds) { #define OPENSSL_CIPHERS \ "DHE-RSA-AES256-SHA DHE-DSS-AES256-SHA " \ "AES256-SHA EDH-RSA-DES-CBC3-SHA " \ "EDH-DSS-DES-CBC3-SHA DES-CBC3-SHA " \ "DES-CBC3-MD5 DHE-RSA-AES128-SHA " \ "DHE-DSS-AES128-SHA AES128-SHA RC2-CBC-MD5 RC4-SHA RC4-MD5" SSL *con; SSL_CTX *ctx; BIO *b, *b2; int ret; const char *tls_msg; con = NULL; b = NULL; b2 = NULL; ret = 1; tds_check_wildcard_test(); tds_ssl_deinit(tds->conn); tls_msg = "initializing tls"; ctx = tds_init_openssl(); if (!ctx) goto cleanup; if (!tds_dstr_isempty(&tds->login->cafile)) { tls_msg = "loading CA file"; if (strcasecmp(tds_dstr_cstr(&tds->login->cafile), "system") == 0) ret = SSL_CTX_set_default_verify_paths(ctx); else ret = SSL_CTX_load_verify_locations(ctx, tds_dstr_cstr(&tds->login->cafile), NULL); if (ret != 1) goto cleanup; if (!tds_dstr_isempty(&tds->login->crlfile)) { X509_STORE *store = SSL_CTX_get_cert_store(ctx); X509_LOOKUP *lookup; tls_msg = "loading CRL file"; if (!(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) || (!X509_load_crl_file(lookup, tds_dstr_cstr(&tds->login->crlfile), X509_FILETYPE_PEM))) goto cleanup; X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); } /* Initialize TLS session */ tls_msg = "initializing session"; con = SSL_new(ctx); if (!con) goto cleanup; tls_msg = "creating bio"; b = BIO_new(&tds_method_login); if (!b) goto cleanup; b2 = BIO_new(&tds_method); if (!b2) goto cleanup; b->shutdown=1; b->init=1; b->num= -1; b->ptr = tds; BIO_set_conn_hostname(b, tds_dstr_cstr(&tds->login->server_host_name)); SSL_set_bio(con, b, b); b = NULL; /* use priorities... */ SSL_set_cipher_list(con, OPENSSL_CIPHERS); #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS /* this disable a security improvement but allow connection... */ SSL_set_options(con, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); #endif /* Perform the TLS handshake */ tls_msg = "handshake"; SSL_set_connect_state(con); ret = SSL_connect(con) != 1 || con->state != SSL_ST_OK; if (ret != 0) goto cleanup; /* check certificate hostname */ if (!tds_dstr_isempty(&tds->login->cafile) && tds->login->check_ssl_hostname) { X509 *cert; cert = SSL_get_peer_certificate(con); tls_msg = "checking hostname"; if (!cert || !check_hostname(cert, tds_dstr_cstr(&tds->login->server_host_name))) goto cleanup; } tdsdump_log(TDS_DBG_INFO1, "handshake succeeded!!\n"); b2->shutdown = 1; b2->init = 1; b2->num = -1; b2->ptr = tds->conn; SSL_set_bio(con, b2, b2); tds->conn->tls_session = con; tds->conn->tls_ctx = ctx; return TDS_SUCCESS; cleanup: if (b2) BIO_free(b2); if (b) BIO_free(b); if (con) { SSL_shutdown(con); SSL_free(con); } SSL_CTX_free(ctx); tdsdump_log(TDS_DBG_ERROR, "%s failed\n", tls_msg); return TDS_FAIL; }