mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Merge branch 'PHP-7.4'
* PHP-7.4: Native Windows support for mysqlnd sha256 authentification Abstract over crypto operations
This commit is contained in:
commit
3abe64f16a
2 changed files with 209 additions and 61 deletions
|
@ -36,6 +36,9 @@ if (PHP_MYSQLND != "no") {
|
||||||
{
|
{
|
||||||
AC_DEFINE("MYSQLND_COMPRESSION_ENABLED", 1, "Compression support");
|
AC_DEFINE("MYSQLND_COMPRESSION_ENABLED", 1, "Compression support");
|
||||||
AC_DEFINE("MYSQLND_SSL_SUPPORTED", 1, "SSL support");
|
AC_DEFINE("MYSQLND_SSL_SUPPORTED", 1, "SSL support");
|
||||||
|
if (CHECK_LIB("crypt32.lib", "mysqlnd")) {
|
||||||
|
AC_DEFINE("MYSQLND_HAVE_SSL", 1, "Extended SSL support");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PHP_INSTALL_HEADERS("", "ext/mysqlnd");
|
PHP_INSTALL_HEADERS("", "ext/mysqlnd");
|
||||||
}
|
}
|
||||||
|
|
|
@ -692,20 +692,146 @@ mysqlnd_xor_string(char * dst, const size_t dst_len, const char * xor_str, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PHP_WIN32
|
||||||
|
|
||||||
#include <openssl/rsa.h>
|
#include <openssl/rsa.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
typedef RSA * mysqlnd_rsa_t;
|
||||||
|
|
||||||
|
/* {{{ mysqlnd_sha256_get_rsa_from_pem */
|
||||||
|
static mysqlnd_rsa_t
|
||||||
|
mysqlnd_sha256_get_rsa_from_pem(const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
BIO * bio = BIO_new_mem_buf(buf, len);
|
||||||
|
RSA * ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
|
||||||
|
BIO_free(bio);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ mysqlnd_sha256_public_encrypt */
|
||||||
|
static zend_uchar *
|
||||||
|
mysqlnd_sha256_public_encrypt(MYSQLND_CONN_DATA * conn, mysqlnd_rsa_t server_public_key, size_t passwd_len, size_t * auth_data_len, char *xor_str)
|
||||||
|
{
|
||||||
|
zend_uchar * ret = NULL;
|
||||||
|
size_t server_public_key_len = (size_t) RSA_size(server_public_key);
|
||||||
|
|
||||||
|
DBG_ENTER("mysqlnd_sha256_public_encrypt");
|
||||||
|
/*
|
||||||
|
Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len.
|
||||||
|
RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here:
|
||||||
|
http://www.openssl.org/docs/crypto/RSA_public_encrypt.html
|
||||||
|
*/
|
||||||
|
if (server_public_key_len <= passwd_len + 41) {
|
||||||
|
/* password message is to long */
|
||||||
|
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
|
||||||
|
DBG_ERR("password is too long");
|
||||||
|
DBG_RETURN(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
*auth_data_len = server_public_key_len;
|
||||||
|
ret = malloc(*auth_data_len);
|
||||||
|
RSA_public_encrypt(passwd_len + 1, (zend_uchar *) xor_str, ret, server_public_key, RSA_PKCS1_OAEP_PADDING);
|
||||||
|
RSA_free(server_public_key);
|
||||||
|
DBG_RETURN(ret);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <wincrypt.h>
|
||||||
|
#include <bcrypt.h>
|
||||||
|
|
||||||
|
typedef HANDLE mysqlnd_rsa_t;
|
||||||
|
|
||||||
|
/* {{{ mysqlnd_sha256_get_rsa_from_pem */
|
||||||
|
static mysqlnd_rsa_t
|
||||||
|
mysqlnd_sha256_get_rsa_from_pem(const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
BCRYPT_KEY_HANDLE ret = 0;
|
||||||
|
LPCSTR der_buf = NULL;
|
||||||
|
DWORD der_len;
|
||||||
|
CERT_PUBLIC_KEY_INFO *key_info = NULL;
|
||||||
|
DWORD key_info_len;
|
||||||
|
ALLOCA_FLAG(use_heap);
|
||||||
|
|
||||||
|
if (!CryptStringToBinaryA(buf, len, CRYPT_STRING_BASE64HEADER, NULL, &der_len, NULL, NULL)) {
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
der_buf = do_alloca(der_len, use_heap);
|
||||||
|
if (!CryptStringToBinaryA(buf, len, CRYPT_STRING_BASE64HEADER, der_buf, &der_len, NULL, NULL)) {
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, der_buf, der_len, CRYPT_ENCODE_ALLOC_FLAG, NULL, &key_info, &key_info_len)) {
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
if (!CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING, key_info, CRYPT_OID_INFO_PUBKEY_ENCRYPT_KEY_FLAG, NULL, &ret)) {
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
finish:
|
||||||
|
if (key_info) {
|
||||||
|
LocalFree(key_info);
|
||||||
|
}
|
||||||
|
if (der_buf) {
|
||||||
|
free_alloca(der_buf, use_heap);
|
||||||
|
}
|
||||||
|
return (mysqlnd_rsa_t) ret;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ mysqlnd_sha256_public_encrypt */
|
||||||
|
static zend_uchar *
|
||||||
|
mysqlnd_sha256_public_encrypt(MYSQLND_CONN_DATA * conn, mysqlnd_rsa_t server_public_key, size_t passwd_len, size_t * auth_data_len, char *xor_str)
|
||||||
|
{
|
||||||
|
zend_uchar * ret = NULL;
|
||||||
|
DWORD server_public_key_len = passwd_len;
|
||||||
|
BCRYPT_OAEP_PADDING_INFO padding_info;
|
||||||
|
|
||||||
|
DBG_ENTER("mysqlnd_sha256_public_encrypt");
|
||||||
|
|
||||||
|
ZeroMemory(&padding_info, sizeof padding_info);
|
||||||
|
padding_info.pszAlgId = BCRYPT_SHA1_ALGORITHM;
|
||||||
|
if (BCryptEncrypt((BCRYPT_KEY_HANDLE) server_public_key, xor_str, passwd_len + 1, &padding_info,
|
||||||
|
NULL, 0, NULL, 0, &server_public_key_len, BCRYPT_PAD_OAEP)) {
|
||||||
|
DBG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len.
|
||||||
|
RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here:
|
||||||
|
http://www.openssl.org/docs/crypto/RSA_public_encrypt.html
|
||||||
|
*/
|
||||||
|
if ((size_t) server_public_key_len <= passwd_len + 41) {
|
||||||
|
/* password message is to long */
|
||||||
|
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
|
||||||
|
DBG_ERR("password is too long");
|
||||||
|
DBG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
*auth_data_len = server_public_key_len;
|
||||||
|
ret = malloc(*auth_data_len);
|
||||||
|
if (BCryptEncrypt((BCRYPT_KEY_HANDLE) server_public_key, xor_str, passwd_len + 1, &padding_info,
|
||||||
|
NULL, 0, ret, server_public_key_len, &server_public_key_len, BCRYPT_PAD_OAEP)) {
|
||||||
|
DBG_RETURN(0);
|
||||||
|
}
|
||||||
|
BCryptDestroyKey((BCRYPT_KEY_HANDLE) server_public_key);
|
||||||
|
DBG_RETURN(ret);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* {{{ mysqlnd_sha256_get_rsa_key */
|
/* {{{ mysqlnd_sha256_get_rsa_key */
|
||||||
static RSA *
|
static mysqlnd_rsa_t
|
||||||
mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn,
|
mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn,
|
||||||
const MYSQLND_SESSION_OPTIONS * const session_options,
|
const MYSQLND_SESSION_OPTIONS * const session_options,
|
||||||
const MYSQLND_PFC_DATA * const pfc_data
|
const MYSQLND_PFC_DATA * const pfc_data
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
RSA * ret = NULL;
|
mysqlnd_rsa_t ret = NULL;
|
||||||
const char * fname = (pfc_data->sha256_server_public_key && pfc_data->sha256_server_public_key[0] != '\0')?
|
const char * fname = (pfc_data->sha256_server_public_key && pfc_data->sha256_server_public_key[0] != '\0')?
|
||||||
pfc_data->sha256_server_public_key:
|
pfc_data->sha256_server_public_key:
|
||||||
MYSQLND_G(sha256_server_public_key);
|
MYSQLND_G(sha256_server_public_key);
|
||||||
|
@ -737,11 +863,7 @@ mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn,
|
||||||
}
|
}
|
||||||
DBG_INF_FMT("Public key(%d):\n%s", pk_resp_packet.public_key_len, pk_resp_packet.public_key);
|
DBG_INF_FMT("Public key(%d):\n%s", pk_resp_packet.public_key_len, pk_resp_packet.public_key);
|
||||||
/* now extract the public key */
|
/* now extract the public key */
|
||||||
{
|
ret = mysqlnd_sha256_get_rsa_from_pem((const char *) pk_resp_packet.public_key, pk_resp_packet.public_key_len);
|
||||||
BIO * bio = BIO_new_mem_buf(pk_resp_packet.public_key, pk_resp_packet.public_key_len);
|
|
||||||
ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
|
|
||||||
BIO_free(bio);
|
|
||||||
}
|
|
||||||
} while (0);
|
} while (0);
|
||||||
PACKET_FREE(&pk_req_packet);
|
PACKET_FREE(&pk_req_packet);
|
||||||
PACKET_FREE(&pk_resp_packet);
|
PACKET_FREE(&pk_resp_packet);
|
||||||
|
@ -760,9 +882,7 @@ mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn,
|
||||||
|
|
||||||
if (stream) {
|
if (stream) {
|
||||||
if ((key_str = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) != NULL) {
|
if ((key_str = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) != NULL) {
|
||||||
BIO * bio = BIO_new_mem_buf(ZSTR_VAL(key_str), ZSTR_LEN(key_str));
|
ret = mysqlnd_sha256_get_rsa_from_pem(ZSTR_VAL(key_str), ZSTR_LEN(key_str));
|
||||||
ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
|
|
||||||
BIO_free(bio);
|
|
||||||
DBG_INF("Successfully loaded");
|
DBG_INF("Successfully loaded");
|
||||||
DBG_INF_FMT("Public key:%*.s", ZSTR_LEN(key_str), ZSTR_VAL(key_str));
|
DBG_INF_FMT("Public key:%*.s", ZSTR_LEN(key_str), ZSTR_VAL(key_str));
|
||||||
zend_string_release_ex(key_str, 0);
|
zend_string_release_ex(key_str, 0);
|
||||||
|
@ -786,7 +906,7 @@ mysqlnd_sha256_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self
|
||||||
const zend_ulong mysql_flags
|
const zend_ulong mysql_flags
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
RSA * server_public_key;
|
mysqlnd_rsa_t server_public_key;
|
||||||
zend_uchar * ret = NULL;
|
zend_uchar * ret = NULL;
|
||||||
DBG_ENTER("mysqlnd_sha256_auth_get_auth_data");
|
DBG_ENTER("mysqlnd_sha256_auth_get_auth_data");
|
||||||
DBG_INF_FMT("salt(%d)=[%.*s]", auth_plugin_data_len, auth_plugin_data_len, auth_plugin_data);
|
DBG_INF_FMT("salt(%d)=[%.*s]", auth_plugin_data_len, auth_plugin_data_len, auth_plugin_data);
|
||||||
|
@ -803,31 +923,12 @@ mysqlnd_sha256_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self
|
||||||
server_public_key = mysqlnd_sha256_get_rsa_key(conn, session_options, pfc_data);
|
server_public_key = mysqlnd_sha256_get_rsa_key(conn, session_options, pfc_data);
|
||||||
|
|
||||||
if (server_public_key) {
|
if (server_public_key) {
|
||||||
int server_public_key_len;
|
|
||||||
ALLOCA_FLAG(use_heap);
|
ALLOCA_FLAG(use_heap);
|
||||||
char *xor_str = do_alloca(passwd_len + 1, use_heap);
|
char *xor_str = do_alloca(passwd_len + 1, use_heap);
|
||||||
memcpy(xor_str, passwd, passwd_len);
|
memcpy(xor_str, passwd, passwd_len);
|
||||||
xor_str[passwd_len] = '\0';
|
xor_str[passwd_len] = '\0';
|
||||||
mysqlnd_xor_string(xor_str, passwd_len, (char *) auth_plugin_data, auth_plugin_data_len);
|
mysqlnd_xor_string(xor_str, passwd_len, (char *) auth_plugin_data, auth_plugin_data_len);
|
||||||
|
ret = mysqlnd_sha256_public_encrypt(conn, server_public_key, passwd_len, auth_data_len, xor_str);
|
||||||
server_public_key_len = RSA_size(server_public_key);
|
|
||||||
/*
|
|
||||||
Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len.
|
|
||||||
RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here:
|
|
||||||
http://www.openssl.org/docs/crypto/RSA_public_encrypt.html
|
|
||||||
*/
|
|
||||||
if ((size_t) server_public_key_len - 41 <= passwd_len) {
|
|
||||||
/* password message is to long */
|
|
||||||
free_alloca(xor_str, use_heap);
|
|
||||||
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
|
|
||||||
DBG_ERR("password is too long");
|
|
||||||
DBG_RETURN(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
*auth_data_len = server_public_key_len;
|
|
||||||
ret = malloc(*auth_data_len);
|
|
||||||
RSA_public_encrypt(passwd_len + 1, (zend_uchar *) xor_str, ret, server_public_key, RSA_PKCS1_OAEP_PADDING);
|
|
||||||
RSA_free(server_public_key);
|
|
||||||
free_alloca(xor_str, use_heap);
|
free_alloca(xor_str, use_heap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -899,6 +1000,73 @@ void php_mysqlnd_scramble_sha2(zend_uchar * const buffer, const zend_uchar * con
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
#ifndef PHP_WIN32
|
||||||
|
|
||||||
|
/* {{{ mysqlnd_caching_sha2_public_encrypt */
|
||||||
|
static size_t
|
||||||
|
mysqlnd_caching_sha2_public_encrypt(MYSQLND_CONN_DATA * conn, mysqlnd_rsa_t server_public_key, size_t passwd_len, unsigned char **crypted, char *xor_str)
|
||||||
|
{
|
||||||
|
size_t server_public_key_len = (size_t) RSA_size(server_public_key);
|
||||||
|
|
||||||
|
DBG_ENTER("mysqlnd_caching_sha2_public_encrypt");
|
||||||
|
/*
|
||||||
|
Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len.
|
||||||
|
RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here:
|
||||||
|
http://www.openssl.org/docs/crypto/RSA_public_encrypt.html
|
||||||
|
*/
|
||||||
|
if (server_public_key_len <= passwd_len + 41) {
|
||||||
|
/* password message is to long */
|
||||||
|
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
|
||||||
|
DBG_ERR("password is too long");
|
||||||
|
DBG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
*crypted = emalloc(server_public_key_len);
|
||||||
|
RSA_public_encrypt(passwd_len + 1, (zend_uchar *) xor_str, *crypted, server_public_key, RSA_PKCS1_OAEP_PADDING);
|
||||||
|
DBG_RETURN(server_public_key_len);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* {{{ mysqlnd_caching_sha2_public_encrypt */
|
||||||
|
static size_t
|
||||||
|
mysqlnd_caching_sha2_public_encrypt(MYSQLND_CONN_DATA * conn, mysqlnd_rsa_t server_public_key, size_t passwd_len, unsigned char **crypted, char *xor_str)
|
||||||
|
{
|
||||||
|
DWORD server_public_key_len = passwd_len;
|
||||||
|
BCRYPT_OAEP_PADDING_INFO padding_info;
|
||||||
|
|
||||||
|
DBG_ENTER("mysqlnd_caching_sha2_public_encrypt");
|
||||||
|
|
||||||
|
ZeroMemory(&padding_info, sizeof padding_info);
|
||||||
|
padding_info.pszAlgId = BCRYPT_SHA1_ALGORITHM;
|
||||||
|
if (BCryptEncrypt((BCRYPT_KEY_HANDLE) server_public_key, xor_str, passwd_len + 1, &padding_info,
|
||||||
|
NULL, 0, NULL, 0, &server_public_key_len, BCRYPT_PAD_OAEP)) {
|
||||||
|
DBG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len.
|
||||||
|
RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here:
|
||||||
|
http://www.openssl.org/docs/crypto/RSA_public_encrypt.html
|
||||||
|
*/
|
||||||
|
if ((size_t) server_public_key_len <= passwd_len + 41) {
|
||||||
|
/* password message is to long */
|
||||||
|
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
|
||||||
|
DBG_ERR("password is too long");
|
||||||
|
DBG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
*crypted = emalloc(server_public_key_len);
|
||||||
|
if (BCryptEncrypt((BCRYPT_KEY_HANDLE) server_public_key, xor_str, passwd_len + 1, &padding_info,
|
||||||
|
NULL, 0, *crypted, server_public_key_len, &server_public_key_len, BCRYPT_PAD_OAEP)) {
|
||||||
|
DBG_RETURN(0);
|
||||||
|
}
|
||||||
|
DBG_RETURN(server_public_key_len);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* {{{ mysqlnd_native_auth_get_auth_data */
|
/* {{{ mysqlnd_native_auth_get_auth_data */
|
||||||
static zend_uchar *
|
static zend_uchar *
|
||||||
|
@ -936,10 +1104,10 @@ mysqlnd_caching_sha2_get_auth_data(struct st_mysqlnd_authentication_plugin * sel
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static RSA *
|
static mysqlnd_rsa_t
|
||||||
mysqlnd_caching_sha2_get_key(MYSQLND_CONN_DATA *conn)
|
mysqlnd_caching_sha2_get_key(MYSQLND_CONN_DATA *conn)
|
||||||
{
|
{
|
||||||
RSA * ret = NULL;
|
mysqlnd_rsa_t ret = NULL;
|
||||||
const MYSQLND_PFC_DATA * const pfc_data = conn->protocol_frame_codec->data;
|
const MYSQLND_PFC_DATA * const pfc_data = conn->protocol_frame_codec->data;
|
||||||
const char * fname = (pfc_data->sha256_server_public_key && pfc_data->sha256_server_public_key[0] != '\0')?
|
const char * fname = (pfc_data->sha256_server_public_key && pfc_data->sha256_server_public_key[0] != '\0')?
|
||||||
pfc_data->sha256_server_public_key:
|
pfc_data->sha256_server_public_key:
|
||||||
|
@ -973,11 +1141,7 @@ mysqlnd_caching_sha2_get_key(MYSQLND_CONN_DATA *conn)
|
||||||
}
|
}
|
||||||
DBG_INF_FMT("Public key(%d):\n%s", pk_resp_packet.public_key_len, pk_resp_packet.public_key);
|
DBG_INF_FMT("Public key(%d):\n%s", pk_resp_packet.public_key_len, pk_resp_packet.public_key);
|
||||||
/* now extract the public key */
|
/* now extract the public key */
|
||||||
{
|
ret = mysqlnd_sha256_get_rsa_from_pem((const char *) pk_resp_packet.public_key, pk_resp_packet.public_key_len);
|
||||||
BIO * bio = BIO_new_mem_buf(pk_resp_packet.public_key, pk_resp_packet.public_key_len);
|
|
||||||
ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
|
|
||||||
BIO_free(bio);
|
|
||||||
}
|
|
||||||
} while (0);
|
} while (0);
|
||||||
PACKET_FREE(&req_packet);
|
PACKET_FREE(&req_packet);
|
||||||
PACKET_FREE(&pk_resp_packet);
|
PACKET_FREE(&pk_resp_packet);
|
||||||
|
@ -996,9 +1160,7 @@ mysqlnd_caching_sha2_get_key(MYSQLND_CONN_DATA *conn)
|
||||||
|
|
||||||
if (stream) {
|
if (stream) {
|
||||||
if ((key_str = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) != NULL) {
|
if ((key_str = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) != NULL) {
|
||||||
BIO * bio = BIO_new_mem_buf(ZSTR_VAL(key_str), ZSTR_LEN(key_str));
|
ret = mysqlnd_sha256_get_rsa_from_pem(ZSTR_VAL(key_str), ZSTR_LEN(key_str));
|
||||||
ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
|
|
||||||
BIO_free(bio);
|
|
||||||
DBG_INF("Successfully loaded");
|
DBG_INF("Successfully loaded");
|
||||||
DBG_INF_FMT("Public key:%*.s", ZSTR_LEN(key_str), ZSTR_VAL(key_str));
|
DBG_INF_FMT("Public key:%*.s", ZSTR_LEN(key_str), ZSTR_VAL(key_str));
|
||||||
zend_string_release(key_str);
|
zend_string_release(key_str);
|
||||||
|
@ -1011,7 +1173,7 @@ mysqlnd_caching_sha2_get_key(MYSQLND_CONN_DATA *conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* {{{ mysqlnd_caching_sha2_get_key */
|
/* {{{ mysqlnd_caching_sha2_get_and_use_key */
|
||||||
static size_t
|
static size_t
|
||||||
mysqlnd_caching_sha2_get_and_use_key(MYSQLND_CONN_DATA *conn,
|
mysqlnd_caching_sha2_get_and_use_key(MYSQLND_CONN_DATA *conn,
|
||||||
const zend_uchar * auth_plugin_data, const size_t auth_plugin_data_len,
|
const zend_uchar * auth_plugin_data, const size_t auth_plugin_data_len,
|
||||||
|
@ -1019,8 +1181,7 @@ mysqlnd_caching_sha2_get_and_use_key(MYSQLND_CONN_DATA *conn,
|
||||||
const char * const passwd,
|
const char * const passwd,
|
||||||
const size_t passwd_len)
|
const size_t passwd_len)
|
||||||
{
|
{
|
||||||
static RSA *server_public_key;
|
mysqlnd_rsa_t server_public_key = mysqlnd_caching_sha2_get_key(conn);
|
||||||
server_public_key = mysqlnd_caching_sha2_get_key(conn);
|
|
||||||
|
|
||||||
DBG_ENTER("mysqlnd_caching_sha2_get_and_use_key(");
|
DBG_ENTER("mysqlnd_caching_sha2_get_and_use_key(");
|
||||||
|
|
||||||
|
@ -1031,23 +1192,7 @@ mysqlnd_caching_sha2_get_and_use_key(MYSQLND_CONN_DATA *conn,
|
||||||
memcpy(xor_str, passwd, passwd_len);
|
memcpy(xor_str, passwd, passwd_len);
|
||||||
xor_str[passwd_len] = '\0';
|
xor_str[passwd_len] = '\0';
|
||||||
mysqlnd_xor_string(xor_str, passwd_len, (char *) auth_plugin_data, SCRAMBLE_LENGTH);
|
mysqlnd_xor_string(xor_str, passwd_len, (char *) auth_plugin_data, SCRAMBLE_LENGTH);
|
||||||
|
server_public_key_len = mysqlnd_caching_sha2_public_encrypt(conn, server_public_key, passwd_len, crypted, xor_str);
|
||||||
server_public_key_len = RSA_size(server_public_key);
|
|
||||||
/*
|
|
||||||
Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len.
|
|
||||||
RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here:
|
|
||||||
http://www.openssl.org/docs/crypto/RSA_public_encrypt.html
|
|
||||||
*/
|
|
||||||
if ((size_t) server_public_key_len - 41 <= passwd_len) {
|
|
||||||
/* password message is to long */
|
|
||||||
free_alloca(xor_str, use_heap);
|
|
||||||
SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
|
|
||||||
DBG_ERR("password is too long");
|
|
||||||
DBG_RETURN(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
*crypted = emalloc(server_public_key_len);
|
|
||||||
RSA_public_encrypt(passwd_len + 1, (zend_uchar *) xor_str, *crypted, server_public_key, RSA_PKCS1_OAEP_PADDING);
|
|
||||||
free_alloca(xor_str, use_heap);
|
free_alloca(xor_str, use_heap);
|
||||||
DBG_RETURN(server_public_key_len);
|
DBG_RETURN(server_public_key_len);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue