Exemple #1
0
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;
	}
}
Exemple #2
0
/*
  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);
}
Exemple #3
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;
}
Exemple #5
0
/******************************************************************************
 ******************************************************************************
 ** 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;
}
Exemple #7
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;
}
Exemple #8
0
/*
  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);
}
Exemple #9
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;
}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #12
0
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;
	}
}
Exemple #13
0
/*
    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;
}
Exemple #14
0
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);
	}
}
Exemple #15
0
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;
	}
}
Exemple #16
0
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);
}
Exemple #17
0
/******************************************************************************
 ******************************************************************************
 ** 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);
}
Exemple #18
0
/* 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;
}
Exemple #19
0
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;
				}
		}
	}
}
Exemple #20
0
/* 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;
}
Exemple #21
0
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;
}
Exemple #22
0
/* 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));
}
Exemple #23
0
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;
}
Exemple #24
0
/*
  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;
}
Exemple #27
0
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);
}
Exemple #28
0
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;
}
Exemple #29
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);

	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;
}
Exemple #30
0
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);
}