1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

Revert "self-signed certificate verification", it's 3.4 feature

This reverts 395641549ac7..536d9e2b9e5b, in particular:

8dffd56936 MDEV-31857 enable MYSQL_OPT_SSL_VERIFY_SERVER_CERT by default
a99570c118 MDEV-31855 SSL cert validation protocol extension
9aa15e72a7 TLS fingerprint

and related commits
This commit is contained in:
Sergei Golubchik
2024-02-19 11:09:11 +01:00
parent 536d9e2b9e
commit f6e99af056
29 changed files with 121 additions and 422 deletions

View File

@@ -305,8 +305,7 @@ IF(NOT WITH_SSL STREQUAL "OFF")
ENDIF() ENDIF()
IF(OPENSSL_FOUND) IF(OPENSSL_FOUND)
ADD_DEFINITIONS(-DHAVE_OPENSSL -DHAVE_TLS) ADD_DEFINITIONS(-DHAVE_OPENSSL -DHAVE_TLS)
SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/openssl.c" SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/openssl.c")
"${CC_SOURCE_DIR}/libmariadb/secure/openssl_crypt.c")
SET(SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}) SET(SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
IF(WIN32) IF(WIN32)
CHECK_INCLUDE_FILES (${OPENSSL_INCLUDE_DIR}/openssl/applink.c HAVE_OPENSSL_APPLINK_C) CHECK_INCLUDE_FILES (${OPENSSL_INCLUDE_DIR}/openssl/applink.c HAVE_OPENSSL_APPLINK_C)
@@ -333,8 +332,7 @@ IF(NOT WITH_SSL STREQUAL "OFF")
FIND_PACKAGE(GnuTLS "3.3.24" REQUIRED) FIND_PACKAGE(GnuTLS "3.3.24" REQUIRED)
IF(GNUTLS_FOUND) IF(GNUTLS_FOUND)
ADD_DEFINITIONS(-DHAVE_GNUTLS -DHAVE_TLS) ADD_DEFINITIONS(-DHAVE_GNUTLS -DHAVE_TLS)
SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/gnutls.c" SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/gnutls.c")
"${CC_SOURCE_DIR}/libmariadb/secure/gnutls_crypt.c")
SET(SSL_LIBRARIES ${GNUTLS_LIBRARY}) SET(SSL_LIBRARIES ${GNUTLS_LIBRARY})
SET(TLS_LIBRARY_VERSION "GnuTLS ${GNUTLS_VERSION_STRING}") SET(TLS_LIBRARY_VERSION "GnuTLS ${GNUTLS_VERSION_STRING}")
INCLUDE_DIRECTORIES(${GNUTLS_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${GNUTLS_INCLUDE_DIR})
@@ -344,13 +342,12 @@ IF(NOT WITH_SSL STREQUAL "OFF")
ENDIF() ENDIF()
IF(WIN32) IF(WIN32)
IF(WITH_SSL STREQUAL "SCHANNEL") IF(WITH_SSL STREQUAL "SCHANNEL")
ADD_DEFINITIONS(-DHAVE_SCHANNEL -DHAVE_TLS -DHAVE_WINCRYPT) ADD_DEFINITIONS(-DHAVE_SCHANNEL -DHAVE_TLS)
SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/schannel.c" SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/schannel.c"
"${CC_SOURCE_DIR}/libmariadb/secure/win_crypt.c"
"${CC_SOURCE_DIR}/libmariadb/secure/ma_schannel.c" "${CC_SOURCE_DIR}/libmariadb/secure/ma_schannel.c"
"${CC_SOURCE_DIR}/libmariadb/secure/schannel_certs.c") "${CC_SOURCE_DIR}/libmariadb/secure/schannel_certs.c")
INCLUDE_DIRECTORIES("${CC_SOURCE_DIR}/plugins/pvio/") INCLUDE_DIRECTORIES("${CC_SOURCE_DIR}/plugins/pvio/")
SET(SSL_LIBRARIES secur32 crypt32 bcrypt) SET(SSL_LIBRARIES secur32)
SET(TLS_LIBRARY_VERSION "Schannel ${CMAKE_SYSTEM_VERSION}") SET(TLS_LIBRARY_VERSION "Schannel ${CMAKE_SYSTEM_VERSION}")
ENDIF() ENDIF()
ENDIF() ENDIF()
@@ -385,7 +382,7 @@ CONFIGURE_FILE(${CC_SOURCE_DIR}/include/mariadb_version.h.in
INCLUDE_DIRECTORIES(${CC_BINARY_DIR}/include) INCLUDE_DIRECTORIES(${CC_BINARY_DIR}/include)
IF(WIN32) IF(WIN32)
SET(SYSTEM_LIBS ws2_32 advapi32 kernel32 shlwapi crypt32 bcrypt ${LIBZ}) SET(SYSTEM_LIBS ws2_32 advapi32 kernel32 shlwapi crypt32 ${LIBZ})
ELSE() ELSE()
SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${LIBPTHREAD} ${CMAKE_DL_LIBS} ${LIBM}) SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${LIBPTHREAD} ${CMAKE_DL_LIBS} ${LIBM})
IF(ICONV_EXTERNAL) IF(ICONV_EXTERNAL)

View File

@@ -86,7 +86,7 @@ struct st_mysql_options_extension {
unsigned short rpl_port; unsigned short rpl_port;
void (*status_callback)(void *ptr, enum enum_mariadb_status_info type, ...); void (*status_callback)(void *ptr, enum enum_mariadb_status_info type, ...);
void *status_data; void *status_data;
my_bool tls_allow_invalid_server_cert; my_bool tls_verify_server_cert;
}; };
typedef struct st_connection_handler typedef struct st_connection_handler
@@ -129,16 +129,3 @@ typedef struct st_mariadb_field_extension
{ {
MARIADB_CONST_STRING metadata[MARIADB_FIELD_ATTR_LAST+1]; /* 10.5 */ MARIADB_CONST_STRING metadata[MARIADB_FIELD_ATTR_LAST+1]; /* 10.5 */
} MA_FIELD_EXTENSION; } MA_FIELD_EXTENSION;
#if defined(HAVE_SCHANNEL) || defined(HAVE_GNUTLS)
#define reset_tls_self_signed_error(mysql) \
do { \
free((char*)mysql->net.tls_self_signed_error); \
mysql->net.tls_self_signed_error= 0; \
} while(0)
#else
#define reset_tls_self_signed_error(mysql) \
do { \
mysql->net.tls_self_signed_error= 0; \
} while(0)
#endif

View File

@@ -17,20 +17,34 @@
51 Franklin St., Fifth Floor, Boston, MA 02110, USA 51 Franklin St., Fifth Floor, Boston, MA 02110, USA
*/ */
#ifndef _ma_crypt_h_ #ifndef _ma_hash_h_
#define _ma_crypt_h_ #define _ma_hash_h_
#include <ma_hash.h>
#include <stddef.h> #include <stddef.h>
#include <stdarg.h> #include <stdarg.h>
/*! Hash algorithms */ /*! Hash algorithms */
#define MA_HASH_MD5 1
#define MA_HASH_SHA1 2
#define MA_HASH_SHA224 3
#define MA_HASH_SHA256 4
#define MA_HASH_SHA384 5
#define MA_HASH_SHA512 6
#define MA_HASH_RIPEMD160 7 #define MA_HASH_RIPEMD160 7
#define MA_HASH_MAX 8 #define MA_HASH_MAX 8
/*! Hash digest sizes */ /*! Hash digest sizes */
#define MA_MD5_HASH_SIZE 16
#define MA_SHA1_HASH_SIZE 20
#define MA_SHA224_HASH_SIZE 28
#define MA_SHA256_HASH_SIZE 32
#define MA_SHA384_HASH_SIZE 48
#define MA_SHA512_HASH_SIZE 64
#define MA_RIPEMD160_HASH_SIZE 20 #define MA_RIPEMD160_HASH_SIZE 20
#define MA_MAX_HASH_SIZE 64
/** \typedef MRL hash context */
#if defined(HAVE_WINCRYPT) #if defined(HAVE_WINCRYPT)
typedef void MA_HASH_CTX; typedef void MA_HASH_CTX;
#elif defined(HAVE_OPENSSL) #elif defined(HAVE_OPENSSL)
@@ -109,6 +123,8 @@ static inline size_t ma_hash_digest_size(unsigned int hash_alg)
return MA_SHA384_HASH_SIZE; return MA_SHA384_HASH_SIZE;
case MA_HASH_SHA512: case MA_HASH_SHA512:
return MA_SHA512_HASH_SIZE; return MA_SHA512_HASH_SIZE;
case MA_HASH_RIPEMD160:
return MA_RIPEMD160_HASH_SIZE;
default: default:
return 0; return 0;
} }
@@ -136,4 +152,4 @@ static inline void ma_hash(unsigned int algorithm,
ma_hash_free(ctx); ma_hash_free(ctx);
} }
#endif /* _ma_crypt_h_ */ #endif /* _ma_hash_h_ */

View File

@@ -1,8 +1,6 @@
#ifndef _ma_tls_h_ #ifndef _ma_tls_h_
#define _ma_tls_h_ #define _ma_tls_h_
#include <ma_hash.h>
enum enum_pvio_tls_type { enum enum_pvio_tls_type {
SSL_TYPE_DEFAULT=0, SSL_TYPE_DEFAULT=0,
#ifdef _WIN32 #ifdef _WIN32
@@ -130,14 +128,12 @@ const char *ma_tls_get_cipher(MARIADB_TLS *ssl);
returns SHA1 finger print of server certificate returns SHA1 finger print of server certificate
Parameter: Parameter:
MARIADB_TLS MariaDB SSL container MARIADB_TLS MariaDB SSL container
hash_type hash_type as defined in ma_hash.h
fp buffer for fingerprint fp buffer for fingerprint
fp_len buffer length fp_len buffer length
Returns: Returns:
actual size of finger print actual size of finger print
*/ */
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, uint hash_type, char *fp, unsigned int fp_len); unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, char *fp, unsigned int fp_len);
/* ma_tls_get_protocol_version /* ma_tls_get_protocol_version
returns protocol version number in use returns protocol version number in use

View File

@@ -288,7 +288,7 @@ typedef struct st_net {
my_bool unused_2; my_bool unused_2;
my_bool compress; my_bool compress;
my_bool unused_3; my_bool unused_3;
const char *tls_self_signed_error; void *unused_4;
unsigned int last_errno; unsigned int last_errno;
unsigned char error; unsigned char error;
my_bool unused_5; my_bool unused_5;

View File

@@ -43,7 +43,7 @@
#define MYSQL_CLIENT_PLUGIN_RESERVED2 1 #define MYSQL_CLIENT_PLUGIN_RESERVED2 1
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2 /* authentication */ #define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2 /* authentication */
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0101 #define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0100
#define MYSQL_CLIENT_MAX_PLUGINS 3 #define MYSQL_CLIENT_MAX_PLUGINS 3
/* Connector/C specific plugin types */ /* Connector/C specific plugin types */
@@ -128,7 +128,6 @@ struct st_mysql_client_plugin_AUTHENTICATION
{ {
MYSQL_CLIENT_PLUGIN_HEADER MYSQL_CLIENT_PLUGIN_HEADER
int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql); int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
int (*hash_password_bin)(struct st_mysql *mysql, unsigned char *hash, size_t *hash_length);
}; };
/******** trace plugin *******/ /******** trace plugin *******/

View File

@@ -344,10 +344,6 @@ IF(WIN32)
${CC_SOURCE_DIR}/win-iconv/win_iconv.c ${CC_SOURCE_DIR}/win-iconv/win_iconv.c
win32_errmsg.c win32_errmsg.c
win32_errmsg.h) win32_errmsg.h)
IF(WITH_SSL STREQUAL "SCHANNEL")
SET(LIBMARIADB_SOURCES ${LIBMARIADB_SOURCES}
secure/win_crypt.c)
ENDIF()
ELSE() ELSE()
IF(ICONV_INCLUDE_DIR) IF(ICONV_INCLUDE_DIR)
INCLUDE_DIRECTORIES(BEFORE ${ICONV_INCLUDE_DIR}) INCLUDE_DIRECTORIES(BEFORE ${ICONV_INCLUDE_DIR})

View File

@@ -111,7 +111,8 @@ static int get_plugin_nr(uint type)
static const char *check_plugin_version(struct st_mysql_client_plugin *plugin, unsigned int version) static const char *check_plugin_version(struct st_mysql_client_plugin *plugin, unsigned int version)
{ {
if (plugin->interface_version >> 8 != version >> 8) if (plugin->interface_version < version ||
(plugin->interface_version >> 8) > (version >> 8))
return "Incompatible client plugin interface"; return "Incompatible client plugin interface";
return 0; return 0;
} }

View File

@@ -522,44 +522,6 @@ my_bool ma_pvio_has_data(MARIADB_PVIO *pvio, ssize_t *data_len)
/* }}} */ /* }}} */
#ifdef HAVE_TLS #ifdef HAVE_TLS
/**
Checks if self-signed certificate error should be ignored.
*/
static my_bool ignore_self_signed_cert_error(MARIADB_PVIO *pvio)
{
const char *hostname= pvio->mysql->host;
const char *local_host_names[]= {
#ifdef _WIN32
/*
On Unix, we consider TCP connections with "localhost"
an insecure transport, for the single reason to run tests for
insecure transport on CI.This is artificial, but should be ok.
Default client connections use unix sockets anyway, so it
would not hurt much.
On Windows, the situation is quite different.
Default connections type is TCP, default host name is "localhost",
non-password plugin gssapi is common (every installation)
In this environment, there would be a lot of faux/disruptive
"self-signed certificates" errors there. Thus, "localhost" TCP
needs to be considered secure transport.
*/
"localhost",
#endif
"127.0.0.1", "::1", NULL};
int i;
if (pvio->type != PVIO_TYPE_SOCKET)
return TRUE;
if (!hostname)
return FALSE;
for (i= 0; local_host_names[i]; i++)
{
if (strcmp(hostname, local_host_names[i]) == 0)
return TRUE;
}
return FALSE;
}
/* {{{ my_bool ma_pvio_start_ssl */ /* {{{ my_bool ma_pvio_start_ssl */
my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio) my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio)
{ {
@@ -582,8 +544,7 @@ my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio)
2. verify CN (requires option ssl_verify_check) 2. verify CN (requires option ssl_verify_check)
3. verrify finger print 3. verrify finger print
*/ */
if (!pvio->mysql->options.extension->tls_allow_invalid_server_cert && if (pvio->mysql->options.extension->tls_verify_server_cert &&
!pvio->mysql->net.tls_self_signed_error &&
ma_pvio_tls_verify_server_cert(pvio->ctls)) ma_pvio_tls_verify_server_cert(pvio->ctls))
return 1; return 1;
@@ -595,12 +556,8 @@ my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio)
pvio->mysql->options.extension->tls_fp, pvio->mysql->options.extension->tls_fp,
pvio->mysql->options.extension->tls_fp_list)) pvio->mysql->options.extension->tls_fp_list))
return 1; return 1;
reset_tls_self_signed_error(pvio->mysql); // validated
} }
if (pvio->mysql->net.tls_self_signed_error && ignore_self_signed_cert_error(pvio))
reset_tls_self_signed_error(pvio->mysql);
return 0; return 0;
} }
/* }}} */ /* }}} */

View File

@@ -41,15 +41,12 @@
#include <ma_tls.h> #include <ma_tls.h>
#include <mysql/client_plugin.h> #include <mysql/client_plugin.h>
#include <mariadb/ma_io.h> #include <mariadb/ma_io.h>
#include <ma_hash.h>
#ifdef HAVE_NONBLOCK #ifdef HAVE_NONBLOCK
#include <mariadb_async.h> #include <mariadb_async.h>
#include <ma_context.h> #include <ma_context.h>
#endif #endif
#define MAX_FINGERPRINT_LEN 128;
/* Errors should be handled via pvio callback function */ /* Errors should be handled via pvio callback function */
my_bool ma_tls_initialized= FALSE; my_bool ma_tls_initialized= FALSE;
unsigned int mariadb_deinitialize_ssl= 1; unsigned int mariadb_deinitialize_ssl= 1;
@@ -144,96 +141,62 @@ static signed char ma_hex2int(char c)
return -1; return -1;
} }
#ifndef EVP_MAX_MD_SIZE static my_bool ma_pvio_tls_compare_fp(const char *cert_fp,
#define EVP_MAX_MD_SIZE 64 unsigned int cert_fp_len,
#endif const char *fp, unsigned int fp_len)
static my_bool ma_pvio_tls_compare_fp(MARIADB_TLS *ctls,
const char *cert_fp,
unsigned int cert_fp_len
)
{ {
const char fp[EVP_MAX_MD_SIZE]; char *p= (char *)fp,
unsigned int fp_len= EVP_MAX_MD_SIZE; *c;
unsigned int hash_type;
char *p, *c; /* check length */
uint hash_len; if (cert_fp_len != 20)
/* check length without colons */
if (strchr(cert_fp, ':'))
hash_len= (uint)((strlen(cert_fp) + 1) / 3) * 2;
else
hash_len= (uint)strlen(cert_fp);
/* check hash size */
switch (hash_len) {
#ifndef DISABLE_WEAK_HASH
case MA_SHA1_HASH_SIZE * 2:
hash_type = MA_HASH_SHA1;
break;
#endif
case MA_SHA224_HASH_SIZE * 2:
hash_type = MA_HASH_SHA224;
break;
case MA_SHA256_HASH_SIZE * 2:
hash_type = MA_HASH_SHA256;
break;
case MA_SHA384_HASH_SIZE * 2:
hash_type = MA_HASH_SHA384;
break;
case MA_SHA512_HASH_SIZE * 2:
hash_type = MA_HASH_SHA512;
break;
default:
{
MYSQL* mysql = ctls->pvio->mysql;
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR),
"Unknown or invalid fingerprint hash size detected");
return 1;
}
}
if (!ma_tls_get_finger_print(ctls, hash_type, (char *)fp, fp_len))
return 1; return 1;
p= (char *)cert_fp; /* We support two formats:
c = (char *)fp; 2 digits hex numbers, separated by colons (length=59)
20 * 2 digits hex numbers without separators (length = 40)
*/
if (fp_len != (strchr(fp, ':') ? 59 : 40))
return 1;
for (p = (char*)cert_fp; p < cert_fp + cert_fp_len; c++, p += 2) for(c= (char *)cert_fp; c < cert_fp + cert_fp_len; c++)
{ {
signed char d1, d2; signed char d1, d2;
if (*p == ':') if (*p == ':')
p++; p++;
if (p - cert_fp > (int)fp_len - 1) if (p - fp > (int)fp_len -1)
return 1; return 1;
if ((d1 = ma_hex2int(*p)) == -1 || if ((d1 = ma_hex2int(*p)) == - 1 ||
(d2 = ma_hex2int(*(p + 1))) == -1 || (d2 = ma_hex2int(*(p+1))) == -1 ||
(char)(d1 * 16 + d2) != *c) (char)(d1 * 16 + d2) != *c)
return 1; return 1;
p+= 2;
} }
return 0; return 0;
} }
my_bool ma_pvio_tls_check_fp(MARIADB_TLS *ctls, const char *fp, const char *fp_list) my_bool ma_pvio_tls_check_fp(MARIADB_TLS *ctls, const char *fp, const char *fp_list)
{ {
unsigned int cert_fp_len= 64;
char *cert_fp= NULL;
my_bool rc=1; my_bool rc=1;
MYSQL *mysql= ctls->pvio->mysql; MYSQL *mysql= ctls->pvio->mysql;
cert_fp= (char *)malloc(cert_fp_len);
if ((cert_fp_len= ma_tls_get_finger_print(ctls, cert_fp, cert_fp_len)) < 1)
goto end;
if (fp) if (fp)
{ rc= ma_pvio_tls_compare_fp(cert_fp, cert_fp_len, fp, (unsigned int)strlen(fp));
rc = ma_pvio_tls_compare_fp(ctls, fp, (uint)strlen(fp));
}
else if (fp_list) else if (fp_list)
{ {
MA_FILE *f; MA_FILE *fp;
char buff[255]; char buff[255];
if (!(f = ma_open(fp_list, "r", mysql))) if (!(fp = ma_open(fp_list, "r", mysql)))
goto end; goto end;
while (ma_gets(buff, sizeof(buff)-1, f)) while (ma_gets(buff, sizeof(buff)-1, fp))
{ {
/* remove trailing new line character */ /* remove trailing new line character */
char *pos= strchr(buff, '\r'); char *pos= strchr(buff, '\r');
@@ -242,20 +205,22 @@ my_bool ma_pvio_tls_check_fp(MARIADB_TLS *ctls, const char *fp, const char *fp_l
if (pos) if (pos)
*pos= '\0'; *pos= '\0';
if (!ma_pvio_tls_compare_fp(ctls, buff, (uint)strlen(buff))) if (!ma_pvio_tls_compare_fp(cert_fp, cert_fp_len, buff, (unsigned int)strlen(buff)))
{ {
/* finger print is valid: close file and exit */ /* finger print is valid: close file and exit */
ma_close(f); ma_close(fp);
rc= 0; rc= 0;
goto end; goto end;
} }
} }
/* No finger print matched - close file and return error */ /* No finger print matched - close file and return error */
ma_close(f); ma_close(fp);
} }
end: end:
if (cert_fp)
free(cert_fp);
if (rc) if (rc)
{ {
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,

View File

@@ -1440,8 +1440,6 @@ mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
if (!mysql->options.extension || !mysql->options.extension->status_callback) if (!mysql->options.extension || !mysql->options.extension->status_callback)
mysql_optionsv(mysql, MARIADB_OPT_STATUS_CALLBACK, NULL, NULL); mysql_optionsv(mysql, MARIADB_OPT_STATUS_CALLBACK, NULL, NULL);
reset_tls_self_signed_error(mysql);
/* if host contains a semicolon, we need to parse connection string */ /* if host contains a semicolon, we need to parse connection string */
if (host && strchr(host, ';')) if (host && strchr(host, ';'))
{ {
@@ -2446,7 +2444,6 @@ mysql_close(MYSQL *mysql)
mysql_close_memory(mysql); mysql_close_memory(mysql);
mysql_close_options(mysql); mysql_close_options(mysql);
ma_clear_session_state(mysql); ma_clear_session_state(mysql);
reset_tls_self_signed_error(mysql);
if (mysql->net.extension) if (mysql->net.extension)
{ {
@@ -3550,7 +3547,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
mysql->options.use_ssl= (*(my_bool *)arg1); mysql->options.use_ssl= (*(my_bool *)arg1);
break; break;
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
OPT_SET_EXTENDED_VALUE(&mysql->options, tls_allow_invalid_server_cert, !*(my_bool *)arg1); OPT_SET_EXTENDED_VALUE(&mysql->options, tls_verify_server_cert, *(my_bool *)arg1);
break; break;
case MYSQL_OPT_SSL_KEY: case MYSQL_OPT_SSL_KEY:
OPT_SET_VALUE_STR(&mysql->options, ssl_key, (char *)arg1); OPT_SET_VALUE_STR(&mysql->options, ssl_key, (char *)arg1);
@@ -3916,7 +3913,7 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...)
*((my_bool *)arg)= mysql->options.use_ssl; *((my_bool *)arg)= mysql->options.use_ssl;
break; break;
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
*((my_bool*)arg) = mysql->options.extension ? !mysql->options.extension->tls_allow_invalid_server_cert: 1; *((my_bool*)arg) = mysql->options.extension ? mysql->options.extension->tls_verify_server_cert : 0;
break; break;
case MYSQL_OPT_SSL_KEY: case MYSQL_OPT_SSL_KEY:
*((char **)arg)= mysql->options.ssl_key; *((char **)arg)= mysql->options.ssl_key;

View File

@@ -1357,7 +1357,7 @@ static int my_verify_callback(gnutls_session_t ssl)
CLEAR_CLIENT_ERROR(mysql); CLEAR_CLIENT_ERROR(mysql);
if (!mysql->options.extension->tls_allow_invalid_server_cert) if ((mysql->options.extension->tls_verify_server_cert))
{ {
const char *hostname= mysql->host; const char *hostname= mysql->host;
@@ -1371,23 +1371,11 @@ static int my_verify_callback(gnutls_session_t ssl)
{ {
gnutls_datum_t out; gnutls_datum_t out;
int type; int type;
if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
{
/* accept self signed certificates if we don't have to verify server cert */ /* accept self signed certificates if we don't have to verify server cert */
if (mysql->options.extension->tls_allow_invalid_server_cert) if (!(mysql->options.extension->tls_verify_server_cert) &&
(status & GNUTLS_CERT_SIGNER_NOT_FOUND))
return 0; return 0;
/* postpone the error for self signed certificates if CA isn't set */
if (!mysql->options.ssl_ca && !mysql->options.ssl_capath)
{
type= gnutls_certificate_type_get(ssl);
gnutls_certificate_verification_status_print(status, type, &out, 0);
mysql->net.tls_self_signed_error= (char*)out.data;
return 0;
}
}
/* gnutls default error message "certificate validation failed" isn't very /* gnutls default error message "certificate validation failed" isn't very
descriptive, so we provide more information about the error here */ descriptive, so we provide more information about the error here */
type= gnutls_certificate_type_get(ssl); type= gnutls_certificate_type_get(ssl);
@@ -1403,43 +1391,18 @@ static int my_verify_callback(gnutls_session_t ssl)
return 0; return 0;
} }
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, uint hash_type, char *fp, unsigned int len) unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, char *fp, unsigned int len)
{ {
MYSQL *mysql; MYSQL *mysql;
size_t fp_len= len; size_t fp_len= len;
const gnutls_datum_t *cert_list; const gnutls_datum_t *cert_list;
unsigned int cert_list_size; unsigned int cert_list_size;
gnutls_digest_algorithm_t hash_alg;
if (!ctls || !ctls->ssl) if (!ctls || !ctls->ssl)
return 0; return 0;
mysql= (MYSQL *)gnutls_session_get_ptr(ctls->ssl); mysql= (MYSQL *)gnutls_session_get_ptr(ctls->ssl);
switch (hash_type)
{
case MA_HASH_SHA1:
hash_alg = GNUTLS_DIG_SHA1;
break;
case MA_HASH_SHA224:
hash_alg = GNUTLS_DIG_SHA224;
break;
case MA_HASH_SHA256:
hash_alg = GNUTLS_DIG_SHA256;
break;
case MA_HASH_SHA384:
hash_alg = GNUTLS_DIG_SHA384;
break;
case MA_HASH_SHA512:
hash_alg = GNUTLS_DIG_SHA512;
break;
default:
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR),
"Cannot detect hash algorithm for fingerprint verification");
return 0;
}
cert_list = gnutls_certificate_get_peers (ctls->ssl, &cert_list_size); cert_list = gnutls_certificate_get_peers (ctls->ssl, &cert_list_size);
if (cert_list == NULL) if (cert_list == NULL)
{ {
@@ -1449,7 +1412,7 @@ unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, uint hash_type, char *fp
return 0; return 0;
} }
if (gnutls_fingerprint(hash_alg, &cert_list[0], fp, &fp_len) == 0) if (gnutls_fingerprint(GNUTLS_DIG_SHA1, &cert_list[0], fp, &fp_len) == 0)
return fp_len; return fp_len;
else else
{ {

View File

@@ -34,6 +34,8 @@ static gnutls_digest_algorithm_t ma_hash_get_algorithm(unsigned int alg)
return GNUTLS_DIG_SHA384; return GNUTLS_DIG_SHA384;
case MA_HASH_SHA512: case MA_HASH_SHA512:
return GNUTLS_DIG_SHA512; return GNUTLS_DIG_SHA512;
case MA_HASH_RIPEMD160:
return GNUTLS_DIG_RMD160;
default: default:
return GNUTLS_DIG_UNKNOWN; return GNUTLS_DIG_UNKNOWN;
} }

View File

@@ -526,13 +526,6 @@ my_bool ma_schannel_verify_certs(MARIADB_TLS *ctls, BOOL verify_server_name)
end: end:
if (!ret) if (!ret)
{ {
/* postpone the error for self signed certificates if CA isn't set */
if (status == CERT_E_UNTRUSTEDROOT && !ca_file && !ca_path)
{
mysql->net.tls_self_signed_error= strdup(errmsg);
ret= 1;
}
else
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, errmsg); pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, errmsg);
} }
if (pServerCert) if (pServerCert)

View File

@@ -28,7 +28,6 @@
#include <ma_common.h> #include <ma_common.h>
#include <ma_pvio.h> #include <ma_pvio.h>
#include <errmsg.h> #include <errmsg.h>
#include <ma_hash.h>
#include <wincrypt.h> #include <wincrypt.h>
@@ -36,7 +35,6 @@
#include <security.h> #include <security.h>
#include <ma_crypt.h>
#include <schnlsp.h> #include <schnlsp.h>
#undef SECURITY_WIN32 #undef SECURITY_WIN32
@@ -59,7 +57,7 @@ struct st_schannel {
DWORD IoBufferSize; DWORD IoBufferSize;
SecPkgContext_StreamSizes Sizes; SecPkgContext_StreamSizes Sizes;
CtxtHandle hCtxt; CtxtHandle hCtxt;
BCRYPT_ALG_HANDLE HashProv[MA_MAX_HASH_SIZE];
/* Cached data from the last read/decrypt call.*/ /* Cached data from the last read/decrypt call.*/
SecBuffer extraBuf; /* encrypted data read from server. */ SecBuffer extraBuf; /* encrypted data read from server. */
SecBuffer dataBuf; /* decrypted but still unread data from server.*/ SecBuffer dataBuf; /* decrypted but still unread data from server.*/

View File

@@ -29,7 +29,6 @@
#include <openssl/err.h> /* error reporting */ #include <openssl/err.h> /* error reporting */
#include <openssl/conf.h> #include <openssl/conf.h>
#include <openssl/md4.h> #include <openssl/md4.h>
#include <ma_tls.h>
#if defined(_WIN32) && !defined(_OPENSSL_Applink) && defined(HAVE_OPENSSL_APPLINK_C) #if defined(_WIN32) && !defined(_OPENSSL_Applink) && defined(HAVE_OPENSSL_APPLINK_C)
#include <openssl/applink.c> #include <openssl/applink.c>
@@ -506,15 +505,11 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
/* In case handshake failed or if a root certificate (ca) was specified, /* In case handshake failed or if a root certificate (ca) was specified,
we need to check the result code of X509 verification. A detailed check we need to check the result code of X509 verification. A detailed check
of the peer certificate (hostname checking will follow later) */ of the peer certificate (hostname checking will follow later) */
if (rc != 1 || !mysql->options.extension->tls_allow_invalid_server_cert || if (rc != 1 || mysql->options.extension->tls_verify_server_cert ||
mysql->options.ssl_ca || mysql->options.ssl_capath) mysql->options.ssl_ca || mysql->options.ssl_capath)
{ {
long x509_err= SSL_get_verify_result(ssl); long x509_err= SSL_get_verify_result(ssl);
if ((x509_err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || if (x509_err != X509_V_OK)
x509_err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) && rc == 1 &&
!mysql->options.ssl_ca && !mysql->options.ssl_capath)
mysql->net.tls_self_signed_error= X509_verify_cert_error_string(x509_err);
else if (x509_err != X509_V_OK)
{ {
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(x509_err)); ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(x509_err));
@@ -734,49 +729,16 @@ const char *ma_tls_get_cipher(MARIADB_TLS *ctls)
return SSL_get_cipher_name(ctls->ssl); return SSL_get_cipher_name(ctls->ssl);
} }
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, uint hash_type, char *fp, unsigned int len) unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, char *fp, unsigned int len)
{ {
X509 *cert= NULL; X509 *cert= NULL;
MYSQL *mysql; MYSQL *mysql;
unsigned int fp_len; unsigned int fp_len;
const EVP_MD *hash_alg;
if (!ctls || !ctls->ssl) if (!ctls || !ctls->ssl)
return 0; return 0;
mysql = SSL_get_app_data(ctls->ssl); mysql= SSL_get_app_data(ctls->ssl);
if (len < EVP_MAX_MD_SIZE)
{
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR),
"Finger print buffer too small");
return 0;
}
switch (hash_type)
{
case MA_HASH_SHA1:
hash_alg = EVP_sha1();
break;
case MA_HASH_SHA224:
hash_alg = EVP_sha224();
break;
case MA_HASH_SHA256:
hash_alg = EVP_sha256();
break;
case MA_HASH_SHA384:
hash_alg = EVP_sha384();
break;
case MA_HASH_SHA512:
hash_alg = EVP_sha512();
break;
default:
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR),
"Cannot detect hash algorithm for fingerprint verification");
return 0;
}
if (!(cert= SSL_get_peer_certificate(ctls->ssl))) if (!(cert= SSL_get_peer_certificate(ctls->ssl)))
{ {
@@ -786,7 +748,14 @@ unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, uint hash_type, char *fp
goto end; goto end;
} }
if (!X509_digest(cert, hash_alg, (unsigned char *)fp, &fp_len)) if (len < EVP_MAX_MD_SIZE)
{
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR),
"Finger print buffer too small");
goto end;
}
if (!X509_digest(cert, EVP_sha1(), (unsigned char *)fp, &fp_len))
{ {
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR), ER(CR_SSL_CONNECTION_ERROR),

View File

@@ -36,6 +36,8 @@ static const EVP_MD *ma_hash_get_algorithm(unsigned int alg)
return EVP_sha384(); return EVP_sha384();
case MA_HASH_SHA512: case MA_HASH_SHA512:
return EVP_sha512(); return EVP_sha512();
case MA_HASH_RIPEMD160:
return EVP_ripemd160();
default: default:
return NULL; return NULL;
} }

View File

@@ -20,9 +20,6 @@
#include "ma_schannel.h" #include "ma_schannel.h"
#include "schannel_certs.h" #include "schannel_certs.h"
#include <string.h> #include <string.h>
#include <ma_crypt.h>
#include <wincrypt.h>
#include <bcrypt.h>
extern my_bool ma_tls_initialized; extern my_bool ma_tls_initialized;
char tls_library_version[] = "Schannel"; char tls_library_version[] = "Schannel";
@@ -451,11 +448,11 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
goto end; goto end;
verify_certs = mysql->options.ssl_ca || mysql->options.ssl_capath || verify_certs = mysql->options.ssl_ca || mysql->options.ssl_capath ||
!mysql->options.extension->tls_allow_invalid_server_cert; (mysql->options.extension->tls_verify_server_cert);
if (verify_certs) if (verify_certs)
{ {
if (!ma_schannel_verify_certs(ctls, !mysql->options.extension->tls_allow_invalid_server_cert)) if (!ma_schannel_verify_certs(ctls, mysql->options.extension->tls_verify_server_cert))
goto end; goto end;
} }
@@ -553,33 +550,15 @@ const char *ma_tls_get_cipher(MARIADB_TLS *ctls)
return cipher_name(&CipherInfo); return cipher_name(&CipherInfo);
} }
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, uint hash_type, char *fp, unsigned int len) unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, char *fp, unsigned int len)
{ {
MA_HASH_CTX* hash_ctx;
SC_CTX *sctx= (SC_CTX *)ctls->ssl; SC_CTX *sctx= (SC_CTX *)ctls->ssl;
PCCERT_CONTEXT pRemoteCertContext = NULL; PCCERT_CONTEXT pRemoteCertContext = NULL;
int rc= 0;
if (hash_type == MA_HASH_SHA224)
{
MYSQL *mysql = ctls->pvio->mysql;
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR),
"SHA224 hash for fingerprint verification is not supported in Schannel");
return 0;
}
if (QueryContextAttributes(&sctx->hCtxt, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pRemoteCertContext) != SEC_E_OK) if (QueryContextAttributes(&sctx->hCtxt, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pRemoteCertContext) != SEC_E_OK)
return 0; return 0;
CertGetCertificateContextProperty(pRemoteCertContext, CERT_HASH_PROP_ID, fp, (DWORD *)&len);
hash_ctx = ma_hash_new(hash_type);
ma_hash_input(hash_ctx, pRemoteCertContext->pbCertEncoded, pRemoteCertContext->cbCertEncoded);
ma_hash_result(hash_ctx, fp);
ma_hash_free(hash_ctx);
CertFreeCertificateContext(pRemoteCertContext); CertFreeCertificateContext(pRemoteCertContext);
return (uint)ma_hash_digest_size(hash_type); return len;
} }
void ma_tls_set_connection(MYSQL *mysql __attribute__((unused))) void ma_tls_set_connection(MYSQL *mysql __attribute__((unused)))

View File

@@ -117,6 +117,5 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
NULL, NULL,
NULL, NULL,
NULL, NULL,
gssapi_auth_client, gssapi_auth_client
NULL
}; };

View File

@@ -145,8 +145,7 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
auth_caching_sha2_init, auth_caching_sha2_init,
auth_caching_sha2_deinit, auth_caching_sha2_deinit,
NULL, NULL,
auth_caching_sha2_client, auth_caching_sha2_client
NULL
}; };
#ifdef HAVE_WINCRYPT #ifdef HAVE_WINCRYPT

View File

@@ -58,8 +58,7 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
auth_dialog_init, auth_dialog_init,
NULL, NULL,
NULL, NULL,
auth_dialog_open, auth_dialog_open
NULL
}; };

View File

@@ -64,7 +64,6 @@ static int auth_ed25519_init(char *unused1,
size_t unused2, size_t unused2,
int unused3, int unused3,
va_list); va_list);
static int auth_ed25519_hash(MYSQL *, unsigned char *out, size_t *outlen);
#ifndef PLUGIN_DYNAMIC #ifndef PLUGIN_DYNAMIC
@@ -78,24 +77,21 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
"client_ed25519", "client_ed25519",
"Sergei Golubchik, Georg Richter", "Sergei Golubchik, Georg Richter",
"Ed25519 Authentication Plugin", "Ed25519 Authentication Plugin",
{0,1,1}, {0,1,0},
"LGPL", "LGPL",
NULL, NULL,
auth_ed25519_init, auth_ed25519_init,
auth_ed25519_deinit, auth_ed25519_deinit,
NULL, NULL,
auth_ed25519_client, auth_ed25519_client
auth_ed25519_hash
}; };
static int auth_ed25519_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) static int auth_ed25519_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
{ {
unsigned char *packet, unsigned char *packet,
signature[CRYPTO_BYTES + NONCE_BYTES], signature[CRYPTO_BYTES + NONCE_BYTES];
pk[CRYPTO_PUBLICKEYBYTES]; int pkt_len;
unsigned long long pkt_len, pwlen= strlen(mysql->passwd);
char *newpw;
/* /*
Step 1: Server sends nonce Step 1: Server sends nonce
@@ -110,36 +106,16 @@ static int auth_ed25519_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
return CR_SERVER_HANDSHAKE_ERR; return CR_SERVER_HANDSHAKE_ERR;
/* Sign nonce: the crypto_sign function is part of ref10 */ /* Sign nonce: the crypto_sign function is part of ref10 */
ma_crypto_sign(signature, pk, packet, NONCE_BYTES, (unsigned char*)mysql->passwd, pwlen); ma_crypto_sign(signature, packet, NONCE_BYTES, (unsigned char*)mysql->passwd, strlen(mysql->passwd));
/* send signature to server */ /* send signature to server */
if (vio->write_packet(vio, signature, CRYPTO_BYTES)) if (vio->write_packet(vio, signature, CRYPTO_BYTES))
return CR_ERROR; return CR_ERROR;
/* save pk for the future auth_ed25519_hash() call */
if ((newpw= realloc(mysql->passwd, pwlen + 1 + sizeof(pk))))
{
memcpy(newpw + pwlen + 1, pk, sizeof(pk));
mysql->passwd= newpw;
}
return CR_OK; return CR_OK;
} }
/* }}} */ /* }}} */
/* {{{ static int auth_ed25519_hash */
static int auth_ed25519_hash(MYSQL *mysql, unsigned char *out, size_t *outlen)
{
if (*outlen < CRYPTO_PUBLICKEYBYTES)
return 1;
*outlen= CRYPTO_PUBLICKEYBYTES;
/* use the cached value */
memcpy(out, mysql->passwd + strlen(mysql->passwd) + 1, CRYPTO_PUBLICKEYBYTES);
return 0;
}
/* }}} */
/* {{{ static int auth_ed25519_init */ /* {{{ static int auth_ed25519_init */
static int auth_ed25519_init(char *unused1 __attribute__((unused)), static int auth_ed25519_init(char *unused1 __attribute__((unused)),
size_t unused2 __attribute__((unused)), size_t unused2 __attribute__((unused)),

View File

@@ -70,8 +70,7 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
NULL, NULL,
NULL, NULL,
NULL, NULL,
clear_password_auth_client, clear_password_auth_client
NULL
}; };

View File

@@ -3,29 +3,17 @@
#include <errmsg.h> #include <errmsg.h>
#include <string.h> #include <string.h>
#include <ma_common.h> #include <ma_common.h>
#include <ma_crypt.h>
#include <mysql/client_plugin.h> #include <mysql/client_plugin.h>
typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t; typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t;
static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, size_t); static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, size_t);
static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql); static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
static int native_password_hash(MYSQL *mysql, unsigned char *out, size_t *outlen);
static int dummy_fallback_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql __attribute__((unused))); static int dummy_fallback_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql __attribute__((unused)));
extern void read_user_name(char *name); extern void read_user_name(char *name);
extern char *ma_send_connect_attr(MYSQL *mysql, unsigned char *buffer); extern char *ma_send_connect_attr(MYSQL *mysql, unsigned char *buffer);
extern int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length); extern int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length);
extern unsigned char *mysql_net_store_length(unsigned char *packet, ulonglong length); extern unsigned char *mysql_net_store_length(unsigned char *packet, ulonglong length);
#define hashing(p) (p->interface_version >= 0x0101 && p->hash_password_bin)
static int set_error_from_tls_self_signed_error(MYSQL *mysql)
{
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR), mysql->net.tls_self_signed_error);
reset_tls_self_signed_error(mysql);
return 1;
}
typedef struct { typedef struct {
int (*read_packet)(struct st_plugin_vio *vio, uchar **buf); int (*read_packet)(struct st_plugin_vio *vio, uchar **buf);
int (*write_packet)(struct st_plugin_vio *vio, const uchar *pkt, size_t pkt_len); int (*write_packet)(struct st_plugin_vio *vio, const uchar *pkt, size_t pkt_len);
@@ -56,14 +44,13 @@ auth_plugin_t mysql_native_password_client_plugin=
native_password_plugin_name, native_password_plugin_name,
"R.J.Silk, Sergei Golubchik", "R.J.Silk, Sergei Golubchik",
"Native MySQL authentication", "Native MySQL authentication",
{1, 0, 1}, {1, 0, 0},
"LGPL", "LGPL",
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
native_password_auth_client, native_password_auth_client
native_password_hash
}; };
@@ -110,22 +97,6 @@ static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
return CR_OK; return CR_OK;
} }
static int native_password_hash(MYSQL *mysql, unsigned char *out, size_t *out_length)
{
unsigned char digest[MA_SHA1_HASH_SIZE];
if (*out_length < MA_SHA1_HASH_SIZE)
return 1;
*out_length= MA_SHA1_HASH_SIZE;
/* would it be better to reuse instead of recalculating here? see ed25519 */
ma_hash(MA_HASH_SHA1, (unsigned char*)mysql->passwd, strlen(mysql->passwd),
digest);
ma_hash(MA_HASH_SHA1, digest, sizeof(digest), out);
return 0;
}
auth_plugin_t dummy_fallback_client_plugin= auth_plugin_t dummy_fallback_client_plugin=
{ {
MYSQL_CLIENT_AUTHENTICATION_PLUGIN, MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
@@ -139,8 +110,7 @@ auth_plugin_t dummy_fallback_client_plugin=
NULL, NULL,
NULL, NULL,
NULL, NULL,
dummy_fallback_auth_client, dummy_fallback_auth_client
NULL
}; };
@@ -253,7 +223,7 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
if (mysql->options.ssl_key || mysql->options.ssl_cert || if (mysql->options.ssl_key || mysql->options.ssl_cert ||
mysql->options.ssl_ca || mysql->options.ssl_capath || mysql->options.ssl_ca || mysql->options.ssl_capath ||
mysql->options.ssl_cipher || mysql->options.use_ssl || mysql->options.ssl_cipher || mysql->options.use_ssl ||
!mysql->options.extension->tls_allow_invalid_server_cert) mysql->options.extension->tls_verify_server_cert)
mysql->options.use_ssl= 1; mysql->options.use_ssl= 1;
if (mysql->options.use_ssl) if (mysql->options.use_ssl)
mysql->client_flag|= CLIENT_SSL; mysql->client_flag|= CLIENT_SSL;
@@ -273,16 +243,15 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
mysql->net.pvio->type == PVIO_TYPE_SHAREDMEM)) mysql->net.pvio->type == PVIO_TYPE_SHAREDMEM))
{ {
mysql->server_capabilities &= ~(CLIENT_SSL); mysql->server_capabilities &= ~(CLIENT_SSL);
mysql->options.extension->tls_allow_invalid_server_cert= 1;
} }
/* if server doesn't support SSL and verification of server certificate /* if server doesn't support SSL and verification of server certificate
was set to mandatory, we need to return an error */ was set to mandatory, we need to return an error */
if (mysql->options.use_ssl && !(mysql->server_capabilities & CLIENT_SSL)) if (mysql->options.use_ssl && !(mysql->server_capabilities & CLIENT_SSL))
{ {
if (!mysql->options.extension->tls_allow_invalid_server_cert || if (mysql->options.extension->tls_verify_server_cert ||
mysql->options.extension->tls_fp || (mysql->options.extension && (mysql->options.extension->tls_fp ||
mysql->options.extension->tls_fp_list) mysql->options.extension->tls_fp_list)))
{ {
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
ER(CR_SSL_CONNECTION_ERROR), ER(CR_SSL_CONNECTION_ERROR),
@@ -381,13 +350,6 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
} }
if (ma_pvio_start_ssl(mysql->net.pvio)) if (ma_pvio_start_ssl(mysql->net.pvio))
goto error; goto error;
if (mysql->net.tls_self_signed_error &&
(!mysql->passwd || !mysql->passwd[0] || !hashing(mpvio->plugin)))
{
/* cannot use auth to validate the cert */
set_error_from_tls_self_signed_error(mysql);
goto error;
}
} }
#endif /* HAVE_TLS */ #endif /* HAVE_TLS */
@@ -765,62 +727,15 @@ retry:
auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN))) auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
auth_plugin= &dummy_fallback_client_plugin; auth_plugin= &dummy_fallback_client_plugin;
/* can we use this plugin with this tls server cert ? */
if (mysql->net.tls_self_signed_error && !hashing(auth_plugin))
return set_error_from_tls_self_signed_error(mysql);
goto retry; goto retry;
} }
/* /*
net->read_pos[0] should always be 0 here if the server implements net->read_pos[0] should always be 0 here if the server implements
the protocol correctly the protocol correctly
*/ */
if (mysql->net.read_pos[0] != 0) if (mysql->net.read_pos[0] == 0)
return ma_read_ok_packet(mysql, mysql->net.read_pos + 1, pkt_length);
return 1; return 1;
if (ma_read_ok_packet(mysql, mysql->net.read_pos + 1, pkt_length))
return -1;
if (!mysql->net.tls_self_signed_error)
return 0;
assert(mysql->options.use_ssl);
assert(!mysql->options.extension->tls_allow_invalid_server_cert);
assert(!mysql->options.ssl_ca);
assert(!mysql->options.ssl_capath);
assert(!mysql->options.extension->tls_fp);
assert(!mysql->options.extension->tls_fp_list);
assert(hashing(auth_plugin));
assert(mysql->passwd[0]);
if (mysql->info && mysql->info[0] == '\1')
{
MA_HASH_CTX *ctx = NULL;
unsigned char buf[1024], digest[MA_SHA256_HASH_SIZE];
char fp[128], hexdigest[sizeof(digest)*2+1], *hexsig= mysql->info + 1;
size_t buflen= sizeof(buf) - 1, fplen;
mysql->info= NULL; /* no need to confuse the client with binary info */
if (!(fplen= ma_tls_get_finger_print(mysql->net.pvio->ctls, MA_HASH_SHA256,
fp, sizeof(fp))))
return 1; /* error is already set */
if (auth_plugin->hash_password_bin(mysql, buf, &buflen) ||
!(ctx= ma_hash_new(MA_HASH_SHA256)))
{
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return 1;
}
ma_hash_input(ctx, (unsigned char*)buf, buflen);
ma_hash_input(ctx, (unsigned char*)mysql->scramble_buff, SCRAMBLE_LENGTH);
ma_hash_input(ctx, (unsigned char*)fp, fplen);
ma_hash_result(ctx, digest);
ma_hash_free(ctx);
mysql_hex_string(hexdigest, (char*)digest, sizeof(digest));
if (strcmp(hexdigest, hexsig) == 0)
return 0; /* phew. self-signed certificate is validated! */
}
return set_error_from_tls_self_signed_error(mysql);
} }

View File

@@ -63,8 +63,7 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
NULL, NULL,
NULL, NULL,
NULL, NULL,
auth_old_password, auth_old_password
NULL
}; };
/** /**

View File

@@ -3,7 +3,7 @@ int crypto_sign_keypair(
unsigned char *pw, unsigned long long pwlen unsigned char *pw, unsigned long long pwlen
); );
int ma_crypto_sign( int ma_crypto_sign(
unsigned char *sm, unsigned char *pk, unsigned char *sm,
const unsigned char *m, unsigned long long mlen, const unsigned char *m, unsigned long long mlen,
const unsigned char *pw, unsigned long long pwlen const unsigned char *pw, unsigned long long pwlen
); );

View File

@@ -5,7 +5,7 @@
#include "sc.h" #include "sc.h"
int ma_crypto_sign( int ma_crypto_sign(
unsigned char *sm, unsigned char *pk, unsigned char *sm,
const unsigned char *m,unsigned long long mlen, const unsigned char *m,unsigned long long mlen,
const unsigned char *pw,unsigned long long pwlen const unsigned char *pw,unsigned long long pwlen
) )
@@ -26,7 +26,6 @@ int ma_crypto_sign(
ge_scalarmult_base(&A,az); ge_scalarmult_base(&A,az);
ge_p3_tobytes(sm + 32,&A); ge_p3_tobytes(sm + 32,&A);
memmove(pk, sm + 32, 32);
sc_reduce(nonce); sc_reduce(nonce);
ge_scalarmult_base(&R,nonce); ge_scalarmult_base(&R,nonce);

View File

@@ -76,8 +76,7 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
auth_sha256_init, auth_sha256_init,
NULL, NULL,
NULL, NULL,
auth_sha256_client, auth_sha256_client
NULL
}; };
#ifdef HAVE_WINCRYPT #ifdef HAVE_WINCRYPT

View File

@@ -686,7 +686,6 @@ int test_connection_timeout2(MYSQL *unused __attribute__((unused)))
unsigned int timeout= 5; unsigned int timeout= 5;
time_t start, elapsed; time_t start, elapsed;
MYSQL *mysql; MYSQL *mysql;
my_bool no= 0;
SKIP_SKYSQL; SKIP_SKYSQL;
SKIP_MAXSCALE; SKIP_MAXSCALE;
@@ -695,7 +694,6 @@ int test_connection_timeout2(MYSQL *unused __attribute__((unused)))
mysql= mysql_init(NULL); mysql= mysql_init(NULL);
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (unsigned int *)&timeout); mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (unsigned int *)&timeout);
mysql_options(mysql, MYSQL_INIT_COMMAND, "set @a:=SLEEP(7)"); mysql_options(mysql, MYSQL_INIT_COMMAND, "set @a:=SLEEP(7)");
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &no);
start= time(NULL); start= time(NULL);
if (my_test_connect(mysql, hostname, username, password, schema, port, socketname, CLIENT_REMEMBER_OPTIONS)) if (my_test_connect(mysql, hostname, username, password, schema, port, socketname, CLIENT_REMEMBER_OPTIONS))
{ {