/* allocates a new ssl object SYNOPSIS my_ssl_init mysql connection object RETURN VALUES NULL on error SSL new SSL object */ SSL *my_ssl_init(MYSQL *mysql) { int verify; SSL *ssl= NULL; DBUG_ENTER("my_ssl_init"); DBUG_ASSERT(mysql->net.vio->ssl == NULL); if (!my_ssl_initialized) my_ssl_start(mysql); if (!(ssl= SSL_new(SSL_context))) goto error; if (!SSL_set_app_data(ssl, mysql)) goto error; if (my_ssl_set_certs(ssl)) goto error; verify= (!mysql->options.ssl_ca && !mysql->options.ssl_capath) ? SSL_VERIFY_NONE : SSL_VERIFY_PEER; SSL_set_verify(ssl, verify, my_verify_callback); SSL_set_verify_depth(ssl, 1); DBUG_RETURN(ssl); error: if (ssl) SSL_free(ssl); DBUG_RETURN(NULL); }
int dtls_flow_start(struct dtls_flow *flow, const struct sa *peer, bool active) { int r, err = 0; if (!flow || !peer) return EINVAL; flow->peer = *peer; if (active) { r = SSL_connect(flow->ssl); if (r < 0) { int ssl_err = SSL_get_error(flow->ssl, r); ERR_clear_error(); if (ssl_err != SSL_ERROR_WANT_READ) { warning("dtls: SSL_connect() failed" " (err=%d)\n", ssl_err); } } check_timer(flow); } else { SSL_set_accept_state(flow->ssl); SSL_set_verify_depth(flow->ssl, 0); SSL_set_verify(flow->ssl, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verify_callback); } return err; }
void SecuredServerSession::verifyPeer(const std::string &caFile) { if (!caFile.empty()) { auto certs = SSL_load_client_CA_file(caFile.c_str()); if (!certs) throw std::runtime_error(ERR_error_string(ERR_get_error(), nullptr)); SSL_set_client_CA_list(m_SSL, certs); } SSL_set_verify(m_SSL, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, &verify_callback); SSL_set_verify_depth(m_SSL, 10); m_renegotiate = true; }
CWBool CWSecurityInitSessionClient(CWSocket sock, CWNetworkLev4Address *addrPtr, CWSafeList packetReceiveList, CWSecurityContext ctx, CWSecuritySession *sessionPtr, int *PMTUPtr) { BIO *sbio = NULL; CWNetworkLev4Address peer; int peerlen = sizeof(peer); int i; if(ctx == NULL || sessionPtr == NULL || PMTUPtr == NULL) return CWErrorRaise(CW_ERROR_WRONG_ARG, NULL); if((*sessionPtr = SSL_new(ctx)) == NULL) { CWSecurityRaiseError(CW_ERROR_CREATING); } #ifdef CW_DEBUGGING CWDebugLog("My Certificate"); PEM_write_X509(stdout, SSL_get_certificate(*sessionPtr)); #endif if((sbio = BIO_new_memory(sock, addrPtr, packetReceiveList)) == NULL) { SSL_free(*sessionPtr); CWSecurityRaiseError(CW_ERROR_CREATING); } if (getsockname(sock, (struct sockaddr*)&peer, (void *)&peerlen) < 0) { SSL_free(*sessionPtr); CWSecurityRaiseSystemError(CW_ERROR_GENERAL); } i = BIO_ctrl_set_connected(sbio, 1, &peer); //BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); // TO-DO (pass MTU?) BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_MTU, 10000, NULL); // TO-DO if we don't set a big MTU, thw DTLS implementation will // not be able to use a big certificate // Let the verify_callback catch the verify_depth error so that we get // an appropriate error in the logfile. SSL_set_verify_depth((*sessionPtr), CW_DTLS_CERT_VERIFY_DEPTH + 1); SSL_set_read_ahead( (*sessionPtr), 1); // required by DTLS implementation to avoid data loss SSL_set_bio((*sessionPtr), sbio, sbio); SSL_set_connect_state((*sessionPtr)); CWDebugLog("Before HS"); CWSecurityManageSSLError( SSL_do_handshake(*sessionPtr), *sessionPtr, SSL_free(*sessionPtr););
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; }
static int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) { const char *servername; connection *con = (connection *) SSL_get_app_data(ssl); UNUSED(al); buffer_copy_string(con->uri.scheme, "https"); if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { #if 0 /* this "error" just means the client didn't support it */ log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", "failed to get TLS server name"); #endif return SSL_TLSEXT_ERR_NOACK; } buffer_copy_string(con->tlsext_server_name, servername); buffer_to_lower(con->tlsext_server_name); /* Sometimes this is still set, confusing COMP_HTTP_HOST */ buffer_reset(con->uri.authority); config_cond_cache_reset(srv, con); config_setup_connection(srv, con); con->conditional_is_valid[COMP_SERVER_SOCKET] = 1; con->conditional_is_valid[COMP_HTTP_SCHEME] = 1; con->conditional_is_valid[COMP_HTTP_HOST] = 1; config_patch_connection(srv, con); if (NULL == con->conf.ssl_pemfile_x509 || NULL == con->conf.ssl_pemfile_pkey) { /* x509/pkey available <=> pemfile was set <=> pemfile got patched: so this should never happen, unless you nest $SERVER["socket"] */ log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", "no certificate/private key for TLS server name", con->tlsext_server_name); return SSL_TLSEXT_ERR_ALERT_FATAL; } /* first set certificate! setting private key checks whether certificate matches it */ if (!SSL_use_certificate(ssl, con->conf.ssl_pemfile_x509)) { log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:", "failed to set certificate for TLS server name", con->tlsext_server_name, ERR_error_string(ERR_get_error(), NULL)); return SSL_TLSEXT_ERR_ALERT_FATAL; } if (!SSL_use_PrivateKey(ssl, con->conf.ssl_pemfile_pkey)) { log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:", "failed to set private key for TLS server name", con->tlsext_server_name, ERR_error_string(ERR_get_error(), NULL)); return SSL_TLSEXT_ERR_ALERT_FATAL; } if (con->conf.ssl_verifyclient) { if (NULL == con->conf.ssl_ca_file_cert_names) { log_error_write(srv, __FILE__, __LINE__, "ssb:s", "SSL:", "can't verify client without ssl.ca-file for TLS server name", con->tlsext_server_name, ERR_error_string(ERR_get_error(), NULL)); return SSL_TLSEXT_ERR_ALERT_FATAL; } SSL_set_client_CA_list(ssl, SSL_dup_CA_list(con->conf.ssl_ca_file_cert_names)); /* forcing verification here is really not that useful - a client could just connect without SNI */ SSL_set_verify( ssl, SSL_VERIFY_PEER | (con->conf.ssl_verifyclient_enforce ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0), NULL ); SSL_set_verify_depth(ssl, con->conf.ssl_verifyclient_depth); } else { SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); } return SSL_TLSEXT_ERR_OK; }
/* Switch a socket to SSL communication * * Creates a SSL data structure for the connection; * Sets up callbacks and initiates a SSL handshake with the peer; * Reports error conditions and performs cleanup upon failure. * * flags: ssl flags, i.e connect or listen * verify: peer certificate verification flags * loglevel: is the level to output information about the connection * and certificates. * host: contains the dns name or ip address of the peer. Used for * verification. * cb: optional callback, this function will be called after the * handshake completes. * * Return value: 0 on success, !=0 on failure. */ int ssl_handshake(int sock, int flags, int verify, int loglevel, char *host, IntFunc cb) { int i, err, ret; ssl_appdata *data; struct threaddata *td = threaddata(); debug0("TLS: attempting SSL negotiation..."); if (!ssl_ctx && ssl_init()) { debug0("TLS: Failed. OpenSSL not initialized properly."); return -1; } /* find the socket in the list */ i = findsock(sock); if (i == -1) { debug0("TLS: socket not in socklist"); return -2; } if (td->socklist[i].ssl) { debug0("TLS: handshake not required - SSL session already established"); return 0; } td->socklist[i].ssl = SSL_new(ssl_ctx); if (!td->socklist[i].ssl || !SSL_set_fd(td->socklist[i].ssl, td->socklist[i].sock)) { debug1("TLS: cannot initiate SSL session - %s", ERR_error_string(ERR_get_error(), 0)); return -3; } /* Prepare a ssl appdata struct for the verify callback */ data = nmalloc(sizeof(ssl_appdata)); egg_bzero(data, sizeof(ssl_appdata)); data->flags = flags & (TLS_LISTEN | TLS_CONNECT); data->verify = flags & ~(TLS_LISTEN | TLS_CONNECT); data->loglevel = loglevel; data->cb = cb; strncpyz(data->host, host ? host : "", sizeof(data->host)); SSL_set_app_data(td->socklist[i].ssl, data); SSL_set_info_callback(td->socklist[i].ssl, (void *) ssl_info); /* We set this +1 to be able to report extra long chains properly. * Otherwise, OpenSSL will break the verification reporting about * missing certificates instead. The rest of the fix is in * ssl_verify() */ SSL_set_verify_depth(td->socklist[i].ssl, tls_maxdepth + 1); SSL_set_mode(td->socklist[i].ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); if (data->flags & TLS_CONNECT) { SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify); ret = SSL_connect(td->socklist[i].ssl); if (!ret) debug0("TLS: connect handshake failed."); } else { if (data->flags & TLS_VERIFYPEER) SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify); else SSL_set_verify(td->socklist[i].ssl, SSL_VERIFY_PEER, ssl_verify); ret = SSL_accept(td->socklist[i].ssl); if (!ret) debug0("TLS: accept handshake failed"); } err = SSL_get_error(td->socklist[i].ssl, ret); /* Normal condition for async I/O, similar to EAGAIN */ if (ret > 0 || err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) { debug0("TLS: handshake in progress"); return 0; } if (ERR_peek_error()) debug0("TLS: handshake failed due to the following errors: "); while ((err = ERR_get_error())) debug1("TLS: %s", ERR_error_string(err, NULL)); /* Attempt failed, cleanup and abort */ SSL_shutdown(td->socklist[i].ssl); SSL_free(td->socklist[i].ssl); td->socklist[i].ssl = NULL; nfree(data); return -4; }
SSL* SDMMD_lockssl_handshake(SDMMD_lockdown_conn *lockdown_conn, CFTypeRef hostCert, CFTypeRef deviceCert, CFTypeRef hostPrivKey, uint32_t num) { SSL *ssl = NULL; SSL_CTX *sslCTX = NULL; sdmmd_return_t result = 0x0; BIO_METHOD *bioMethod = BIO_s_socket(); BIO *bioSocket = BIO_new(bioMethod); if (bioSocket) { BIO_set_fd(bioSocket, lockdown_conn->connection, 0); X509 *cert = SDMMD__decode_certificate(hostCert); if (cert == 0) { printf("_create_ssl_context: Could not certificate.\n"); } RSA *rsa = NULL; BIO *dataBIO = SDMMD__create_bio_from_data(hostPrivKey); if (dataBIO == 0) { printf("_create_ssl_context: Could not decode host private key.\n"); if (cert) { X509_free(cert); result = 0x0; } } else { PEM_read_bio_RSAPrivateKey(dataBIO, &rsa, 0x0, 0x0); BIO_free(dataBIO); if (rsa) { if (hostCert) { sslCTX = SSL_CTX_new(SSLv3_method()); if (sslCTX) { result = SSL_CTX_use_certificate(sslCTX, cert); if (result == 0) printf("_create_ssl_context: Could not set certificate.\n"); result = SSL_CTX_use_RSAPrivateKey(sslCTX, rsa); if (result == 0) printf("_create_ssl_context: Could not set private key.\n"); } else { printf("_create_ssl_context: Could not create SSLv3 context.\n"); } } RSA_free(rsa); if (cert) X509_free(cert); if (sslCTX) { ssl = SSL_new(sslCTX); if (ssl) { if (num) { SSL_set_connect_state(ssl); } else { SSL_set_accept_state(ssl); } SSL_set_verify(ssl, 0x3, SDMMD__ssl_verify_callback); SSL_set_verify_depth(ssl, 0x0); SSL_set_bio(ssl, bioSocket, bioSocket); SSL_set_ex_data(ssl, SDMMobileDevice->peer_certificate_data_index, (void*)deviceCert); result = SSL_do_handshake(ssl); if (result == 1) { SSL_CTX_free(sslCTX); } else { uint32_t err = SSL_get_error(ssl, result); if (err) { char *reason = SDMMD_ssl_strerror(ssl, err); printf("lockssl_handshake: SSL handshake fatal lower level error %d: %s.\n", err, reason); } else { char *reason = SDMMD_ssl_strerror(ssl, 0x0); printf("lockssl_handshake: SSL handshake controlled failure %d: %s.\n", err, reason); } SSL_free(ssl); } } else { printf("_create_ssl: Could not create SSL thing.\n"); } } } else { printf("_create_ssl_context: Could not decode private key.\n"); if (cert) { X509_free(cert); result = 0x0; } } } } else { printf("lockssl_handshake: Could not create SSL bio.\n"); } return ssl; }