Example #1
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;
}
Example #2
0
static int ma_tls_set_certs(MYSQL *mysql)
{
  char *certfile= mysql->options.ssl_cert,
       *keyfile= mysql->options.ssl_key;
  
  /* add cipher */
  if ((mysql->options.ssl_cipher && 
        mysql->options.ssl_cipher[0] != 0) &&
      SSL_CTX_set_cipher_list(SSL_context, mysql->options.ssl_cipher) == 0)
    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 (keyfile && !certfile)
    certfile= keyfile;
  if (certfile && !keyfile)
    keyfile= certfile;

  /* set cert */
  if (certfile  && certfile[0] != 0)  
    if (SSL_CTX_use_certificate_file(SSL_context, certfile, SSL_FILETYPE_PEM) != 1)
      goto error; 

  /* If the private key file is encrypted, we need to register a callback function
   * for providing password. */
  if (OPT_HAS_EXT_VAL(mysql, tls_pw))
  {
    SSL_CTX_set_default_passwd_cb_userdata(SSL_context, (void *)mysql->options.extension->tls_pw);
    SSL_CTX_set_default_passwd_cb(SSL_context, ma_tls_get_password);
  }

  if (keyfile && keyfile[0])
  {
    if (SSL_CTX_use_PrivateKey_file(SSL_context, keyfile, SSL_FILETYPE_PEM) != 1)
    {
      unsigned long err= ERR_peek_error();
      if (!(ERR_GET_LIB(err) == ERR_LIB_X509 &&
	  ERR_GET_REASON(err) == X509_R_CERT_ALREADY_IN_HASH_TABLE))
        goto error;
    }
  }
  if (OPT_HAS_EXT_VAL(mysql, tls_pw))
  {
    SSL_CTX_set_default_passwd_cb_userdata(SSL_context, NULL);
    SSL_CTX_set_default_passwd_cb(SSL_context, NULL);
  }
  /* verify key */
  if (certfile && !SSL_CTX_check_private_key(SSL_context))
    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.extension->ssl_crl,
                                               mysql->options.extension->ssl_crlpath) == 0)
        goto error;

      X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
    }
  }
  return 0;

error:
  ma_tls_set_error(mysql);
  return 1;
}
Example #3
0
my_bool ma_tls_connect(MARIADB_TLS *ctls)
{
  SSL *ssl = (SSL *)ctls->ssl;
  my_bool blocking, try_connect= 1;
  MYSQL *mysql;
  MARIADB_PVIO *pvio;
  int rc;
#if OPENSSL_USE_BIOMETHOD
  BIO_METHOD *bio_method= NULL;
  BIO *bio;
#endif

  mysql= (MYSQL *)SSL_get_app_data(ssl);
  pvio= mysql->net.pvio;

  /* Set socket to non blocking if not already set */
  if (!(blocking= pvio->methods->is_blocking(pvio)))
    pvio->methods->blocking(pvio, FALSE, 0);

  SSL_clear(ssl);

#if OPENSSL_USE_BIOMETHOD
  bio= BIO_new(&ma_BIO_method);
  bio->ptr= pvio;
  SSL_set_bio(ssl, bio, bio);
  BIO_set_fd(bio, mysql_get_socket(mysql), BIO_NOCLOSE);
#else
  SSL_set_fd(ssl, mysql_get_socket(mysql));
#endif

  while (try_connect && (rc= SSL_connect(ssl)) == -1)
  {
    switch(SSL_get_error(ssl, rc)) {
    case SSL_ERROR_WANT_READ:
      if (pvio->methods->wait_io_or_timeout(pvio, TRUE, mysql->options.connect_timeout) < 1)
        try_connect= 0;
      break;
    case SSL_ERROR_WANT_WRITE:
      if (pvio->methods->wait_io_or_timeout(pvio, TRUE, mysql->options.connect_timeout) < 1)
        try_connect= 0;
      break;
    default:
      try_connect= 0;
    }
  }
  if (rc != 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;
}