You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-10 01:02:57 +03:00
TLS fingerprint
Beside SHA1 fingerprint hash, Connector/C now also supports SHA224 (OpenSSL and GnuTLS only), SHA256, SHA384 and SHA512 fingerprint hashes.
This commit is contained in:
committed by
Sergei Golubchik
parent
395641549a
commit
9aa15e72a7
@@ -382,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 ${LIBZ})
|
SET(SYSTEM_LIBS ws2_32 advapi32 kernel32 shlwapi crypt32 bcrypt ${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)
|
||||||
|
@@ -17,34 +17,20 @@
|
|||||||
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _ma_hash_h_
|
#ifndef _ma_crypt_h_
|
||||||
#define _ma_hash_h_
|
#define _ma_crypt_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)
|
||||||
@@ -123,8 +109,6 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -152,4 +136,4 @@ static inline void ma_hash(unsigned int algorithm,
|
|||||||
ma_hash_free(ctx);
|
ma_hash_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _ma_hash_h_ */
|
#endif /* _ma_crypt_h_ */
|
||||||
|
22
include/ma_hash.h
Normal file
22
include/ma_hash.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef _ma_hash_h_
|
||||||
|
#define _ma_hash_h_
|
||||||
|
|
||||||
|
/*! 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
|
||||||
|
|
||||||
|
/*! 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_MAX_HASH_SIZE 64
|
||||||
|
|
||||||
|
#endif
|
@@ -1,6 +1,8 @@
|
|||||||
#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
|
||||||
@@ -128,12 +130,14 @@ 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, char *fp, unsigned int fp_len);
|
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, uint hash_type, 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
|
||||||
|
@@ -344,6 +344,10 @@ 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})
|
||||||
|
@@ -41,12 +41,15 @@
|
|||||||
#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;
|
||||||
@@ -141,36 +144,74 @@ static signed char ma_hex2int(char c)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static my_bool ma_pvio_tls_compare_fp(const char *cert_fp,
|
#ifndef EVP_MAX_MD_SIZE
|
||||||
unsigned int cert_fp_len,
|
#define EVP_MAX_MD_SIZE 64
|
||||||
const char *fp, unsigned int fp_len)
|
#endif
|
||||||
|
|
||||||
|
static my_bool ma_pvio_tls_compare_fp(MARIADB_TLS *ctls,
|
||||||
|
const char *cert_fp,
|
||||||
|
unsigned int cert_fp_len
|
||||||
|
)
|
||||||
{
|
{
|
||||||
char *p= (char *)fp,
|
const char fp[EVP_MAX_MD_SIZE];
|
||||||
*c;
|
unsigned int fp_len= EVP_MAX_MD_SIZE;
|
||||||
|
unsigned int hash_type;
|
||||||
|
|
||||||
/* check length */
|
char *p, *c;
|
||||||
if (cert_fp_len != 20)
|
uint hash_len;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
/* We support two formats:
|
p= (char *)cert_fp;
|
||||||
2 digits hex numbers, separated by colons (length=59)
|
c = (char *)fp;
|
||||||
20 * 2 digits hex numbers without separators (length = 40)
|
|
||||||
*/
|
|
||||||
if (fp_len != (strchr(fp, ':') ? 59 : 40))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
for(c= (char *)cert_fp; c < cert_fp + cert_fp_len; c++)
|
for (p = (char*)cert_fp; p < cert_fp + cert_fp_len; c++, p += 2)
|
||||||
{
|
{
|
||||||
signed char d1, d2;
|
signed char d1, d2;
|
||||||
if (*p == ':')
|
if (*p == ':')
|
||||||
p++;
|
p++;
|
||||||
if (p - fp > (int)fp_len -1)
|
if (p - cert_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;
|
||||||
}
|
}
|
||||||
@@ -184,10 +225,10 @@ my_bool ma_pvio_tls_check_fp(MARIADB_TLS *ctls, const char *fp, const char *fp_l
|
|||||||
|
|
||||||
cert_fp= (char *)malloc(cert_fp_len);
|
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 *fp;
|
MA_FILE *fp;
|
||||||
@@ -205,7 +246,7 @@ 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(cert_fp, cert_fp_len, buff, (unsigned int)strlen(buff)))
|
if (!ma_pvio_tls_compare_fp(ctls, cert_fp, cert_fp_len))
|
||||||
{
|
{
|
||||||
/* finger print is valid: close file and exit */
|
/* finger print is valid: close file and exit */
|
||||||
ma_close(fp);
|
ma_close(fp);
|
||||||
|
@@ -1391,18 +1391,43 @@ static int my_verify_callback(gnutls_session_t ssl)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, char *fp, unsigned int len)
|
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, uint hash_type, 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)
|
||||||
{
|
{
|
||||||
@@ -1412,7 +1437,7 @@ unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, char *fp, unsigned int l
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gnutls_fingerprint(GNUTLS_DIG_SHA1, &cert_list[0], fp, &fp_len) == 0)
|
if (gnutls_fingerprint(hash_alg, &cert_list[0], fp, &fp_len) == 0)
|
||||||
return fp_len;
|
return fp_len;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -34,8 +34,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#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>
|
||||||
@@ -35,6 +36,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <security.h>
|
#include <security.h>
|
||||||
|
#include <ma_crypt.h>
|
||||||
|
|
||||||
#include <schnlsp.h>
|
#include <schnlsp.h>
|
||||||
#undef SECURITY_WIN32
|
#undef SECURITY_WIN32
|
||||||
@@ -57,7 +59,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.*/
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#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>
|
||||||
@@ -729,17 +730,50 @@ 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, char *fp, unsigned int len)
|
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, uint hash_type, 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)))
|
||||||
{
|
{
|
||||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||||
@@ -748,14 +782,7 @@ unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, char *fp, unsigned int l
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len < EVP_MAX_MD_SIZE)
|
if (!X509_digest(cert, hash_alg, (unsigned char *)fp, &fp_len))
|
||||||
{
|
|
||||||
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),
|
||||||
|
@@ -36,8 +36,6 @@ 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;
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,9 @@
|
|||||||
#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";
|
||||||
@@ -550,15 +553,33 @@ 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, char *fp, unsigned int len)
|
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, uint hash_type, 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 len;
|
return (uint)ma_hash_digest_size(hash_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ma_tls_set_connection(MYSQL *mysql __attribute__((unused)))
|
void ma_tls_set_connection(MYSQL *mysql __attribute__((unused)))
|
||||||
|
Reference in New Issue
Block a user