static void sr_ssl_ctx_info_callback(const SSL *ssl, int event, int ret) { struct tls_extra_data* data = 0; int tls_dbg; if (event & SSL_CB_HANDSHAKE_START) { tls_dbg = cfg_get(tls, tls_cfg, debug); LOG(tls_dbg, "SSL handshake started\n"); if(data==0) data = (struct tls_extra_data*)SSL_get_app_data(ssl); if(data->flags & F_TLS_CON_HANDSHAKED) { LOG(tls_dbg, "SSL renegotiation initiated by client\n"); data->flags |= F_TLS_CON_RENEGOTIATION; } } if (event & SSL_CB_HANDSHAKE_DONE) { tls_dbg = cfg_get(tls, tls_cfg, debug); if(data==0) data = (struct tls_extra_data*)SSL_get_app_data(ssl); LOG(tls_dbg, "SSL handshake done\n"); #if OPENSSL_VERSION_NUMBER < 0x010100000L /* CVE-2009-3555 - disable renegotiation */ if (ssl->s3) { LOG(tls_dbg, "SSL disable renegotiation\n"); ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; } #endif data->flags |= F_TLS_CON_HANDSHAKED; } }
/* establish SSL connection between client and server SYNOPSIS my_ssl_connect ssl ssl object RETURN VALUES 0 success 1 error */ int my_ssl_connect(SSL *ssl) { my_bool blocking; MYSQL *mysql; long rc; my_bool try_connect= 1; DBUG_ENTER("my_ssl_connect"); DBUG_ASSERT(ssl != NULL); mysql= (MYSQL *)SSL_get_app_data(ssl); CLEAR_CLIENT_ERROR(mysql); /* Set socket to non blocking */ if (!(blocking= vio_is_blocking(mysql->net.vio))) vio_blocking(mysql->net.vio, FALSE, 0); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), mysql->options.connect_timeout); SSL_set_fd(ssl, mysql->net.vio->sd); while (try_connect && (rc= SSL_connect(ssl)) == -1) { switch(SSL_get_error(ssl, rc)) { case SSL_ERROR_WANT_READ: if (vio_wait_or_timeout(mysql->net.vio, TRUE, mysql->options.connect_timeout) < 1) try_connect= 0; break; case SSL_ERROR_WANT_WRITE: if (vio_wait_or_timeout(mysql->net.vio, TRUE, mysql->options.connect_timeout) < 1) try_connect= 0; break; default: try_connect= 0; } } if (rc != 1) { my_SSL_error(mysql); DBUG_RETURN(1); } rc= SSL_get_verify_result(ssl); if (rc != X509_V_OK) { my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(rc)); /* restore blocking mode */ if (!blocking) vio_blocking(mysql->net.vio, FALSE, 0); DBUG_RETURN(1); } vio_reset(mysql->net.vio, VIO_TYPE_SSL, mysql->net.vio->sd, 0, 0); mysql->net.vio->ssl= ssl; DBUG_RETURN(0); }
static int verify_callback(int ok, X509_STORE_CTX *store) { SSL *ssl; struct stream_fd *sfd; struct packet_stream *ps; struct call_media *media; ssl = X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx()); sfd = SSL_get_app_data(ssl); if (sfd->dtls.ssl != ssl) return 0; ps = sfd->stream; if (!ps) return 0; if (PS_ISSET(ps, FINGERPRINT_VERIFIED)) return 1; media = ps->media; if (!media) return 0; if (ps->dtls_cert) X509_free(ps->dtls_cert); ps->dtls_cert = X509_dup(X509_STORE_CTX_get_current_cert(store)); if (!media->fingerprint.hash_func) return 1; /* delay verification */ if (dtls_verify_cert(ps)) return 0; return 1; }
static int my_verify_callback(int ok, X509_STORE_CTX *ctx) { X509 *check_cert; SSL *ssl; MYSQL *mysql; ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); mysql= (MYSQL *)SSL_get_app_data(ssl); /* skip verification if no ca_file/path was specified */ if (!mysql->options.ssl_ca && !mysql->options.ssl_capath) { ok= 1; return 1; } if (!ok) { uint depth; if (!(check_cert= X509_STORE_CTX_get_current_cert(ctx))) return 0; depth= X509_STORE_CTX_get_error_depth(ctx); if (depth == 0) ok= 1; } return ok; }
/****************************************************************************** ****************************************************************************** ** Higher Level SSL_CTX Wrappers ** ****************************************************************************** ******************************************************************************/ static void log_callback(const SSL *ssl, int where, int ret) { const char *retstr = ""; int should_log = 0; lcbio_SOCKET *sock = SSL_get_app_data(ssl); /* Ignore low-level SSL stuff */ if (where & SSL_CB_ALERT) { should_log = 1; } if (where == SSL_CB_HANDSHAKE_START || where == SSL_CB_HANDSHAKE_DONE) { should_log = 1; } if ((where & SSL_CB_EXIT) && ret == 0) { should_log = 1; } if (!should_log) { return; } retstr = SSL_alert_type_string(ret); lcb_log(LOGARGS(ssl, LCB_LOG_TRACE), "sock=%p: ST(0x%x). %s. R(0x%x)%s", (void*)sock, where, SSL_state_string_long(ssl), ret, retstr); if (where == SSL_CB_HANDSHAKE_DONE) { lcb_log(LOGARGS(ssl, LCB_LOG_DEBUG), "sock=%p. Using SSL version %s. Cipher=%s", (void*)sock, SSL_get_version(ssl), SSL_get_cipher_name(ssl)); } }
static int ma_tls_session_cb(SSL *ssl, SSL_SESSION *session) { MYSQL *mysql; MA_SSL_SESSION *stored_session; int i; mysql= (MYSQL *)SSL_get_app_data(ssl); /* check if we already stored session key */ if ((stored_session= ma_tls_get_session(mysql))) { SSL_SESSION_free(stored_session->session); stored_session->session= session; return 1; } for (i=0; i < ma_tls_session_cache_size; i++) { if (!ma_tls_sessions[i].session) { ma_md4_hash(mysql->host, mysql->user, mysql->port, ma_tls_sessions[i].md4_hash); ma_tls_sessions[i].session= session; } return 1; } return 0; }
int tls_session_verify_dn(X509_STORE_CTX *ctx) { SSL *ssl = X509_STORE_CTX_get_app_data(ctx); TLSSession *self = SSL_get_app_data(ssl); gboolean match = FALSE; GList *current_dn = self->ctx->trusted_dn_list; X509 *cert = X509_STORE_CTX_get_current_cert(ctx); GString *dn; if (!current_dn || !cert) return TRUE; dn = g_string_sized_new(128); tls_x509_format_dn(X509_get_subject_name(cert), dn); do { if (g_pattern_match_simple((const gchar *) current_dn->data, dn->str)) { match = TRUE; break; } } while ((current_dn = g_list_next(current_dn)) != NULL); return match; }
/* establish SSL connection between client and server SYNOPSIS my_ssl_connect ssl ssl object RETURN VALUES 0 success 1 error */ int my_ssl_connect(SSL *ssl) { my_bool blocking; MYSQL *mysql; DBUG_ENTER("my_ssl_connect"); DBUG_ASSERT(ssl != NULL); mysql= (MYSQL *)SSL_get_app_data(ssl); CLEAR_CLIENT_ERROR(mysql); /* Set socket to blocking if not already set */ if (!(blocking= vio_is_blocking(mysql->net.vio))) vio_blocking(mysql->net.vio, TRUE); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), mysql->options.connect_timeout); SSL_set_fd(ssl, mysql->net.vio->sd); if (SSL_connect(ssl) != 1) { my_SSL_error(mysql); /* restore blocking mode */ if (!blocking) vio_blocking(mysql->net.vio, FALSE); DBUG_RETURN(1); } vio_reset(mysql->net.vio, VIO_TYPE_SSL, mysql->net.vio->sd, 0, 0); mysql->net.vio->ssl= ssl; DBUG_RETURN(0); }
long ssl_io_data_cb(BIO *bio, int cmd, const char *argp, int argi, long argl, long rc) { SSL *ssl; conn_rec *c; server_rec *s; if ((ssl = (SSL *)BIO_get_callback_arg(bio)) == NULL) return rc; if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL) return rc; s = c->server; if ( cmd == (BIO_CB_WRITE|BIO_CB_RETURN) || cmd == (BIO_CB_READ |BIO_CB_RETURN) ) { if (rc >= 0) { ssl_log(s, SSL_LOG_DEBUG, "%s: %s %ld/%d bytes %s BIO#%08lX [mem: %08lX] %s", SSL_LIBRARY_NAME, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"), rc, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"), (long)bio, (long)argp, (argp != NULL ? "(BIO dump follows)" : "(Ops, no memory buffer?)")); if (argp != NULL) ssl_io_data_dump(s, argp, rc); } else { ssl_log(s, SSL_LOG_DEBUG, "%s: I/O error, %d bytes expected to %s on BIO#%08lX [mem: %08lX]", SSL_LIBRARY_NAME, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"), (long)bio, (long)argp); } } return rc; }
static int ssl_io_hook_writev(BUFF *fb, const struct iovec *iov, int iovcnt) { SSL *ssl; conn_rec *c; int rc; if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) { rc = SSL_writev(ssl, iov, iovcnt); /* * Simulate an EINTR in case OpenSSL wants to write more. */ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE) errno = EINTR; /* * Log SSL errors */ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_SSL) { c = (conn_rec *)SSL_get_app_data(ssl); ssl_log(c->server, SSL_LOG_ERROR|SSL_ADD_SSLERR, "SSL error on writing data"); } /* * writev(2) returns only the generic error number -1 */ if (rc < 0) rc = -1; } else rc = writev(fb->fd, iov, iovcnt); return rc; }
static int ssl_io_hook_read(BUFF *fb, char *buf, int len) { SSL *ssl; conn_rec *c; int rc; if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) { rc = SSL_read(ssl, buf, len); /* * Simulate an EINTR in case OpenSSL wants to read more. * (This is usually the case when the client forces an SSL * renegotation which is handled implicitly by OpenSSL.) */ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ) errno = EINTR; /* * Log SSL errors */ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_SSL) { c = (conn_rec *)SSL_get_app_data(ssl); ssl_log(c->server, SSL_LOG_ERROR|SSL_ADD_SSLERR, "SSL error on reading data"); } /* * read(2) returns only the generic error number -1 */ if (rc < 0) rc = -1; } else rc = read(fb->fd_in, buf, len); return rc; }
static void ssl_info_callback(const SSL *ssl, int where, int ret) { UNUSED(ret); if (0 != (where & SSL_CB_HANDSHAKE_START)) { connection *con = SSL_get_app_data(ssl); ++con->renegotiations; } }
/* Set the ephemeral DH key */ static DH *dhcallback(SSL *handle, int isExport, int keyLength) { OpenSocket *osp; OpenConfig *cfg; osp = (OpenSocket*) SSL_get_app_data(handle); cfg = osp->sock->ssl->config; return cfg->dhKey; }
static void transport_ssl_cb(SSL* ssl, int where, int ret) { rdpTransport *transport; if ((where | SSL_CB_ALERT) && (ret == 561)) { transport = (rdpTransport *) SSL_get_app_data(ssl); if (!freerdp_get_last_error(transport->context)) freerdp_set_last_error(transport->context, FREERDP_ERROR_AUTHENTICATION_FAILED); } }
static void ssl_info_callback(const SSL *ssl, int where, int ret) { UNUSED(ret); if (0 != (where & SSL_CB_HANDSHAKE_START)) { connection *con = SSL_get_app_data(ssl); ++con->renegotiations; } else if (0 != (where & SSL_CB_HANDSHAKE_DONE)) { ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; } }
void engine_free(ms_conn* conn) { ms_cert_buf* cert_buf = (ms_cert_buf*)SSL_get_app_data(conn->ssl); if(cert_buf) { OPENSSL_free(cert_buf->buf); free(cert_buf); } SSL_free(conn->ssl); SSL_CTX_free(conn->ctx); free(conn); }
/****************************************************************************** ****************************************************************************** ** Higher Level SSL_CTX Wrappers ** ****************************************************************************** ******************************************************************************/ static void log_callback(const SSL *ssl, int where, int ret) { const char *retstr = ""; lcbio_SOCKET *sock = SSL_get_app_data(ssl); if (where & SSL_CB_ALERT) { retstr = SSL_alert_type_string(ret); } lcb_log(LOGARGS(ssl, LCB_LOG_TRACE), "sock=%p: ST(0x%x). %s. R(0x%x)%s", (void*)sock, where, SSL_state_string_long(ssl), ret, retstr); }
/* Count allocated memory for SSL. This excludes memory allocated by OpenSSL's * family of malloc functions. */ int expmem_tls() { int i, tot; struct threaddata *td = threaddata(); /* currently it's only the appdata structs allocated by ssl_handshake() */ for (i = 0, tot = 0; i < td->MAXSOCKS; i++) if (!(td->socklist[i].flags & (SOCK_UNUSED | SOCK_TCL))) if (td->socklist[i].ssl && SSL_get_app_data(td->socklist[i].ssl)) tot += sizeof(ssl_appdata); return tot; }
static void transport_ssl_cb(SSL* ssl, int where, int ret) { if (where & SSL_CB_ALERT) { rdpTransport* transport = (rdpTransport*) SSL_get_app_data(ssl); switch (ret) { case (SSL3_AL_FATAL << 8) | SSL_AD_ACCESS_DENIED: { if (!freerdp_get_last_error(transport->context)) { WLog_Print(transport->log, WLOG_ERROR, "%s: ACCESS DENIED", __FUNCTION__); freerdp_set_last_error(transport->context, FREERDP_ERROR_AUTHENTICATION_FAILED); } } break; case (SSL3_AL_FATAL << 8) | SSL_AD_INTERNAL_ERROR: { if (transport->NlaMode) { UINT32 kret = 0; #ifdef WITH_GSSAPI if ((strlen(transport->settings->Domain) != 0) && (strncmp(transport->settings->Domain, ".", 1) != 0)) { kret = transport_krb5_check_account(transport, transport->settings->Username, transport->settings->Domain, transport->settings->Password); } else #endif /* WITH_GSSAPI */ kret = FREERDP_ERROR_CONNECT_PASSWORD_CERTAINLY_EXPIRED; if (!freerdp_get_last_error(transport->context)) freerdp_set_last_error(transport->context, kret); } break; case (SSL3_AL_WARNING << 8) | SSL3_AD_CLOSE_NOTIFY: break; default: WLog_Print(transport->log, WLOG_WARN, "Unhandled SSL error (where=%d, ret=%d [%s, %s])", where, ret, SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret)); break; } } } }
/* OpenSSL cert verification callback. This is invoked for *each* * error which is encoutered whilst verifying the cert chain; multiple * invocations for any particular cert in the chain are possible. */ static int verify_callback(int ok, X509_STORE_CTX *ctx) { /* OpenSSL, living in its own little happy world of global state, * where userdata was just a twinkle in the eye of an API designer * yet to be born. Or... "Seriously, wtf?" */ SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); ne_session *sess = SSL_get_app_data(ssl); int depth = X509_STORE_CTX_get_error_depth(ctx); int err = X509_STORE_CTX_get_error(ctx); int failures = 0; /* If there's no error, nothing to do here. */ if (ok) return ok; NE_DEBUG(NE_DBG_SSL, "ssl: Verify callback @ %d => %d\n", depth, err); /* Map the error code onto any of the exported cert validation * errors, if possible. */ switch (err) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: case X509_V_ERR_CERT_UNTRUSTED: case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: failures |= NE_SSL_UNTRUSTED; break; case X509_V_ERR_CERT_NOT_YET_VALID: failures |= depth > 0 ? NE_SSL_BADCHAIN : NE_SSL_NOTYETVALID; break; case X509_V_ERR_CERT_HAS_EXPIRED: failures |= depth > 0 ? NE_SSL_BADCHAIN : NE_SSL_EXPIRED; break; case X509_V_OK: break; default: /* Clear the failures bitmask so check_certificate knows this * is a bailout. */ sess->ssl_context->failures |= NE_SSL_UNHANDLED; NE_DEBUG(NE_DBG_SSL, "ssl: Unhandled verification error %d -> %s\n", err, X509_verify_cert_error_string(err)); return 0; } sess->ssl_context->failures |= failures; NE_DEBUG(NE_DBG_SSL, "ssl: Verify failures |= %d => %d\n", failures, sess->ssl_context->failures); return 1; }
static int openssl_sni_servername_cb (SSL *ssl, int *ad, void *arg) { ret_t ret; int re; const char *servername; cherokee_connection_t *conn; cherokee_buffer_t tmp; cherokee_server_t *srv = SRV(arg); cherokee_virtual_server_t *vsrv = NULL; UNUSED(ad); /* Get the pointer to the socket */ conn = SSL_get_app_data (ssl); if (unlikely (conn == NULL)) { LOG_ERROR (CHEROKEE_ERROR_SSL_SOCKET, ssl); return SSL_TLSEXT_ERR_ALERT_FATAL; } cherokee_buffer_init(&tmp); cherokee_buffer_ensure_size(&tmp, 40); /* Read the SNI server name */ servername = SSL_get_servername (ssl, TLSEXT_NAMETYPE_host_name); if (servername == NULL) { /* Set the server name to the IP address if we couldn't get the host name via SNI */ cherokee_socket_ntop (&conn->socket, tmp.buf, tmp.size); TRACE (ENTRIES, "No SNI: Did not provide a server name, using IP='%s' as servername.\n", tmp.buf); } else { cherokee_buffer_add (&tmp, servername, strlen(servername)); TRACE (ENTRIES, "SNI: Switching to servername='%s'\n", servername); } /* Look up and change the vserver */ ret = cherokee_cryptor_libssl_find_vserver(ssl, srv, &tmp, conn); if (ret != ret_ok) { re = SSL_TLSEXT_ERR_NOACK; } else { re = SSL_TLSEXT_ERR_OK; } cherokee_buffer_mrproper (&tmp); return re; }
/* SSL info callback, this is used to trace engine state changes * and to check when the handshake is finished, so we can display * some cipher and session information and process callbacks. */ void ssl_info(SSL *ssl, int where, int ret) { int sock; X509 *cert; char buf[256]; ssl_appdata *data; SSL_CIPHER *cipher; int secret, processed; /* We're doing non-blocking IO, so we check here if the handshake has finished */ if (where & SSL_CB_HANDSHAKE_DONE) { if (!(data = (ssl_appdata *) SSL_get_app_data(ssl))) return; /* Callback for completed handshake. Cheaper and more convenient than using H_tls */ sock = SSL_get_fd(ssl); if (data->cb) data->cb(sock); /* Call TLS binds. We allow scripts to take over or disable displaying of certificate information. */ if (check_tcl_tls(sock)) return; putlog(data->loglevel, "*", "TLS: handshake successful. Secure connection " "established."); if ((cert = SSL_get_peer_certificate(ssl))) ssl_showcert(cert, data->loglevel); else putlog(data->loglevel, "*", "TLS: peer did not present a certificate"); /* Display cipher information */ cipher = SSL_get_current_cipher(ssl); processed = SSL_CIPHER_get_bits(cipher, &secret); putlog(data->loglevel, "*", "TLS: cipher used: %s %s; %d bits (%d secret)", SSL_CIPHER_get_name(cipher), SSL_CIPHER_get_version(cipher), processed, secret); /* secret are the actually secret bits. If processed and secret differ, the rest of the bits are fixed, i.e. for limited export ciphers */ /* More verbose information, for debugging only */ SSL_CIPHER_description(cipher, buf, sizeof buf); debug1("TLS: cipher details: %s", buf); } /* Display the state of the engine for debugging purposes */ debug1("TLS: state change: %s", SSL_state_string_long(ssl)); }
static unsigned int psk_callback(SSL *ssl, const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len) { struct openconnect_info *vpninfo = SSL_get_app_data(ssl); if (!vpninfo || max_identity_len < 4 || max_psk_len < PSK_KEY_SIZE) return 0; vpn_progress(vpninfo, PRG_TRACE, _("PSK callback\n")); snprintf(identity, max_psk_len, "psk"); memcpy(psk, vpninfo->dtls_secret, PSK_KEY_SIZE); return PSK_KEY_SIZE; }
/* establish SSL connection between client and server SYNOPSIS my_ssl_connect ssl ssl object RETURN VALUES 0 success 1 error */ int my_ssl_connect(SSL *ssl) { my_bool blocking; MYSQL *mysql; long rc; DBUG_ENTER("my_ssl_connect"); DBUG_ASSERT(ssl != NULL); mysql= (MYSQL *)SSL_get_app_data(ssl); CLEAR_CLIENT_ERROR(mysql); /* Set socket to blocking if not already set */ if (!(blocking= vio_is_blocking(mysql->net.vio))) vio_blocking(mysql->net.vio, TRUE, 0); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), mysql->options.connect_timeout); SSL_set_fd(ssl, mysql->net.vio->sd); if (SSL_connect(ssl) != 1) { my_SSL_error(mysql); /* restore blocking mode */ if (!blocking) vio_blocking(mysql->net.vio, FALSE, 0); DBUG_RETURN(1); } rc= SSL_get_verify_result(ssl); if (rc != X509_V_OK) { my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(rc)); /* restore blocking mode */ if (!blocking) vio_blocking(mysql->net.vio, FALSE, 0); DBUG_RETURN(1); } vio_reset(mysql->net.vio, VIO_TYPE_SSL, mysql->net.vio->sd, 0, 0); mysql->net.vio->ssl= ssl; DBUG_RETURN(0); }
my_bool ma_tls_connect(MARIADB_TLS *ctls) { SSL *ssl = (SSL *)ctls->ssl; my_bool blocking; MYSQL *mysql; MARIADB_PVIO *pvio; int rc; mysql= (MYSQL *)SSL_get_app_data(ssl); pvio= mysql->net.pvio; /* Set socket to blocking if not already set */ if (!(blocking= pvio->methods->is_blocking(pvio))) pvio->methods->blocking(pvio, TRUE, 0); SSL_clear(ssl); SSL_SESSION_set_timeout(SSL_get_session(ssl), mysql->options.connect_timeout); SSL_set_fd(ssl, mysql_get_socket(mysql)); if (SSL_connect(ssl) != 1) { ma_tls_set_error(mysql); /* restore blocking mode */ if (!blocking) pvio->methods->blocking(pvio, FALSE, 0); return 1; } if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT)) { rc= SSL_get_verify_result(ssl); if (rc != X509_V_OK) { my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(rc)); /* restore blocking mode */ if (!blocking) pvio->methods->blocking(pvio, FALSE, 0); return 1; } } pvio->ctls->ssl= ctls->ssl= (void *)ssl; return 0; }
int ma_ssl_verify_server_cert(MARIADB_SSL *cssl) { X509 *cert; MYSQL *mysql; MARIADB_PVIO *pvio; SSL *ssl; char *p1, *p2, buf[256]; if (!cssl || !cssl->ssl) return 1; ssl= (SSL *)cssl->ssl; mysql= (MYSQL *)SSL_get_app_data(ssl); pvio= mysql->net.pvio; if (!mysql->host) { pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, "Invalid (empty) hostname"); return 1; } if (!(cert= SSL_get_peer_certificate(ssl))) { pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, "Unable to get server certificate"); return 1; } X509_NAME_oneline(X509_get_subject_name(cert), buf, 256); X509_free(cert); /* Extract the server name from buffer: Format: ....CN=/hostname/.... */ if ((p1= strstr(buf, "/CN="))) { p1+= 4; if ((p2= strchr(p1, '/'))) *p2= 0; if (!strcmp(mysql->host, p1)) return(0); } pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, "Validation of SSL server certificate failed"); return 1; }
static int ssl_verify_callback(int goodcert, X509_STORE_CTX *x509) { SSL *ssl= X509_STORE_CTX_get_ex_data(x509, SSL_get_ex_data_X509_STORE_CTX_idx() ); struct tls_info *info=SSL_get_app_data(ssl); if (info->peer_verify_domain || get_peer_verify_level(info)) { if (!goodcert) return (0); info->certificate_verified=1; } return (1); }
static SSL_SESSION * _evhtp_ssl_get_scache_ent(SSL * ssl, unsigned char * sid, int sid_len, int * copy) { evhtp_connection_t * connection; evhtp_ssl_cfg_t * cfg; SSL_SESSION * sess; connection = (evhtp_connection_t * )SSL_get_app_data(ssl); cfg = connection->htp->ssl_cfg; sess = NULL; if (cfg->scache_get) { sess = (cfg->scache_get)(connection, sid, sid_len); } *copy = 0; return sess; }
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); config_patch_connection(srv, con, COMP_SERVER_SOCKET); config_patch_connection(srv, con, COMP_HTTP_SCHEME); config_patch_connection(srv, con, COMP_HTTP_HOST); if (NULL == con->conf.ssl_ctx) { /* ssl_ctx <=> pemfile was set <=> ssl_ctx got patched: so this should never happen */ log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", "null SSL_CTX for TLS server name", con->tlsext_server_name); return SSL_TLSEXT_ERR_ALERT_FATAL; } /* switch to new SSL_CTX in reaction to a client's server_name extension */ if (con->conf.ssl_ctx != SSL_set_SSL_CTX(ssl, con->conf.ssl_ctx)) { log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", "failed to set SSL_CTX for TLS server name", con->tlsext_server_name); return SSL_TLSEXT_ERR_ALERT_FATAL; } return SSL_TLSEXT_ERR_OK; }
int my_ssl_verify_server_cert(SSL *ssl) { X509 *cert; MYSQL *mysql; char *p1, *p2, buf[256]; DBUG_ENTER("my_ssl_verify_server_cert"); mysql= (MYSQL *)SSL_get_app_data(ssl); if (!mysql->host) { my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_SSL_CONNECTION_ERROR), "Invalid (empty) hostname"); DBUG_RETURN(1); } if (!(cert= SSL_get_peer_certificate(ssl))) { my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_SSL_CONNECTION_ERROR), "Unable to get server certificate"); DBUG_RETURN(1); } X509_NAME_oneline(X509_get_subject_name(cert), buf, 256); X509_free(cert); /* Extract the server name from buffer: Format: ....CN=/hostname/.... */ if ((p1= strstr(buf, "/CN="))) { p1+= 4; if ((p2= strchr(p1, '/'))) *p2= 0; if (!strcmp(mysql->host, p1)) DBUG_RETURN(0); } my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_SSL_CONNECTION_ERROR), "Validation of SSL server certificate failed"); DBUG_RETURN(1); }