Example #1
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);
}
Example #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);
}
Example #3
0
/* {{{ my_bool ma_pvio_start_ssl */
my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio)
{
  if (!pvio || !pvio->mysql)
    return 1;
  CLEAR_CLIENT_ERROR(pvio->mysql);
  if (!(pvio->cssl= ma_pvio_ssl_init(pvio->mysql)))
  {
    return 1;
  }
  if (ma_pvio_ssl_connect(pvio->cssl))
  {
    my_free(pvio->cssl);
    pvio->cssl= NULL;
    return 1;
  }
  if ((pvio->mysql->options.ssl_ca || pvio->mysql->options.ssl_capath) &&
        (pvio->mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
         ma_pvio_ssl_verify_server_cert(pvio->cssl))
    return 1;

  if (pvio->mysql->options.extension &&
      (pvio->mysql->options.extension->ssl_fp || pvio->mysql->options.extension->ssl_fp_list))
  {

    if (ma_pvio_ssl_check_fp(pvio->cssl, 
          pvio->mysql->options.extension->ssl_fp,
          pvio->mysql->options.extension->ssl_fp_list))
      return 1;
  }

  return 0;
}
Example #4
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);
}
Example #5
0
/* {{{ my_bool ma_pvio_start_ssl */
my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio)
{
  if (!pvio || !pvio->mysql)
    return 1;
  CLEAR_CLIENT_ERROR(pvio->mysql);
  if (!(pvio->ctls= ma_pvio_tls_init(pvio->mysql)))
  {
    return 1;
  }
  if (ma_pvio_tls_connect(pvio->ctls))
  {
    free(pvio->ctls);
    pvio->ctls= NULL;
    return 1;
  }

  /* default behaviour:
     1. peer certificate verification
     2. verify CN (requires option ssl_verify_check)
     3. verrify finger print
  */
  if ((pvio->mysql->options.ssl_ca || pvio->mysql->options.ssl_capath) &&
        (pvio->mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
         ma_pvio_tls_verify_server_cert(pvio->ctls))
    return 1;

  if (pvio->mysql->options.extension &&
      (pvio->mysql->options.extension->tls_fp && pvio->mysql->options.extension->tls_fp[0]) ||
      (pvio->mysql->options.extension->tls_fp_list && pvio->mysql->options.extension->tls_fp_list[0]))
  {

    if (ma_pvio_tls_check_fp(pvio->ctls, 
          pvio->mysql->options.extension->tls_fp,
          pvio->mysql->options.extension->tls_fp_list))
      return 1;
  }

  return 0;
}
Example #6
0
static int my_verify_callback(gnutls_session_t ssl)
{
  unsigned int status;
  const gnutls_datum_t *cert_list;
  unsigned int cert_list_size;
  int ret;
  MYSQL *mysql= (MYSQL *)gnutls_session_get_ptr(ssl);
  MARIADB_PVIO *pvio= mysql->net.pvio;
  gnutls_x509_crt_t cert;
  const char *hostname;

  /* read hostname */
  hostname = mysql->host;

  /* skip verification if no ca_file/path was specified */
  if (!mysql->options.ssl_ca)
    return 0;

  /* This verification function uses the trusted CAs in the credentials
   * structure. So you must have installed one or more CA certificates.
   */
  ret = gnutls_certificate_verify_peers2 (ssl, &status);
  if (ret < 0)
  {
    pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "CA verification failed");
    return GNUTLS_E_CERTIFICATE_ERROR;
  }

//  mysql->net.vio->status= status;

  if (status & GNUTLS_CERT_INVALID)
  {
    return GNUTLS_E_CERTIFICATE_ERROR;
  }
  /* Up to here the process is the same for X.509 certificates and
   * OpenPGP keys. From now on X.509 certificates are assumed. This can
   * be easily extended to work with openpgp keys as well.
   */
  if (gnutls_certificate_type_get (ssl) != GNUTLS_CRT_X509)
  {
    pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Expected X509 certificate");
    return GNUTLS_E_CERTIFICATE_ERROR;
  }
  if (gnutls_x509_crt_init (&cert) < 0)
  {
    pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Error during certificate initialization");
    return GNUTLS_E_CERTIFICATE_ERROR;
  }
  cert_list = gnutls_certificate_get_peers (ssl, &cert_list_size);
  if (cert_list == NULL)
  {
    gnutls_x509_crt_deinit (cert);
    pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "No certificate found");
    return GNUTLS_E_CERTIFICATE_ERROR;
  }
  if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
  {
    gnutls_x509_crt_deinit (cert);
    pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Unknown SSL error");
    return GNUTLS_E_CERTIFICATE_ERROR;
  }

  if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
      !gnutls_x509_crt_check_hostname (cert, hostname))
  {
    gnutls_x509_crt_deinit (cert);
    pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Hostname in certificate doesn't match");
    return GNUTLS_E_CERTIFICATE_ERROR;
  }
  gnutls_x509_crt_deinit (cert);
  /* notify gnutls to continue handshake normally */

  CLEAR_CLIENT_ERROR(mysql);
  return 0;
}