Skip to content
Permalink
Browse files

CONC-431: Use windows crypto libraries on Windows platforms

By default Windows builds now use the native system crypto libraries used
by ed25519, caching_sha2_password and sha256_password authentication plugins.
Even if configuration option WITH_SSL=OFF was specified (or no TLS library was found) authentication plugins using crypto will be available.
  • Loading branch information...
9EOR9 committed Aug 1, 2019
1 parent ed3a91c commit 11a2d035dde02b2a4379d5c5b978ada7447e9bfd
@@ -65,7 +65,10 @@ SET(INSTALL_LIBDIR_DEFAULT "lib/mariadb")
SET(INSTALL_PCDIR_DEFAULT "lib/pkgconfig")
SET(INSTALL_INCLUDEDIR_DEFAULT "include/mariadb")
SET(INSTALL_DOCDIR_DEFAULT "docs")
SET(INSTALL_PLUGINDIR_DEFAULT "lib/mariadb/plugin")
IF(NOT IS_SUBPROJECT)
SET(INSTALL_PLUGINDIR_DEFAULT "lib/mariadb/plugin")
ELSE()
ENDIF()
SET(LIBMARIADB_STATIC_DEFAULT "mariadbclient")
#
# RPM layout
@@ -44,14 +44,7 @@
#define MA_MAX_HASH_SIZE 64
/** \typedef MRL hash context */

#if defined(HAVE_OPENSSL)
typedef void MA_HASH_CTX;
#elif defined(HAVE_GNUTLS)
typedef struct {
void *ctx;
const struct nettle_hash *hash;
} MA_HASH_CTX;
#elif defined(HAVE_SCHANNEL)
#if defined(WIN32)
#include <windows.h>
#include <bcrypt.h>
typedef struct {
@@ -61,6 +54,13 @@ typedef struct {
PBYTE hashObject;
DWORD digest_len;
} MA_HASH_CTX;
#elif defined(HAVE_OPENSSL)
typedef void MA_HASH_CTX;
#elif defined(HAVE_GNUTLS)
typedef struct {
void *ctx;
const struct nettle_hash *hash;
} MA_HASH_CTX;
#endif

/**
@@ -24,7 +24,7 @@
#define MARIADB_PACKAGE_VERSION_ID @MARIADB_PACKAGE_VERSION_ID@
#define MARIADB_SYSTEM_TYPE "@CMAKE_SYSTEM_NAME@"
#define MARIADB_MACHINE_TYPE "@CMAKE_SYSTEM_PROCESSOR@"
#define MARIADB_PLUGINDIR "@PLUGINDIR@"
#define MARIADB_PLUGINDIR "@CMAKE_INSTALL_PREFIX@/@PLUGINDIR@"

/* mysqld compile time options */
#ifndef MYSQL_CHARSET
@@ -3,6 +3,22 @@ SET(AUTH_DIR ${CC_SOURCE_DIR}/plugins/auth)
INCLUDE_DIRECTORIES(${AUTH_DIR})
INCLUDE_DIRECTORIES(${CC_SOURCE_DIR}/include)

SET(CRYPTO_PLUGIN 1)
IF(WIN32)
SET(CRYPT_SOURCE ${CC_SOURCE_DIR}/libmariadb/secure/win_crypt.c)
SET(CRYPT_LIBS crypt32)
ELSEIF(WITH_OPENSSL)
IF(${WITH_SSL} STREQUAL "OPENSSL")
SET(CRYPT_SOURCE ${CC_SOURCE_DIR}/libmariadb/secure/openssl_crypt.c)
SET(CRYPT_LIBS ${SSL_LIBRARIES})
ELSEIF(${WITH_SSL} STREQUAL "GNUTLS")
SET(CRYPT_SOURCE ${CC_SOURCE_DIR}/libmariadb/secure/gnutls_crypt.c)
SET(CRYPT_LIBS ${SSL_LIBRARIES})
ELSE()
UNSET(CRYPTO_PLUGIN)
ENDIF()
ENDIF()

#native password
REGISTER_PLUGIN(TARGET mysql_native_password
TYPE MARIADB_CLIENT_PLUGIN_AUTH
@@ -18,30 +34,23 @@ REGISTER_PLUGIN(TARGET dialog
SOURCES ${CC_SOURCE_DIR}/plugins/auth/dialog.c
${CC_SOURCE_DIR}/libmariadb/get_password.c)

#ED25519 client authentication plugin
SET(REF10_DIR ${CC_SOURCE_DIR}/plugins/auth/ref10)
SET(REF10_SOURCES ${REF10_DIR}/fe_0.c ${REF10_DIR}/fe_isnegative.c ${REF10_DIR}/fe_sub.c ${REF10_DIR}/ge_p1p1_to_p2.c
${REF10_DIR}/ge_p3_to_cached.c ${REF10_DIR}/open.c ${REF10_DIR}/fe_1.c ${REF10_DIR}/fe_isnonzero.c
${REF10_DIR}/fe_tobytes.c ${REF10_DIR}/ge_p1p1_to_p3.c ${REF10_DIR}/ge_p3_to_p2.c ${REF10_DIR}/sc_muladd.c
${REF10_DIR}/fe_add.c ${REF10_DIR}/fe_mul.c ${REF10_DIR}/ge_add.c ${REF10_DIR}/ge_p2_0.c ${REF10_DIR}/ge_precomp_0.c
${REF10_DIR}/sc_reduce.c ${REF10_DIR}/fe_cmov.c ${REF10_DIR}/fe_neg.c ${REF10_DIR}/ge_double_scalarmult.c
${REF10_DIR}/ge_p2_dbl.c ${REF10_DIR}/ge_scalarmult_base.c ${REF10_DIR}/sign.c ${REF10_DIR}/fe_copy.c
${REF10_DIR}/fe_pow22523.c ${REF10_DIR}/ge_frombytes.c ${REF10_DIR}/ge_p3_0.c ${REF10_DIR}/ge_sub.c
${REF10_DIR}/verify.c ${REF10_DIR}/fe_frombytes.c ${REF10_DIR}/fe_sq2.c ${REF10_DIR}/ge_madd.c
${REF10_DIR}/ge_p3_dbl.c ${REF10_DIR}/ge_tobytes.c ${REF10_DIR}/fe_invert.c ${REF10_DIR}/fe_sq.c
${REF10_DIR}/ge_msub.c ${REF10_DIR}/ge_p3_tobytes.c ${REF10_DIR}/keypair.c)

IF(WITH_SSL)
IF(${WITH_SSL} STREQUAL "OPENSSL")
SET(CRYPT_SOURCE ${CC_SOURCE_DIR}/libmariadb/secure/openssl_crypt.c)
SET(ED25519_LIBS ${SSL_LIBRARIES})
ELSEIF(${WITH_SSL} STREQUAL "SCHANNEL")
SET(CRYPT_SOURCE ${CC_SOURCE_DIR}/libmariadb/secure/win_crypt.c)
SET(ED_25519_LIBS crypt32)
ELSE()
SET(CRYPT_SOURCE ${CC_SOURCE_DIR}/libmariadb/secure/gnutls_crypt.c)
SET(ED25519_LIBS ${SSL_LIBRARIES})
ENDIF()
# Crypto plugins
IF(CRYPTO_PLUGIN)

#ED25519 client authentication plugin
SET(REF10_DIR ${CC_SOURCE_DIR}/plugins/auth/ref10)
SET(REF10_SOURCES ${REF10_DIR}/fe_0.c ${REF10_DIR}/fe_isnegative.c ${REF10_DIR}/fe_sub.c ${REF10_DIR}/ge_p1p1_to_p2.c
${REF10_DIR}/ge_p3_to_cached.c ${REF10_DIR}/open.c ${REF10_DIR}/fe_1.c ${REF10_DIR}/fe_isnonzero.c
${REF10_DIR}/fe_tobytes.c ${REF10_DIR}/ge_p1p1_to_p3.c ${REF10_DIR}/ge_p3_to_p2.c ${REF10_DIR}/sc_muladd.c
${REF10_DIR}/fe_add.c ${REF10_DIR}/fe_mul.c ${REF10_DIR}/ge_add.c ${REF10_DIR}/ge_p2_0.c ${REF10_DIR}/ge_precomp_0.c
${REF10_DIR}/sc_reduce.c ${REF10_DIR}/fe_cmov.c ${REF10_DIR}/fe_neg.c ${REF10_DIR}/ge_double_scalarmult.c
${REF10_DIR}/ge_p2_dbl.c ${REF10_DIR}/ge_scalarmult_base.c ${REF10_DIR}/sign.c ${REF10_DIR}/fe_copy.c
${REF10_DIR}/fe_pow22523.c ${REF10_DIR}/ge_frombytes.c ${REF10_DIR}/ge_p3_0.c ${REF10_DIR}/ge_sub.c
${REF10_DIR}/verify.c ${REF10_DIR}/fe_frombytes.c ${REF10_DIR}/fe_sq2.c ${REF10_DIR}/ge_madd.c
${REF10_DIR}/ge_p3_dbl.c ${REF10_DIR}/ge_tobytes.c ${REF10_DIR}/fe_invert.c ${REF10_DIR}/fe_sq.c
${REF10_DIR}/ge_msub.c ${REF10_DIR}/ge_p3_tobytes.c ${REF10_DIR}/keypair.c)

REGISTER_PLUGIN(TARGET client_ed25519
TYPE MARIADB_CLIENT_PLUGIN_AUTH
CONFIGURATIONS DYNAMIC STATIC OFF
@@ -50,36 +59,37 @@ IF(WITH_SSL)
${REF10_SOURCES}
${CRYPT_SOURCE}
INCLUDES ${REF10_DIR}
LIBRARIES ${CRYPT_LIBS}
COMPILE_OPTIONS -DMYSQL_CLIENT=1)
IF(MSVC)
# Silence conversion (integer truncantion) warnings from reference code
SET_SOURCE_FILES_PROPERTIES(${REF10_SOURCES} PROPERTY COMPILE_FLAGS "-DMYSQL_CLIENT=1 /wd4244 /wd4146")
ENDIF()
ENDIF()

#GSSAPI client authentication plugin
IF(NOT WIN32)
INCLUDE(${CC_SOURCE_DIR}/cmake/FindGSSAPI.cmake)
ENDIF()
# SHA256 caching plugin for MySQL 8.0 connection
IF(WITH_SSL)
IF(${WITH_SSL} STREQUAL "OPENSSL")
SET(CRYPT_SOURCE ${CC_SOURCE_DIR}/libmariadb/secure/openssl_crypt.c)
SET(CACHING_SHA2_LIBS ${SSL_LIBRARIES})
ELSEIF(${WITH_SSL} STREQUAL "SCHANNEL")
SET(CRYPT_SOURCE ${CC_SOURCE_DIR}/libmariadb/secure/win_crypt.c)
SET(CACHING_SHA2_LIBS crypt32 bcrypt)
ELSEIF(${WITH_SSL} STREQUAL "GNUTLS")
SET(CRYPT_SOURCE ${CC_SOURCE_DIR}/libmariadb/secure/gnutls_crypt.c)
SET(CACHING_SHA2_LIBS ${SSL_LIBRARIES} ${LIBZ})
ENDIF()
# SHA256 caching plugin for MySQL 8.0 connection
REGISTER_PLUGIN(TARGET caching_sha2_password
TYPE MARIADB_CLIENT_PLUGIN_AUTH
CONFIGURATIONS DYNAMIC STATIC OFF
DEFAULT DYNAMIC
SOURCES ${CC_SOURCE_DIR}/plugins/auth/caching_sha2_pw.c
${CRYPT_SOURCE}
LIBRARIES ${CACHING_SHA2_LIBS})
LIBRARIES ${CRYPT_LIBS})

IF(WITH_SSL STREQUAL "GNUTLS" AND NOT WIN32)
MESSAGE1(STATUS "sha256_password not supported by GnuTLS due to missing OAEP padding")
ELSE()
REGISTER_PLUGIN(TARGET sha256_password
TYPE MARIADB_CLIENT_PLUGIN_AUTH
CONFIGURATIONS DYNAMIC STATIC OFF
DEFAULT DYNAMIC
SOURCES ${AUTH_DIR}/sha256_pw.c
LIBRARIES ${CRYT_LIBS})
ENDIF()
ENDIF()

#GSSAPI client authentication plugin
IF(NOT WIN32)
INCLUDE(${CC_SOURCE_DIR}/cmake/FindGSSAPI.cmake)
ENDIF()

#GSSAPI client authentication plugin
@@ -102,28 +112,13 @@ IF(GSSAPI_SOURCES)
LIBRARIES ${GSSAPI_LIBS})
ENDIF()

IF(${WITH_SSL} STREQUAL "OPENSSL" OR ${WITH_SSL} STREQUAL "SCHANNEL")
IF(WITH_SSL STREQUAL "SCHANNEL")
SET(SHA256_LIBS crypt32)
ELSE()
SET(SHA256_LIBS ${SSL_LIBRARIES})
ENDIF()
REGISTER_PLUGIN(TARGET sha256_password
TYPE MARIADB_CLIENT_PLUGIN_AUTH
CONFIGURATIONS DYNAMIC STATIC OFF
DEFAULT DYNAMIC
SOURCES ${AUTH_DIR}/sha256_pw.c
LIBRARIES ${SHA256_LIBS})
ENDIF()

# old_password plugin
REGISTER_PLUGIN(TARGET mysql_old_password
TYPE MARIADB_CLIENT_PLUGIN_AUTH
CONFIGURATIONS STATIC DYNAMIC OFF
DEFAULT STATIC
SOURCES ${AUTH_DIR}/old_password.c)


# Cleartext
REGISTER_PLUGIN(TARGET mysql_clear_password
TYPE MARIADB_CLIENT_PLUGIN_AUTH
@@ -21,15 +21,14 @@
#endif

#ifdef _WIN32
#if !defined(HAVE_OPENSSL)
#define HAVE_WINCRYPT
#else
#undef HAVE_OPENSSL
#undef HAVE_GNUTLS
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "ws2_32.lib")
#endif
#endif

#if defined(HAVE_OPENSSL) || defined(HAVE_SCHANNEL) || defined(HAVE_GNUTLS)
#if defined(HAVE_OPENSSL) || defined(HAVE_WINCRYPT) || defined(HAVE_GNUTLS)

#include <ma_global.h>
#include <mysql.h>
@@ -51,7 +50,7 @@
#include <openssl/err.h>
#elif defined(HAVE_GNUTLS)
#include <gnutls/gnutls.h>
#elif defined(HAVE_SCHANNEL)
#elif defined(HAVE_WINCRYPT)
#include <windows.h>
#include <wincrypt.h>
#include <bcrypt.h>
@@ -89,7 +88,7 @@ static int ma_sha256_scramble(unsigned char *scramble, size_t scramble_len,
unsigned char digest1[MA_SHA256_HASH_SIZE],
digest2[MA_SHA256_HASH_SIZE],
new_scramble[MA_SHA256_HASH_SIZE];
#ifdef HAVE_SCHANNEL
#ifdef HAVE_WINCRYPT
MA_HASH_CTX myctx;
MA_HASH_CTX *ctx= &myctx;
#else
@@ -108,7 +107,7 @@ static int ma_sha256_scramble(unsigned char *scramble, size_t scramble_len,
ma_hash_input(ctx, source, source_len);
ma_hash_result(ctx, digest1);
ma_hash_free(ctx);
#ifndef HAVE_SCHANNEL
#ifndef HAVE_WINCRYPT
ctx = NULL;
#endif

@@ -118,7 +117,7 @@ static int ma_sha256_scramble(unsigned char *scramble, size_t scramble_len,
ma_hash_input(ctx, digest1, MA_SHA256_HASH_SIZE);
ma_hash_result(ctx, digest2);
ma_hash_free(ctx);
#ifndef HAVE_SCHANNEL
#ifndef HAVE_WINCRYPT
ctx = NULL;
#endif

@@ -165,11 +164,11 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
auth_caching_sha2_client
};

#ifdef HAVE_SCHANNEL
#ifdef HAVE_WINCRYPT
static LPBYTE ma_load_pem(const char *buffer, DWORD *buffer_len)
{
LPBYTE der_buffer= NULL;
DWORD der_buffer_length;
DWORD der_buffer_length= 0;

if (buffer_len == NULL || *buffer_len == 0)
return NULL;
@@ -257,7 +256,7 @@ static int auth_caching_sha2_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
#if defined(HAVE_OPENSSL)
RSA *pubkey= NULL;
BIO *bio;
#elif defined(HAVE_SCHANNEL)
#elif defined(HAVE_WINCRYPT)
BCRYPT_KEY_HANDLE pubkey= 0;
BCRYPT_OAEP_PADDING_INFO paddingInfo;
LPBYTE der_buffer= NULL;
@@ -351,7 +350,7 @@ static int auth_caching_sha2_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
rsa_size= RSA_size(pubkey);
BIO_free(bio);
ERR_clear_error();
#elif defined(HAVE_SCHANNEL)
#elif defined(HAVE_WINCRYPT)
der_buffer_len= packet_length;
/* Load pem and convert it to binary object. New length will be returned
in der_buffer_len */
@@ -389,7 +388,7 @@ static int auth_caching_sha2_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
#if defined(HAVE_OPENSSL)
if (RSA_public_encrypt(pwlen, (unsigned char *)passwd, rsa_enc_pw, pubkey, RSA_PKCS1_OAEP_PADDING) < 0)
goto error;
#elif defined(HAVE_SCHANNEL)
#elif defined(HAVE_WINCRYPT)
ZeroMemory(&paddingInfo, sizeof(paddingInfo));
paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM;
if ((rc= BCryptEncrypt(pubkey, (PUCHAR)passwd, pwlen, &paddingInfo, NULL, 0, rsa_enc_pw,
@@ -414,7 +413,7 @@ static int auth_caching_sha2_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
#if defined(HAVE_OPENSSL)
if (pubkey)
RSA_free(pubkey);
#elif defined(HAVE_SCHANNEL)
#elif defined(HAVE_WINCRYPT)
if (pubkey)
BCryptDestroyKey(pubkey);
if (publicKeyInfo)
@@ -451,7 +450,7 @@ static int auth_caching_sha2_init(char *unused1 __attribute__((unused)),
int unused3 __attribute__((unused)),
va_list unused4 __attribute__((unused)))
{
#if defined(HAVE_SCHANNEL)
#if defined(HAVE_WINCRYPT)
BCryptOpenAlgorithmProvider(&Sha256Prov, BCRYPT_SHA256_ALGORITHM, NULL, 0);
BCryptOpenAlgorithmProvider(&RsaProv, BCRYPT_RSA_ALGORITHM, NULL, 0);
#endif
@@ -462,7 +461,7 @@ static int auth_caching_sha2_init(char *unused1 __attribute__((unused)),
/* {{{ auth_caching_sha2_deinit */
static int auth_caching_sha2_deinit()
{
#if defined(HAVE_SCHANNEL)
#if defined(HAVE_WINCRYPT)
BCryptCloseAlgorithmProvider(Sha256Prov, 0);
BCryptCloseAlgorithmProvider(RsaProv, 0);
#endif

2 comments on commit 11a2d03

@hholzgra

This comment has been minimized.

Copy link

hholzgra replied Oct 7, 2019

This leads to MDEV-20569 in 10.2.27, 10.3.18, 10.4.8, as the compiled in default plugin directory on Linux now becomes /usr//usr/lib64/mysql/plugin which is an invalid path:

- #define MARIADB_PLUGINDIR "@PLUGINDIR@"
+ #define MARIADB_PLUGINDIR "@CMAKE_INSTALL_PREFIX@/@PLUGINDIR@"
@sscherfke

This comment has been minimized.

Copy link

sscherfke replied Oct 15, 2019

It also breaks mysqlclient with gssapi auth: /home/...env//hom/...env/lib/plugin/auth_gssapi_client.so: cannot open shared object file: No such file or directory')

Please sign in to comment.
You can’t perform that action at this time.