diff --git a/components/encryption_udf/encryption_udf_component.cc b/components/encryption_udf/encryption_udf_component.cc index e3366bae3b58..88a53798463d 100644 --- a/components/encryption_udf/encryption_udf_component.cc +++ b/components/encryption_udf/encryption_udf_component.cc @@ -32,8 +32,10 @@ #include #include #include +#include #include +#include #include #include @@ -44,11 +46,14 @@ #include #include #include +#include +#include +#include +#include #include #include +#include #include -#include -#include #include "server_helpers.h" @@ -58,49 +63,54 @@ REQUIRES_SERVICE_PLACEHOLDER(mysql_runtime_error); REQUIRES_SERVICE_PLACEHOLDER(udf_registration); +REQUIRES_SERVICE_PLACEHOLDER(mysql_udf_metadata); REQUIRES_SERVICE_PLACEHOLDER(component_sys_variable_register); REQUIRES_SERVICE_PLACEHOLDER(component_sys_variable_unregister); REQUIRES_SERVICE_PLACEHOLDER(mysql_current_thread_reader); namespace { -// clang-format off -#define ENCRYPTION_UDF_X_MACRO_LIST() \ - ENCRYPTION_UDF_X_MACRO(rsa), \ - ENCRYPTION_UDF_X_MACRO(dsa), \ - ENCRYPTION_UDF_X_MACRO(dh) -// clang-format on +opensslpp::evp_pkey_algorithm get_and_validate_algorithm_id_by_label( + std::string_view algorithm) { + if (algorithm.data() == nullptr) + throw std::invalid_argument("Algorithm cannot be NULL"); -#define ENCRYPTION_UDF_X_MACRO(X) X -enum class algorithm_id_type { ENCRYPTION_UDF_X_MACRO_LIST(), delimiter }; -#undef ENCRYPTION_UDF_X_MACRO + if (boost::iequals(algorithm, "rsa")) + return opensslpp::evp_pkey_algorithm::rsa; + if (boost::iequals(algorithm, "dsa")) + return opensslpp::evp_pkey_algorithm::dsa; + if (boost::iequals(algorithm, "dh")) return opensslpp::evp_pkey_algorithm::dh; -constexpr std::size_t number_of_algorithms = - static_cast(algorithm_id_type::delimiter); + throw std::invalid_argument("Invalid algorithm specified"); +} -#define ENCRYPTION_UDF_X_MACRO(X) BOOST_PP_STRINGIZE(X) -constexpr std::array - algorithm_id_labels = {ENCRYPTION_UDF_X_MACRO_LIST()}; -#undef ENCRYPTION_UDF_X_MACRO +opensslpp::rsa_encryption_padding +get_and_validate_rsa_encryption_padding_by_label(std::string_view padding) { + if (padding.data() == nullptr) + throw std::invalid_argument("RSA encryption padding scheme cannot be NULL"); -#undef ENCRYPTION_UDF_X_MACRO_LIST + if (boost::iequals(padding, "no")) + return opensslpp::rsa_encryption_padding::no; + if (boost::iequals(padding, "pkcs1")) + return opensslpp::rsa_encryption_padding::pkcs1; + if (boost::iequals(padding, "oaep")) + return opensslpp::rsa_encryption_padding::pkcs1_oaep; -algorithm_id_type get_algorithm_id_by_label( - std::string_view algorithm) noexcept { - assert(algorithm.data() != nullptr); - std::size_t index = 0; - while (index < number_of_algorithms && - !boost::iequals(algorithm, algorithm_id_labels[index])) - ++index; - return static_cast(index); + throw std::invalid_argument( + "Invalid RSA encryption padding scheme specified"); } -algorithm_id_type get_and_validate_algorithm_id_by_label( - std::string_view algorithm) { - auto res = get_algorithm_id_by_label(algorithm); - if (res == algorithm_id_type::delimiter) - throw std::invalid_argument("Invalid algorithm specified"); - return res; +opensslpp::evp_pkey_signature_padding +get_and_validate_evp_pkey_signature_padding_by_label(std::string_view padding) { + if (padding.data() == nullptr) + throw std::invalid_argument("RSA signature padding scheme cannot be NULL"); + + if (boost::iequals(padding, "pkcs1")) + return opensslpp::evp_pkey_signature_padding::rsa_pkcs1; + if (boost::iequals(padding, "pkcs1_pss")) + return opensslpp::evp_pkey_signature_padding::rsa_pkcs1_pss; + + throw std::invalid_argument("Invalid RSA signature padding scheme specified"); } enum class threshold_index_type { rsa, dsa, dh, delimiter }; @@ -108,6 +118,7 @@ constexpr std::size_t number_of_thresholds = static_cast(threshold_index_type::delimiter); uint bits_threshold_values[number_of_thresholds] = {}; +bool legacy_padding_scheme_value{false}; struct threshold_definition { std::size_t min; @@ -130,35 +141,26 @@ constexpr std::array thresholds = { threshold_definition{ 1024U, 10000U, "dh_bits_threshold", "Maximum DH key length in bits for create_dh_parameters()"}}; +constexpr char legacy_padding_scheme_variable_name[] = "legacy_padding_scheme"; +constexpr char legacy_padding_scheme_variable_description[] = + "Enable legacy padding scheme for RSA sign/verify and encrypt/decrypt"; using udf_int_arg_raw_type = mysqlpp::udf_arg_t::value_type; bool check_if_bits_in_range(udf_int_arg_raw_type value, threshold_index_type threshold_index) noexcept { - const auto &threshold = thresholds[static_cast(threshold_index)]; + const auto casted_threshold_index{static_cast(threshold_index)}; + const auto &threshold = thresholds[casted_threshold_index]; if (value < static_cast(threshold.min)) return false; - std::size_t max_value = threshold.max; - - static constexpr std::size_t var_buffer_length = 63U; - using var_buffer_type = std::array; - var_buffer_type var_buffer; - void *var_buffer_ptr = var_buffer.data(); - std::size_t var_length = var_buffer_length; - - if (mysql_service_component_sys_variable_register->get_variable( - CURRENT_COMPONENT_NAME_STR, threshold.var_name, &var_buffer_ptr, - &var_length) == 0) { - std::size_t extracted_var_value = 0; - if (boost::conversion::try_lexical_convert( - static_cast(var_buffer_ptr), var_length, - extracted_var_value)) - max_value = extracted_var_value; - } + std::size_t max_value = bits_threshold_values[casted_threshold_index]; if (value > static_cast(max_value)) return false; return true; } +bool check_if_legacy_padding_scheme() noexcept { + return legacy_padding_scheme_value; +} opensslpp::key_generation_cancellation_callback create_cancellation_callback() { THD *local_thd = nullptr; @@ -169,6 +171,9 @@ opensslpp::key_generation_cancellation_callback create_cancellation_callback() { return [local_thd]() noexcept -> bool { return is_thd_killed(local_thd); }; } +constexpr char ascii_charset_name[]{"ascii"}; +constexpr char binary_charset_name[]{"binary"}; + // CREATE_ASYMMETRIC_PRIV_KEY(@algorithm, {@key_len|@dh_parameters}) // This functions generates a private key using the given algorithm // (@algorithm) and key length (@key_len) or Diffie-Hellman @@ -180,17 +185,23 @@ class create_asymmetric_priv_key_impl { if (ctx.get_number_of_args() != 2) throw std::invalid_argument("Function requires exactly two arguments"); + mysqlpp::udf_context_charset_extension charset_ext{ + mysql_service_mysql_udf_metadata}; + // result ctx.mark_result_const(false); ctx.mark_result_nullable(true); + charset_ext.set_return_value_charset(ctx, ascii_charset_name); // arg0 - @algorithm ctx.mark_arg_nullable(0, false); ctx.set_arg_type(0, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 0, ascii_charset_name); // arg1 - @key_len|@dh_parameters ctx.mark_arg_nullable(1, false); ctx.set_arg_type(1, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 1, ascii_charset_name); } mysqlpp::udf_result_t calculate( @@ -199,36 +210,35 @@ class create_asymmetric_priv_key_impl { mysqlpp::udf_result_t create_asymmetric_priv_key_impl::calculate( const mysqlpp::udf_context &ctx) { - auto algorithm = ctx.get_arg(0); - auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm); - auto length_or_dh_parameters = ctx.get_arg(1); + auto algorithm_sv = ctx.get_arg(0); + auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm_sv); + auto length_or_dh_parameters_sv = ctx.get_arg(1); std::string pem; - if (algorithm_id == algorithm_id_type::dh) { - auto dh_parameters_pem = static_cast(length_or_dh_parameters); - - auto key = opensslpp::dh_key::import_parameters_pem(dh_parameters_pem); + if (algorithm_id == opensslpp::evp_pkey_algorithm::dh) { + auto key = + opensslpp::dh_key::import_parameters_pem(length_or_dh_parameters_sv); key.promote_to_key(); pem = opensslpp::dh_key::export_private_pem(key); } else { std::uint32_t length = 0; - if (!boost::conversion::try_lexical_convert(length_or_dh_parameters, + if (!boost::conversion::try_lexical_convert(length_or_dh_parameters_sv, length)) throw std::invalid_argument("Key length is not a numeric value"); - if (algorithm_id == algorithm_id_type::rsa) { + if (algorithm_id == opensslpp::evp_pkey_algorithm::rsa) { if (!check_if_bits_in_range(length, threshold_index_type::rsa)) throw std::invalid_argument("Invalid RSA key length specified"); - opensslpp::rsa_key key; + + opensslpp::evp_pkey key; try { - key = opensslpp::rsa_key::generate(length, - opensslpp::rsa_key::default_exponent, - create_cancellation_callback()); + key = opensslpp::evp_pkey::generate(algorithm_id, length, + create_cancellation_callback()); } catch (const opensslpp::operation_cancelled_error &e) { throw mysqlpp::udf_exception{e.what(), ER_QUERY_INTERRUPTED}; } - pem = opensslpp::rsa_key::export_private_pem(key); - } else if (algorithm_id == algorithm_id_type::dsa) { + pem = opensslpp::evp_pkey::export_private_pem(key); + } else if (algorithm_id == opensslpp::evp_pkey_algorithm::dsa) { if (!check_if_bits_in_range(length, threshold_index_type::dsa)) throw std::invalid_argument("Invalid DSA key length specified"); opensslpp::dsa_key key; @@ -256,17 +266,23 @@ class create_asymmetric_pub_key_impl { if (ctx.get_number_of_args() != 2) throw std::invalid_argument("Function requires exactly two arguments"); + mysqlpp::udf_context_charset_extension charset_ext{ + mysql_service_mysql_udf_metadata}; + // result ctx.mark_result_const(false); ctx.mark_result_nullable(true); + charset_ext.set_return_value_charset(ctx, ascii_charset_name); // arg0 - @algorithm ctx.mark_arg_nullable(0, false); ctx.set_arg_type(0, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 0, ascii_charset_name); // arg1 - @priv_key_str ctx.mark_arg_nullable(1, false); ctx.set_arg_type(1, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 1, ascii_charset_name); } mysqlpp::udf_result_t calculate( @@ -275,19 +291,19 @@ class create_asymmetric_pub_key_impl { mysqlpp::udf_result_t create_asymmetric_pub_key_impl::calculate( const mysqlpp::udf_context &ctx) { - auto algorithm = ctx.get_arg(0); - auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm); - auto priv_key_pem = static_cast(ctx.get_arg(1)); + auto algorithm_sv = ctx.get_arg(0); + auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm_sv); + auto priv_key_pem_sv = ctx.get_arg(1); std::string pem; - if (algorithm_id == algorithm_id_type::rsa) { - auto priv_key = opensslpp::rsa_key::import_private_pem(priv_key_pem); - pem = opensslpp::rsa_key::export_public_pem(priv_key); - } else if (algorithm_id == algorithm_id_type::dsa) { - auto priv_key = opensslpp::dsa_key::import_private_pem(priv_key_pem); + if (algorithm_id == opensslpp::evp_pkey_algorithm::rsa) { + auto priv_key = opensslpp::evp_pkey::import_private_pem(priv_key_pem_sv); + pem = opensslpp::evp_pkey::export_public_pem(priv_key); + } else if (algorithm_id == opensslpp::evp_pkey_algorithm::dsa) { + auto priv_key = opensslpp::dsa_key::import_private_pem(priv_key_pem_sv); pem = opensslpp::dsa_key::export_public_pem(priv_key); - } else if (algorithm_id == algorithm_id_type::dh) { - auto priv_key = opensslpp::dh_key::import_private_pem(priv_key_pem); + } else if (algorithm_id == opensslpp::evp_pkey_algorithm::dh) { + auto priv_key = opensslpp::dh_key::import_private_pem(priv_key_pem_sv); pem = opensslpp::dh_key::export_public_pem(priv_key); } return {std::move(pem)}; @@ -300,24 +316,38 @@ mysqlpp::udf_result_t create_asymmetric_pub_key_impl::calculate( class asymmetric_encrypt_impl { public: asymmetric_encrypt_impl(mysqlpp::udf_context &ctx) { - if (ctx.get_number_of_args() != 3) - throw std::invalid_argument("Function requires exactly three arguments"); + if (ctx.get_number_of_args() < 3 || ctx.get_number_of_args() > 4) + throw std::invalid_argument("Function requires three or four arguments"); + + mysqlpp::udf_context_charset_extension charset_ext{ + mysql_service_mysql_udf_metadata}; // result ctx.mark_result_const(false); ctx.mark_result_nullable(true); + charset_ext.set_return_value_charset(ctx, binary_charset_name); // arg0 - @algorithm ctx.mark_arg_nullable(0, false); ctx.set_arg_type(0, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 0, ascii_charset_name); // arg1 - @str ctx.mark_arg_nullable(1, false); ctx.set_arg_type(1, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 1, binary_charset_name); // arg2 - @key_str ctx.mark_arg_nullable(2, false); ctx.set_arg_type(2, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 2, ascii_charset_name); + + // optional arg3 - @padding + if (ctx.get_number_of_args() == 4) { + ctx.mark_arg_nullable(3, false); + ctx.set_arg_type(3, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 3, ascii_charset_name); + } } mysqlpp::udf_result_t calculate( @@ -326,28 +356,34 @@ class asymmetric_encrypt_impl { mysqlpp::udf_result_t asymmetric_encrypt_impl::calculate( const mysqlpp::udf_context &ctx) { - auto algorithm = ctx.get_arg(0); - auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm); - if (algorithm_id != algorithm_id_type::rsa) + auto algorithm_sv = ctx.get_arg(0); + auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm_sv); + if (algorithm_id != opensslpp::evp_pkey_algorithm::rsa) throw std::invalid_argument("Invalid algorithm specified"); auto message_sv = ctx.get_arg(1); - auto message = static_cast(message_sv); - auto key_pem_sv = ctx.get_arg(2); - auto key_pem = static_cast(key_pem_sv); + + opensslpp::rsa_encryption_padding padding{ + check_if_legacy_padding_scheme() + ? opensslpp::rsa_encryption_padding::pkcs1 + : opensslpp::rsa_encryption_padding::pkcs1_oaep}; + if (ctx.get_number_of_args() == 4) { + auto padding_sv = ctx.get_arg(3); + padding = get_and_validate_rsa_encryption_padding_by_label(padding_sv); + } opensslpp::rsa_key key; try { - key = opensslpp::rsa_key::import_private_pem(key_pem); + key = opensslpp::rsa_key::import_private_pem(key_pem_sv); } catch (const opensslpp::core_error &) { - key = opensslpp::rsa_key::import_public_pem(key_pem); + key = opensslpp::rsa_key::import_public_pem(key_pem_sv); } - return {key.is_private() ? opensslpp::encrypt_with_rsa_private_key( - message, key, opensslpp::rsa_padding::pkcs1) - : opensslpp::encrypt_with_rsa_public_key( - message, key, opensslpp::rsa_padding::pkcs1)}; + return { + key.is_private() + ? opensslpp::encrypt_with_rsa_private_key(message_sv, key, padding) + : opensslpp::encrypt_with_rsa_public_key(message_sv, key, padding)}; } // ASYMMETRIC_DECRYPT(@algorithm, @crypt_str, @key_str) @@ -357,24 +393,38 @@ mysqlpp::udf_result_t asymmetric_encrypt_impl::calculate( class asymmetric_decrypt_impl { public: asymmetric_decrypt_impl(mysqlpp::udf_context &ctx) { - if (ctx.get_number_of_args() != 3) - throw std::invalid_argument("Function requires exactly three arguments"); + if (ctx.get_number_of_args() < 3 || ctx.get_number_of_args() > 4) + throw std::invalid_argument("Function requires three or four arguments"); + + mysqlpp::udf_context_charset_extension charset_ext{ + mysql_service_mysql_udf_metadata}; // result ctx.mark_result_const(false); ctx.mark_result_nullable(true); + charset_ext.set_return_value_charset(ctx, binary_charset_name); // arg0 - @algorithm ctx.mark_arg_nullable(0, false); ctx.set_arg_type(0, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 0, ascii_charset_name); // arg1 - @crypt_str ctx.mark_arg_nullable(1, false); ctx.set_arg_type(1, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 1, binary_charset_name); // arg2 - @key_str ctx.mark_arg_nullable(2, false); ctx.set_arg_type(2, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 2, ascii_charset_name); + + // optional arg3 - @padding + if (ctx.get_number_of_args() == 4) { + ctx.mark_arg_nullable(3, false); + ctx.set_arg_type(3, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 3, ascii_charset_name); + } } mysqlpp::udf_result_t calculate( @@ -383,28 +433,34 @@ class asymmetric_decrypt_impl { mysqlpp::udf_result_t asymmetric_decrypt_impl::calculate( const mysqlpp::udf_context &ctx) { - auto algorithm = ctx.get_arg(0); - auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm); - if (algorithm_id != algorithm_id_type::rsa) + auto algorithm_sv = ctx.get_arg(0); + auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm_sv); + if (algorithm_id != opensslpp::evp_pkey_algorithm::rsa) throw std::invalid_argument("Invalid algorithm specified"); auto message_sv = ctx.get_arg(1); - auto message = static_cast(message_sv); - auto key_pem_sv = ctx.get_arg(2); - auto key_pem = static_cast(key_pem_sv); + + opensslpp::rsa_encryption_padding padding{ + check_if_legacy_padding_scheme() + ? opensslpp::rsa_encryption_padding::pkcs1 + : opensslpp::rsa_encryption_padding::pkcs1_oaep}; + if (ctx.get_number_of_args() == 4) { + auto padding_sv = ctx.get_arg(3); + padding = get_and_validate_rsa_encryption_padding_by_label(padding_sv); + } opensslpp::rsa_key key; try { - key = opensslpp::rsa_key::import_private_pem(key_pem); + key = opensslpp::rsa_key::import_private_pem(key_pem_sv); } catch (const opensslpp::core_error &) { - key = opensslpp::rsa_key::import_public_pem(key_pem); + key = opensslpp::rsa_key::import_public_pem(key_pem_sv); } - return {key.is_private() ? opensslpp::decrypt_with_rsa_private_key( - message, key, opensslpp::rsa_padding::pkcs1) - : opensslpp::decrypt_with_rsa_public_key( - message, key, opensslpp::rsa_padding::pkcs1)}; + return { + key.is_private() + ? opensslpp::decrypt_with_rsa_private_key(message_sv, key, padding) + : opensslpp::decrypt_with_rsa_public_key(message_sv, key, padding)}; } // CREATE_DIGEST(@digest_type, @str) @@ -418,17 +474,23 @@ class create_digest_impl { if (ctx.get_number_of_args() != 2) throw std::invalid_argument("Function requires exactly two arguments"); + mysqlpp::udf_context_charset_extension charset_ext{ + mysql_service_mysql_udf_metadata}; + // result ctx.mark_result_const(false); ctx.mark_result_nullable(true); + charset_ext.set_return_value_charset(ctx, binary_charset_name); // arg0 - @digest_type ctx.mark_arg_nullable(0, false); ctx.set_arg_type(0, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 0, ascii_charset_name); // arg1 - @str ctx.mark_arg_nullable(1, false); ctx.set_arg_type(1, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 1, binary_charset_name); } mysqlpp::udf_result_t calculate( @@ -441,9 +503,8 @@ mysqlpp::udf_result_t create_digest_impl::calculate( auto digest_type = static_cast(digest_type_sv); auto message_sv = ctx.get_arg(1); - auto message = static_cast(message_sv); - return {opensslpp::calculate_digest(digest_type, message)}; + return {opensslpp::calculate_digest(digest_type, message_sv)}; } // ASYMMETRIC_SIGN(@algorithm, @digest_str, @priv_key_str, @digest_type) @@ -462,28 +523,43 @@ mysqlpp::udf_result_t create_digest_impl::calculate( class asymmetric_sign_impl { public: asymmetric_sign_impl(mysqlpp::udf_context &ctx) { - if (ctx.get_number_of_args() != 4) - throw std::invalid_argument("Function requires exactly four arguments"); + if (ctx.get_number_of_args() < 4 || ctx.get_number_of_args() > 5) + throw std::invalid_argument("Function requires four or five arguments"); + + mysqlpp::udf_context_charset_extension charset_ext{ + mysql_service_mysql_udf_metadata}; // result ctx.mark_result_const(false); ctx.mark_result_nullable(true); + charset_ext.set_return_value_charset(ctx, binary_charset_name); // arg0 - @algorithm ctx.mark_arg_nullable(0, false); ctx.set_arg_type(0, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 0, ascii_charset_name); // arg1 - @digest_str ctx.mark_arg_nullable(1, false); ctx.set_arg_type(1, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 1, binary_charset_name); // arg2 - @priv_key_str ctx.mark_arg_nullable(2, false); ctx.set_arg_type(2, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 2, ascii_charset_name); // arg3 - @digest_type ctx.mark_arg_nullable(3, false); ctx.set_arg_type(3, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 3, ascii_charset_name); + + // optional arg4 - @padding + if (ctx.get_number_of_args() == 5) { + ctx.mark_arg_nullable(4, false); + ctx.set_arg_type(4, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 4, ascii_charset_name); + } } mysqlpp::udf_result_t calculate( @@ -492,30 +568,42 @@ class asymmetric_sign_impl { mysqlpp::udf_result_t asymmetric_sign_impl::calculate( const mysqlpp::udf_context &ctx) { - auto algorithm = ctx.get_arg(0); - auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm); - if (algorithm_id != algorithm_id_type::rsa && - algorithm_id != algorithm_id_type::dsa) + auto algorithm_sv = ctx.get_arg(0); + auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm_sv); + if (algorithm_id != opensslpp::evp_pkey_algorithm::rsa && + algorithm_id != opensslpp::evp_pkey_algorithm::dsa) throw std::invalid_argument("Invalid algorithm specified"); - auto message_digest_sv = ctx.get_arg(1); - auto message_digest = static_cast(message_digest_sv); + opensslpp::evp_pkey_signature_padding signature_padding{ + check_if_legacy_padding_scheme() + ? opensslpp::evp_pkey_signature_padding::rsa_pkcs1 + : opensslpp::evp_pkey_signature_padding::rsa_pkcs1_pss}; + if (ctx.get_number_of_args() == 5) { + if (algorithm_id != opensslpp::evp_pkey_algorithm::rsa) + throw std::invalid_argument( + "Signature padding scheme can only be specified for the RSA " + "algorithm"); + auto signature_padding_sv = ctx.get_arg(4); + signature_padding = get_and_validate_evp_pkey_signature_padding_by_label( + signature_padding_sv); + } + auto message_digest_sv = ctx.get_arg(1); auto private_key_pem_sv = ctx.get_arg(2); - auto private_key_pem = static_cast(private_key_pem_sv); - auto digest_type_sv = ctx.get_arg(3); auto digest_type = static_cast(digest_type_sv); std::string signature; - if (algorithm_id == algorithm_id_type::rsa) { - auto private_key = opensslpp::rsa_key::import_private_pem(private_key_pem); - signature = opensslpp::sign_with_rsa_private_key( - digest_type, message_digest, private_key); - } else if (algorithm_id == algorithm_id_type::dsa) { - auto private_key = opensslpp::dsa_key::import_private_pem(private_key_pem); + if (algorithm_id == opensslpp::evp_pkey_algorithm::rsa) { + auto private_key = + opensslpp::evp_pkey::import_private_pem(private_key_pem_sv); + signature = opensslpp::sign_with_private_evp_pkey( + digest_type, message_digest_sv, private_key, signature_padding); + } else if (algorithm_id == opensslpp::evp_pkey_algorithm::dsa) { + auto private_key = + opensslpp::dsa_key::import_private_pem(private_key_pem_sv); signature = opensslpp::sign_with_dsa_private_key( - digest_type, message_digest, private_key); + digest_type, message_digest_sv, private_key); } return {std::move(signature)}; } @@ -539,32 +627,48 @@ mysqlpp::udf_result_t asymmetric_sign_impl::calculate( class asymmetric_verify_impl { public: asymmetric_verify_impl(mysqlpp::udf_context &ctx) { - if (ctx.get_number_of_args() != 5) - throw std::invalid_argument("Function requires exactly five arguments"); + if (ctx.get_number_of_args() < 5 || ctx.get_number_of_args() > 6) + throw std::invalid_argument("Function requires five or six arguments"); + + mysqlpp::udf_context_charset_extension charset_ext{ + mysql_service_mysql_udf_metadata}; // result ctx.mark_result_const(false); ctx.mark_result_nullable(true); + // return value charset is not set here as its type is INT_RESULT // arg0 - @algorithm ctx.mark_arg_nullable(0, false); ctx.set_arg_type(0, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 0, ascii_charset_name); // arg1 - @digest_str ctx.mark_arg_nullable(1, false); ctx.set_arg_type(1, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 1, binary_charset_name); // arg2 - @sig_str ctx.mark_arg_nullable(2, false); ctx.set_arg_type(2, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 2, binary_charset_name); // arg3 - @pub_key_str ctx.mark_arg_nullable(3, false); ctx.set_arg_type(3, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 3, ascii_charset_name); // arg4 - @digest_type ctx.mark_arg_nullable(4, false); ctx.set_arg_type(4, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 4, ascii_charset_name); + + // optional arg5 - @padding + if (ctx.get_number_of_args() == 6) { + ctx.mark_arg_nullable(5, false); + ctx.set_arg_type(5, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 5, ascii_charset_name); + } } mysqlpp::udf_result_t calculate(const mysqlpp::udf_context &ctx); @@ -572,33 +676,42 @@ class asymmetric_verify_impl { mysqlpp::udf_result_t asymmetric_verify_impl::calculate( const mysqlpp::udf_context &ctx) { - auto algorithm = ctx.get_arg(0); - auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm); - if (algorithm_id != algorithm_id_type::rsa && - algorithm_id != algorithm_id_type::dsa) + auto algorithm_sv = ctx.get_arg(0); + auto algorithm_id = get_and_validate_algorithm_id_by_label(algorithm_sv); + if (algorithm_id != opensslpp::evp_pkey_algorithm::rsa && + algorithm_id != opensslpp::evp_pkey_algorithm::dsa) throw std::invalid_argument("Invalid algorithm specified"); - auto message_digest_sv = ctx.get_arg(1); - auto message_digest = static_cast(message_digest_sv); + opensslpp::evp_pkey_signature_padding signature_padding{ + check_if_legacy_padding_scheme() + ? opensslpp::evp_pkey_signature_padding::rsa_pkcs1 + : opensslpp::evp_pkey_signature_padding::rsa_pkcs1_pss}; + if (ctx.get_number_of_args() == 6) { + if (algorithm_id != opensslpp::evp_pkey_algorithm::rsa) + throw std::invalid_argument( + "Signature padding scheme can only be specified for the RSA " + "algorithm"); + auto signature_padding_sv = ctx.get_arg(5); + signature_padding = get_and_validate_evp_pkey_signature_padding_by_label( + signature_padding_sv); + } + auto message_digest_sv = ctx.get_arg(1); auto signature_sv = ctx.get_arg(2); - auto signature = static_cast(signature_sv); - auto public_key_pem_sv = ctx.get_arg(3); - auto public_key_pem = static_cast(public_key_pem_sv); - auto digest_type_sv = ctx.get_arg(4); auto digest_type = static_cast(digest_type_sv); bool verification_result = false; - if (algorithm_id == algorithm_id_type::rsa) { - auto public_key = opensslpp::rsa_key::import_public_pem(public_key_pem); - verification_result = opensslpp::verify_with_rsa_public_key( - digest_type, message_digest, signature, public_key); - } else if (algorithm_id == algorithm_id_type::dsa) { - auto public_key = opensslpp::dsa_key::import_public_pem(public_key_pem); + if (algorithm_id == opensslpp::evp_pkey_algorithm::rsa) { + auto public_key = opensslpp::evp_pkey::import_public_pem(public_key_pem_sv); + verification_result = opensslpp::verify_with_public_evp_pkey( + digest_type, message_digest_sv, signature_sv, public_key, + signature_padding); + } else if (algorithm_id == opensslpp::evp_pkey_algorithm::dsa) { + auto public_key = opensslpp::dsa_key::import_public_pem(public_key_pem_sv); verification_result = opensslpp::verify_with_dsa_public_key( - digest_type, message_digest, signature, public_key); + digest_type, message_digest_sv, signature_sv, public_key); } return {verification_result ? 1LL : 0LL}; } @@ -615,13 +728,18 @@ class create_dh_parameters_impl { if (ctx.get_number_of_args() != 1) throw std::invalid_argument("Function requires exactly one argument"); + mysqlpp::udf_context_charset_extension charset_ext{ + mysql_service_mysql_udf_metadata}; + // result ctx.mark_result_const(false); ctx.mark_result_nullable(true); + charset_ext.set_return_value_charset(ctx, ascii_charset_name); // arg0 - @key_len ctx.mark_arg_nullable(0, false); ctx.set_arg_type(0, INT_RESULT); + // argument charset is not set here as its type is INT_RESULT } mysqlpp::udf_result_t calculate( @@ -663,17 +781,23 @@ class asymmetric_derive_impl { if (ctx.get_number_of_args() != 2) throw std::invalid_argument("Function requires exactly two arguments"); + mysqlpp::udf_context_charset_extension charset_ext{ + mysql_service_mysql_udf_metadata}; + // result ctx.mark_result_const(false); ctx.mark_result_nullable(true); + charset_ext.set_return_value_charset(ctx, binary_charset_name); // arg0 - @pub_key_str ctx.mark_arg_nullable(0, false); ctx.set_arg_type(0, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 0, ascii_charset_name); // arg1 - @priv_key_str ctx.mark_arg_nullable(1, false); ctx.set_arg_type(1, STRING_RESULT); + charset_ext.set_arg_value_charset(ctx, 1, ascii_charset_name); } mysqlpp::udf_result_t calculate( @@ -683,12 +807,10 @@ class asymmetric_derive_impl { mysqlpp::udf_result_t asymmetric_derive_impl::calculate( const mysqlpp::udf_context &ctx) { auto public_key_pem_sv = ctx.get_arg(0); - auto public_key_pem = static_cast(public_key_pem_sv); - auto public_key = opensslpp::dh_key::import_public_pem(public_key_pem); + auto public_key = opensslpp::dh_key::import_public_pem(public_key_pem_sv); auto private_key_pem_sv = ctx.get_arg(1); - auto private_key_pem = static_cast(private_key_pem_sv); - auto private_key = opensslpp::dh_key::import_private_pem(private_key_pem); + auto private_key = opensslpp::dh_key::import_private_pem(private_key_pem_sv); return {opensslpp::compute_dh_key(public_key, private_key, opensslpp::dh_padding::nist_sp800_56a)}; @@ -732,6 +854,7 @@ static udf_bitset_type registered_udfs; using threshold_bitset_type = std::bitset; static threshold_bitset_type registered_thresholds; +static bool legacy_padding_scheme_variable_registered{false}; static mysql_service_status_t component_init() { // here, we use a custom error reporting function 'encryption_udf_my_error()' @@ -751,17 +874,29 @@ static mysql_service_status_t component_init() { if (mysql_service_component_sys_variable_register->register_variable( CURRENT_COMPONENT_NAME_STR, threshold.var_name, PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_RQCMDARG, - threshold.var_description, nullptr, nullptr, - static_cast(&arg), - static_cast(&bits_threshold_values[index])) == 0) + threshold.var_description, nullptr, nullptr, &arg, + &bits_threshold_values[index]) == 0) registered_thresholds.set(index); } ++index; } + if (!legacy_padding_scheme_variable_registered) { + BOOL_CHECK_ARG(bool) arg; + arg.def_val = false; + if (mysql_service_component_sys_variable_register->register_variable( + CURRENT_COMPONENT_NAME_STR, legacy_padding_scheme_variable_name, + PLUGIN_VAR_BOOL, legacy_padding_scheme_variable_description, + nullptr, nullptr, &arg, &legacy_padding_scheme_value) == 0) { + legacy_padding_scheme_variable_registered = true; + } + } mysqlpp::register_udfs(mysql_service_udf_registration, known_udfs, registered_udfs); - return registered_udfs.all() && registered_thresholds.all() ? 0 : 1; + return registered_udfs.all() && registered_thresholds.all() && + legacy_padding_scheme_variable_registered + ? 0 + : 1; } static mysql_service_status_t component_deinit() { @@ -772,13 +907,24 @@ static mysql_service_status_t component_deinit() { for (const auto &threshold : thresholds) { if (registered_thresholds.test(index)) { if (mysql_service_component_sys_variable_unregister->unregister_variable( - CURRENT_COMPONENT_NAME_STR, threshold.var_name) == 0) + CURRENT_COMPONENT_NAME_STR, threshold.var_name) == 0) { registered_thresholds.reset(index); + } } ++index; } + if (legacy_padding_scheme_variable_registered) { + if (mysql_service_component_sys_variable_unregister->unregister_variable( + CURRENT_COMPONENT_NAME_STR, legacy_padding_scheme_variable_name) == + 0) { + legacy_padding_scheme_variable_registered = false; + } + } - return registered_udfs.none() && registered_thresholds.none() ? 0 : 1; + return registered_udfs.none() && registered_thresholds.none() && + !legacy_padding_scheme_variable_registered + ? 0 + : 1; } // clang-format off @@ -788,6 +934,7 @@ END_COMPONENT_PROVIDES(); BEGIN_COMPONENT_REQUIRES(CURRENT_COMPONENT_NAME) REQUIRES_SERVICE(mysql_runtime_error), REQUIRES_SERVICE(udf_registration), + REQUIRES_SERVICE(mysql_udf_metadata), REQUIRES_SERVICE(component_sys_variable_register), REQUIRES_SERVICE(component_sys_variable_unregister), REQUIRES_SERVICE(mysql_current_thread_reader), diff --git a/extra/opensslpp/CMakeLists.txt b/extra/opensslpp/CMakeLists.txt index 5fccc82e29c9..a3cc614d578e 100644 --- a/extra/opensslpp/CMakeLists.txt +++ b/extra/opensslpp/CMakeLists.txt @@ -66,14 +66,21 @@ set( dsa_key.hpp dsa_key_fwd.hpp dsa_sign_verify_operations.hpp + evp_pkey.hpp + evp_pkey_fwd.hpp + evp_pkey_sign_verify_operations.hpp + evp_pkey_algorithm.hpp + evp_pkey_algorithm_fwd.hpp + evp_pkey_signature_padding.hpp + evp_pkey_signature_padding_fwd.hpp key_generation_cancellation_callback_fwd.hpp operation_cancelled_error.hpp operation_cancelled_error_fwd.hpp rsa_encrypt_decrypt_operations.hpp rsa_key.hpp rsa_key_fwd.hpp - rsa_padding.hpp - rsa_padding_fwd.hpp + rsa_encryption_padding.hpp + rsa_encryption_padding_fwd.hpp rsa_sign_verify_operations.hpp ) list_transform_prepend(PUBLIC_HEADER_LIST "${PUBLIC_INCLUDE_DIR_EX}/") @@ -87,11 +94,14 @@ set( dh_key_accessor.hpp digest_context_accessor.hpp dsa_key_accessor.hpp + evp_pkey_accessor.hpp + evp_pkey_algorithm_conversions.hpp + evp_pkey_signature_padding_conversions.hpp key_generation_cancellation_context.hpp key_generation_cancellation_context_accessor.hpp key_generation_cancellation_context_fwd.hpp rsa_key_accessor.hpp - rsa_padding_conversions.hpp + rsa_encryption_padding_conversions.hpp typed_accessor.hpp ) list_transform_prepend(PRIVATE_HEADER_LIST "${PRIVATE_INCLUDE_DIR_EX}/") @@ -106,6 +116,8 @@ set( digest_operations.cpp dsa_key.cpp dsa_sign_verify_operations.cpp + evp_pkey.cpp + evp_pkey_sign_verify_operations.cpp key_generation_cancellation_context.cpp rsa_encrypt_decrypt_operations.cpp rsa_key.cpp @@ -127,7 +139,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE OPENSSL_SUPPRESS_DEPRECATED) set_target_properties( ${PROJECT_NAME} PROPERTIES - CXX_STANDARD 14 + CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO VERSION ${${PROJECT_NAME}_VERSION} diff --git a/extra/opensslpp/include/opensslpp/core_error.hpp b/extra/opensslpp/include/opensslpp/core_error.hpp index 1f43db4e4e4e..80feb09a5e2c 100644 --- a/extra/opensslpp/include/opensslpp/core_error.hpp +++ b/extra/opensslpp/include/opensslpp/core_error.hpp @@ -19,6 +19,7 @@ #include #include +#include #include @@ -30,7 +31,7 @@ class core_error : public std::runtime_error { core_error(const std::string &message) : std::runtime_error{message} {} [[noreturn]] static void raise_with_error_string( - const std::string &prefix = std::string()); + std::string_view prefix = ""); }; } // namespace opensslpp diff --git a/extra/opensslpp/include/opensslpp/dh_key.hpp b/extra/opensslpp/include/opensslpp/dh_key.hpp index fef0d628535b..2f4c1f635a1b 100644 --- a/extra/opensslpp/include/opensslpp/dh_key.hpp +++ b/extra/opensslpp/include/opensslpp/dh_key.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -73,9 +74,9 @@ class dh_key final { static std::string export_private_pem(const dh_key &key); static std::string export_public_pem(const dh_key &key); - static dh_key import_parameters_pem(const std::string &pem); - static dh_key import_private_pem(const std::string &pem); - static dh_key import_public_pem(const std::string &pem); + static dh_key import_parameters_pem(std::string_view pem); + static dh_key import_private_pem(std::string_view pem); + static dh_key import_public_pem(std::string_view pem); private: // should not be declared final as this prevents optimization for empty diff --git a/extra/opensslpp/include/opensslpp/digest_context.hpp b/extra/opensslpp/include/opensslpp/digest_context.hpp index d0f75f459f4c..62d2196cb1b4 100644 --- a/extra/opensslpp/include/opensslpp/digest_context.hpp +++ b/extra/opensslpp/include/opensslpp/digest_context.hpp @@ -19,6 +19,7 @@ #include #include +#include #include @@ -31,6 +32,7 @@ class digest_context final { public: digest_context() noexcept = default; + // no std::string_view for 'type' as we need it to be nul-terminated explicit digest_context(const std::string &type); ~digest_context() noexcept = default; @@ -46,7 +48,7 @@ class digest_context final { std::size_t get_size_in_bytes() const noexcept; - void update(const std::string &data); + void update(std::string_view data); std::string finalize(); private: diff --git a/extra/opensslpp/include/opensslpp/digest_operations.hpp b/extra/opensslpp/include/opensslpp/digest_operations.hpp index 9069e29fd1de..bfc917cdea49 100644 --- a/extra/opensslpp/include/opensslpp/digest_operations.hpp +++ b/extra/opensslpp/include/opensslpp/digest_operations.hpp @@ -18,10 +18,12 @@ #define OPENSSLPP_DIGEST_OPERATIONS_HPP #include +#include namespace opensslpp { -std::string calculate_digest(const std::string &type, const std::string &data); +// no std::string_view for 'type' as we need it to be nul-terminated +std::string calculate_digest(const std::string &type, std::string_view data); } // namespace opensslpp diff --git a/extra/opensslpp/include/opensslpp/dsa_key.hpp b/extra/opensslpp/include/opensslpp/dsa_key.hpp index 44a8ba9593c5..27dca2103a4d 100644 --- a/extra/opensslpp/include/opensslpp/dsa_key.hpp +++ b/extra/opensslpp/include/opensslpp/dsa_key.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -68,9 +69,9 @@ class dsa_key final { static std::string export_private_pem(const dsa_key &key); static std::string export_public_pem(const dsa_key &key); - static dsa_key import_parameters_pem(const std::string &pem); - static dsa_key import_private_pem(const std::string &pem); - static dsa_key import_public_pem(const std::string &pem); + static dsa_key import_parameters_pem(std::string_view pem); + static dsa_key import_private_pem(std::string_view pem); + static dsa_key import_public_pem(std::string_view pem); private: // should not be declared final as this prevents optimization for empty diff --git a/extra/opensslpp/include/opensslpp/dsa_sign_verify_operations.hpp b/extra/opensslpp/include/opensslpp/dsa_sign_verify_operations.hpp index 0a3271c53ea7..81f8b6b8ace9 100644 --- a/extra/opensslpp/include/opensslpp/dsa_sign_verify_operations.hpp +++ b/extra/opensslpp/include/opensslpp/dsa_sign_verify_operations.hpp @@ -18,18 +18,21 @@ #define OPENSSLPP_DSA_SIGN_VERIFY_OPERATIONS_HPP #include +#include #include namespace opensslpp { +// no std::string_view for 'digest_type' as we need it to be nul-terminated std::string sign_with_dsa_private_key(const std::string &digest_type, - const std::string &digest_data, + std::string_view digest_data, const dsa_key &key); +// no std::string_view for 'digest_type' as we need it to be nul-terminated bool verify_with_dsa_public_key(const std::string &digest_type, - const std::string &digest_data, - const std::string &signature_data, + std::string_view digest_data, + std::string_view signature_data, const dsa_key &key); } // namespace opensslpp diff --git a/extra/opensslpp/include/opensslpp/evp_pkey.hpp b/extra/opensslpp/include/opensslpp/evp_pkey.hpp new file mode 100644 index 000000000000..5881d1e270c3 --- /dev/null +++ b/extra/opensslpp/include/opensslpp/evp_pkey.hpp @@ -0,0 +1,85 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef OPENSSLPP_EVP_PKEY_HPP +#define OPENSSLPP_EVP_PKEY_HPP + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +namespace opensslpp { + +class evp_pkey final { + friend class accessor; + + public: + evp_pkey() noexcept = default; + ~evp_pkey() noexcept = default; + + evp_pkey(const evp_pkey &obj); + evp_pkey(evp_pkey &&obj) noexcept = default; + + evp_pkey &operator=(const evp_pkey &obj); + evp_pkey &operator=(evp_pkey &&obj) noexcept = default; + + void swap(evp_pkey &obj) noexcept; + + bool is_empty() const noexcept { return !impl_; } + evp_pkey_algorithm get_algorithm() const noexcept; + bool is_private() const noexcept; + std::size_t get_size_in_bits() const noexcept; + std::size_t get_size_in_bytes() const noexcept; + + evp_pkey derive_public_key() const; + + static evp_pkey generate( + evp_pkey_algorithm algorithm, std::uint32_t bits, + const key_generation_cancellation_callback &cancellation_callback = + key_generation_cancellation_callback{}); + + static std::string export_private_pem(const evp_pkey &key); + static std::string export_public_pem(const evp_pkey &key); + + static evp_pkey import_private_pem(std::string_view pem); + static evp_pkey import_public_pem(std::string_view pem); + + private: + // should not be declared final as this prevents optimization for empty + // deleter in std::unique_ptr + struct evp_pkey_deleter { + void operator()(void *evp_pkey) const noexcept; + }; + + using impl_ptr = std::unique_ptr; + impl_ptr impl_; + + static void validate_if_algorithm_supported(evp_pkey_algorithm algorithm); +}; + +std::ostream &operator<<(std::ostream &os, const evp_pkey &obj); + +} // namespace opensslpp + +#endif diff --git a/extra/opensslpp/include/opensslpp/rsa_padding.hpp b/extra/opensslpp/include/opensslpp/evp_pkey_algorithm.hpp similarity index 84% rename from extra/opensslpp/include/opensslpp/rsa_padding.hpp rename to extra/opensslpp/include/opensslpp/evp_pkey_algorithm.hpp index c0b0bc4b96da..8a78e71c74cc 100644 --- a/extra/opensslpp/include/opensslpp/rsa_padding.hpp +++ b/extra/opensslpp/include/opensslpp/evp_pkey_algorithm.hpp @@ -14,14 +14,12 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef OPENSSLPP_RSA_PADDING_HPP -#define OPENSSLPP_RSA_PADDING_HPP - -#include +#ifndef OPENSSLPP_EVP_PKEY_ALGORITHM_HPP +#define OPENSSLPP_EVP_PKEY_ALGORITHM_HPP namespace opensslpp { -enum class rsa_padding { no, pkcs1 }; +enum class evp_pkey_algorithm { unspecified, rsa, dsa, dh }; } // namespace opensslpp diff --git a/extra/opensslpp/include/opensslpp/evp_pkey_algorithm_fwd.hpp b/extra/opensslpp/include/opensslpp/evp_pkey_algorithm_fwd.hpp new file mode 100644 index 000000000000..df2e9f1a49ec --- /dev/null +++ b/extra/opensslpp/include/opensslpp/evp_pkey_algorithm_fwd.hpp @@ -0,0 +1,26 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef OPENSSLPP_EVP_PKEY_ALGORITHM_FWD_HPP +#define OPENSSLPP_EVP_PKEY_ALGORITHM_FWD_HPP + +namespace opensslpp { + +enum class evp_pkey_algorithm; + +} // namespace opensslpp + +#endif diff --git a/extra/opensslpp/include/opensslpp/rsa_padding_fwd.hpp b/extra/opensslpp/include/opensslpp/evp_pkey_fwd.hpp similarity index 88% rename from extra/opensslpp/include/opensslpp/rsa_padding_fwd.hpp rename to extra/opensslpp/include/opensslpp/evp_pkey_fwd.hpp index fefbd5f8db42..d640b00d93ba 100644 --- a/extra/opensslpp/include/opensslpp/rsa_padding_fwd.hpp +++ b/extra/opensslpp/include/opensslpp/evp_pkey_fwd.hpp @@ -14,12 +14,12 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef OPENSSLPP_RSA_PADDING_FWD_HPP -#define OPENSSLPP_RSA_PADDING_FWD_HPP +#ifndef OPENSSLPP_EVP_PKEY_FWD_HPP +#define OPENSSLPP_EVP_PKEY_FWD_HPP namespace opensslpp { -enum class rsa_padding; +class evp_pkey; } // namespace opensslpp diff --git a/extra/opensslpp/include/opensslpp/evp_pkey_sign_verify_operations.hpp b/extra/opensslpp/include/opensslpp/evp_pkey_sign_verify_operations.hpp new file mode 100644 index 000000000000..6de88abf56bd --- /dev/null +++ b/extra/opensslpp/include/opensslpp/evp_pkey_sign_verify_operations.hpp @@ -0,0 +1,43 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef OPENSSLPP_EVP_PKEY_SIGN_VERIFY_OPERATIONS_HPP +#define OPENSSLPP_EVP_PKEY_SIGN_VERIFY_OPERATIONS_HPP + +#include +#include + +#include +#include + +namespace opensslpp { + +// no std::string_view for 'digest_type' as we need it to be nul-terminated +std::string sign_with_private_evp_pkey(const std::string &digest_type, + std::string_view digest_data, + const evp_pkey &key, + evp_pkey_signature_padding padding); + +// no std::string_view for 'digest_type' as we need it to be nul-terminated +bool verify_with_public_evp_pkey(const std::string &digest_type, + std::string_view digest_data, + std::string_view signature_data, + const evp_pkey &key, + evp_pkey_signature_padding padding); + +} // namespace opensslpp + +#endif diff --git a/extra/opensslpp/include/opensslpp/evp_pkey_signature_padding.hpp b/extra/opensslpp/include/opensslpp/evp_pkey_signature_padding.hpp new file mode 100644 index 000000000000..b380086b0be9 --- /dev/null +++ b/extra/opensslpp/include/opensslpp/evp_pkey_signature_padding.hpp @@ -0,0 +1,26 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef OPENSSLPP_EVP_PKEY_SIGNATURE_PADDING_HPP +#define OPENSSLPP_EVP_PKEY_SIGNATURE_PADDING_HPP + +namespace opensslpp { + +enum class evp_pkey_signature_padding { rsa_pkcs1, rsa_pkcs1_pss }; + +} // namespace opensslpp + +#endif diff --git a/extra/opensslpp/include/opensslpp/evp_pkey_signature_padding_fwd.hpp b/extra/opensslpp/include/opensslpp/evp_pkey_signature_padding_fwd.hpp new file mode 100644 index 000000000000..a9861f1edc99 --- /dev/null +++ b/extra/opensslpp/include/opensslpp/evp_pkey_signature_padding_fwd.hpp @@ -0,0 +1,26 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef OPENSSLPP_EVP_PKEY_SIGNATURE_PADDING_FWD_HPP +#define OPENSSLPP_EVP_PKEY_SIGNATURE_PADDING_FWD_HPP + +namespace opensslpp { + +enum class evp_pkey_signature_padding; + +} // namespace opensslpp + +#endif diff --git a/extra/opensslpp/include/opensslpp/rsa_encrypt_decrypt_operations.hpp b/extra/opensslpp/include/opensslpp/rsa_encrypt_decrypt_operations.hpp index 168d4cfd4c40..888bb2eb44b6 100644 --- a/extra/opensslpp/include/opensslpp/rsa_encrypt_decrypt_operations.hpp +++ b/extra/opensslpp/include/opensslpp/rsa_encrypt_decrypt_operations.hpp @@ -18,25 +18,26 @@ #define OPENSSLPP_RSA_ENCRYPT_DECRYPT_OPERATIONS_HPP #include +#include #include -#include +#include namespace opensslpp { -std::string encrypt_with_rsa_public_key(const std::string &input, +std::string encrypt_with_rsa_public_key(std::string_view input, const rsa_key &key, - rsa_padding padding); -std::string encrypt_with_rsa_private_key(const std::string &input, + rsa_encryption_padding padding); +std::string encrypt_with_rsa_private_key(std::string_view input, const rsa_key &key, - rsa_padding padding); -std::string decrypt_with_rsa_public_key(const std::string &input, + rsa_encryption_padding padding); +std::string decrypt_with_rsa_public_key(std::string_view input, const rsa_key &key, - rsa_padding padding); -std::string decrypt_with_rsa_private_key(const std::string &input, + rsa_encryption_padding padding); +std::string decrypt_with_rsa_private_key(std::string_view input, const rsa_key &key, - rsa_padding padding); + rsa_encryption_padding padding); } // namespace opensslpp diff --git a/extra/opensslpp/include/opensslpp/rsa_encryption_padding.hpp b/extra/opensslpp/include/opensslpp/rsa_encryption_padding.hpp new file mode 100644 index 000000000000..c575d24b38a2 --- /dev/null +++ b/extra/opensslpp/include/opensslpp/rsa_encryption_padding.hpp @@ -0,0 +1,28 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef OPENSSLPP_RSA_ENCRYPTION_PADDING_HPP +#define OPENSSLPP_RSA_ENCRYPTION_PADDING_HPP + +#include + +namespace opensslpp { + +enum class rsa_encryption_padding { no, pkcs1, pkcs1_oaep }; + +} // namespace opensslpp + +#endif diff --git a/extra/opensslpp/include/opensslpp/rsa_encryption_padding_fwd.hpp b/extra/opensslpp/include/opensslpp/rsa_encryption_padding_fwd.hpp new file mode 100644 index 000000000000..3857f3ab9705 --- /dev/null +++ b/extra/opensslpp/include/opensslpp/rsa_encryption_padding_fwd.hpp @@ -0,0 +1,26 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef OPENSSLPP_RSA_ENCRYPTION_PADDING_FWD_HPP +#define OPENSSLPP_RSA_ENCRYPTION_PADDING_FWD_HPP + +namespace opensslpp { + +enum class rsa_encryption_padding; + +} // namespace opensslpp + +#endif diff --git a/extra/opensslpp/include/opensslpp/rsa_key.hpp b/extra/opensslpp/include/opensslpp/rsa_key.hpp index d7cadba47ec9..2ab93b35f44d 100644 --- a/extra/opensslpp/include/opensslpp/rsa_key.hpp +++ b/extra/opensslpp/include/opensslpp/rsa_key.hpp @@ -21,13 +21,14 @@ #include #include #include +#include #include #include #include #include -#include +#include namespace opensslpp { @@ -56,7 +57,8 @@ class rsa_key final { std::size_t get_size_in_bits() const noexcept; std::size_t get_size_in_bytes() const noexcept; - std::size_t get_max_block_size_in_bytes(rsa_padding padding) const noexcept; + std::size_t get_max_block_size_in_bytes( + rsa_encryption_padding padding) const noexcept; rsa_key derive_public_key() const; @@ -68,8 +70,8 @@ class rsa_key final { static std::string export_private_pem(const rsa_key &key); static std::string export_public_pem(const rsa_key &key); - static rsa_key import_private_pem(const std::string &pem); - static rsa_key import_public_pem(const std::string &pem); + static rsa_key import_private_pem(std::string_view pem); + static rsa_key import_public_pem(std::string_view pem); private: // should not be declared final as this prevents optimization for empty diff --git a/extra/opensslpp/include/opensslpp/rsa_sign_verify_operations.hpp b/extra/opensslpp/include/opensslpp/rsa_sign_verify_operations.hpp index 32ebd86c7ff1..f9e9eb3e3e9f 100644 --- a/extra/opensslpp/include/opensslpp/rsa_sign_verify_operations.hpp +++ b/extra/opensslpp/include/opensslpp/rsa_sign_verify_operations.hpp @@ -18,18 +18,21 @@ #define OPENSSLPP_RSA_SIGN_VERIFY_OPERATIONS_HPP #include +#include #include namespace opensslpp { +// no std::string_view for 'digest_type' as we need it to be nul-terminated std::string sign_with_rsa_private_key(const std::string &digest_type, - const std::string &digest_data, + std::string_view digest_data, const rsa_key &key); +// no std::string_view for 'digest_type' as we need it to be nul-terminated bool verify_with_rsa_public_key(const std::string &digest_type, - const std::string &digest_data, - const std::string &signature_data, + std::string_view digest_data, + std::string_view signature_data, const rsa_key &key); } // namespace opensslpp diff --git a/extra/opensslpp/include_private/opensslpp/bio.hpp b/extra/opensslpp/include_private/opensslpp/bio.hpp index 6d25df9e3173..ceee12538691 100644 --- a/extra/opensslpp/include_private/opensslpp/bio.hpp +++ b/extra/opensslpp/include_private/opensslpp/bio.hpp @@ -18,7 +18,7 @@ #define OPENSSLPP_BIO_HPP #include -#include +#include #include "opensslpp/bio_fwd.hpp" @@ -31,7 +31,7 @@ class bio final { public: bio(); - bio(const std::string &buffer); + explicit bio(std::string_view buffer); ~bio() noexcept = default; @@ -41,7 +41,7 @@ class bio final { bio &operator=(const bio &obj) = delete; bio &operator=(bio &&obj) noexcept = default; - std::string str() const; + std::string_view sv() const; private: // should not be declared final as this prevents optimization for empty diff --git a/extra/opensslpp/include_private/opensslpp/evp_pkey_accessor.hpp b/extra/opensslpp/include_private/opensslpp/evp_pkey_accessor.hpp new file mode 100644 index 000000000000..3fc16a377b7f --- /dev/null +++ b/extra/opensslpp/include_private/opensslpp/evp_pkey_accessor.hpp @@ -0,0 +1,32 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef OPENSSLPP_EVP_PKEY_ACCESSOR_HPP +#define OPENSSLPP_EVP_PKEY_ACCESSOR_HPP + +#include + +#include + +#include "opensslpp/typed_accessor.hpp" + +namespace opensslpp { + +using evp_pkey_accessor = typed_accessor; + +} // namespace opensslpp + +#endif diff --git a/extra/opensslpp/include_private/opensslpp/evp_pkey_algorithm_conversions.hpp b/extra/opensslpp/include_private/opensslpp/evp_pkey_algorithm_conversions.hpp new file mode 100644 index 000000000000..a419e376948a --- /dev/null +++ b/extra/opensslpp/include_private/opensslpp/evp_pkey_algorithm_conversions.hpp @@ -0,0 +1,66 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef OPENSSLPP_EVP_PKEY_ALGORITHM_CONVERSIONS_HPP +#define OPENSSLPP_EVP_PKEY_ALGORITHM_CONVERSIONS_HPP + +#include + +#include + +#include + +namespace opensslpp { + +inline int evp_pkey_algorithm_to_native_algorithm( + evp_pkey_algorithm algorithm) noexcept { + int res = EVP_PKEY_NONE; + switch (algorithm) { + case evp_pkey_algorithm::rsa: + res = EVP_PKEY_RSA; + break; + case evp_pkey_algorithm::dsa: + res = EVP_PKEY_DSA; + break; + case evp_pkey_algorithm::dh: + res = EVP_PKEY_DH; + break; + default: + res = EVP_PKEY_NONE; + } + return res; +} + +inline evp_pkey_algorithm native_algorithm_to_evp_pkey_algorithm( + int native_algorithm) noexcept { + evp_pkey_algorithm res = evp_pkey_algorithm::unspecified; + switch (native_algorithm) { + case EVP_PKEY_RSA: + res = evp_pkey_algorithm::rsa; + break; + case EVP_PKEY_DSA: + res = evp_pkey_algorithm::dsa; + break; + case EVP_PKEY_DH: + res = evp_pkey_algorithm::dh; + break; + } + return res; +} + +} // namespace opensslpp + +#endif diff --git a/extra/opensslpp/include_private/opensslpp/evp_pkey_signature_padding_conversions.hpp b/extra/opensslpp/include_private/opensslpp/evp_pkey_signature_padding_conversions.hpp new file mode 100644 index 000000000000..193b7363d909 --- /dev/null +++ b/extra/opensslpp/include_private/opensslpp/evp_pkey_signature_padding_conversions.hpp @@ -0,0 +1,46 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#ifndef OPENSSLPP_EVP_PKEY_ALGORITHM_CONVERSIONS_HPP +#define OPENSSLPP_EVP_PKEY_ALGORITHM_CONVERSIONS_HPP + +#include + +#include + +#include + +namespace opensslpp { + +inline int evp_pkey_signature_padding_to_native_padding( + evp_pkey_signature_padding padding) noexcept { + int res = RSA_PKCS1_PADDING; + switch (padding) { + case evp_pkey_signature_padding::rsa_pkcs1: + res = RSA_PKCS1_PADDING; + break; + case evp_pkey_signature_padding::rsa_pkcs1_pss: + res = RSA_PKCS1_PSS_PADDING; + break; + default: + res = RSA_PKCS1_PADDING; + } + return res; +} + +} // namespace opensslpp + +#endif diff --git a/extra/opensslpp/include_private/opensslpp/rsa_padding_conversions.hpp b/extra/opensslpp/include_private/opensslpp/rsa_encryption_padding_conversions.hpp similarity index 70% rename from extra/opensslpp/include_private/opensslpp/rsa_padding_conversions.hpp rename to extra/opensslpp/include_private/opensslpp/rsa_encryption_padding_conversions.hpp index 51c8936f3612..40afd1e36692 100644 --- a/extra/opensslpp/include_private/opensslpp/rsa_padding_conversions.hpp +++ b/extra/opensslpp/include_private/opensslpp/rsa_encryption_padding_conversions.hpp @@ -14,26 +14,30 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef OPENSSLPP_RSA_PADDING_CONVERSIONS_HPP -#define OPENSSLPP_RSA_PADDING_CONVERSIONS_HPP +#ifndef OPENSSLPP_RSA_ENCRYPTION_PADDING_CONVERSIONS_HPP +#define OPENSSLPP_RSA_ENCRYPTION_PADDING_CONVERSIONS_HPP #include #include -#include +#include namespace opensslpp { -inline int rsa_padding_to_native_padding(rsa_padding padding) noexcept { +inline int rsa_encryption_padding_to_native_padding( + rsa_encryption_padding padding) noexcept { int res = RSA_NO_PADDING; switch (padding) { - case rsa_padding::no: + case rsa_encryption_padding::no: res = RSA_NO_PADDING; break; - case rsa_padding::pkcs1: + case rsa_encryption_padding::pkcs1: res = RSA_PKCS1_PADDING; break; + case rsa_encryption_padding::pkcs1_oaep: + res = RSA_PKCS1_OAEP_PADDING; + break; default: assert(false); } diff --git a/extra/opensslpp/src/opensslpp/bio.cpp b/extra/opensslpp/src/opensslpp/bio.cpp index a26549a33c88..2c366b1e0f9f 100644 --- a/extra/opensslpp/src/opensslpp/bio.cpp +++ b/extra/opensslpp/src/opensslpp/bio.cpp @@ -33,12 +33,12 @@ bio::bio() : impl_(BIO_new(BIO_s_mem())) { if (!impl_) throw core_error{"cannot create new rw bio"}; } -bio::bio(const std::string &buffer) - : impl_(BIO_new_mem_buf(buffer.c_str(), buffer.size())) { +bio::bio(std::string_view buffer) + : impl_(BIO_new_mem_buf(buffer.data(), buffer.size())) { if (!impl_) throw core_error{"cannot create new ro bio"}; } -std::string bio::str() const { +std::string_view bio::sv() const { char *bio_mem_ptr = nullptr; const long bio_mem_len = BIO_get_mem_data( bio_accessor::get_impl_const_casted(*this), &bio_mem_ptr); diff --git a/extra/opensslpp/src/opensslpp/core_error.cpp b/extra/opensslpp/src/opensslpp/core_error.cpp index 7386c4a0a27b..0c00d3612119 100644 --- a/extra/opensslpp/src/opensslpp/core_error.cpp +++ b/extra/opensslpp/src/opensslpp/core_error.cpp @@ -27,9 +27,10 @@ static constexpr std::size_t error_message_buffer_size = 256; /* static */ [[noreturn]] void core_error::raise_with_error_string( - const std::string &prefix /* = std::string() */) { + std::string_view prefix /* = "" */) { std::string message{prefix}; + // TODO: optimize this to avoid buffer -> string copying using buffer_type = std::array; buffer_type buffer; diff --git a/extra/opensslpp/src/opensslpp/dh_compute_operations.cpp b/extra/opensslpp/src/opensslpp/dh_compute_operations.cpp index 4e66065ba0cf..cce17a0717ae 100644 --- a/extra/opensslpp/src/opensslpp/dh_compute_operations.cpp +++ b/extra/opensslpp/src/opensslpp/dh_compute_operations.cpp @@ -57,18 +57,16 @@ static std::string compute_dh_key_internal(const BIGNUM *public_component, auto function = get_compute_key_function(padding); - // TODO: use c++17 non-const std::string::data() member here - using buffer_type = std::vector; - buffer_type res(private_key.get_size_in_bytes()); - auto compute_status = - (*function)(res.data(), public_component, - dh_key_accessor::get_impl_const_casted(private_key)); + std::string res(private_key.get_size_in_bytes(), '\0'); + auto compute_status = (*function)( + reinterpret_cast(res.data()), public_component, + dh_key_accessor::get_impl_const_casted(private_key)); if (compute_status == -1) core_error::raise_with_error_string( "cannot compute shared key from DH private / public components"); - return {reinterpret_cast(res.data()), res.size()}; + return res; } std::string compute_dh_key(const big_number &public_component, diff --git a/extra/opensslpp/src/opensslpp/dh_key.cpp b/extra/opensslpp/src/opensslpp/dh_key.cpp index faac73c10235..1abe125f6d3c 100644 --- a/extra/opensslpp/src/opensslpp/dh_key.cpp +++ b/extra/opensslpp/src/opensslpp/dh_key.cpp @@ -257,7 +257,7 @@ std::string dh_key::export_parameters_pem(const dh_key &key) { core_error::raise_with_error_string( "cannot export DH key to PEM PARAMETERS"); - return sink.str(); + return std::string{sink.sv()}; } struct evp_pkey_deleter { @@ -282,7 +282,7 @@ std::string dh_key::export_private_pem(const dh_key &key) { core_error::raise_with_error_string( "cannot export DH key to PEM PRIVATE KEY"); - return sink.str(); + return std::string{sink.sv()}; } /*static*/ @@ -298,11 +298,11 @@ std::string dh_key::export_public_pem(const dh_key &key) { core_error::raise_with_error_string( "cannot export DH key to PEM PUBLIC KEY"); - return sink.str(); + return std::string{sink.sv()}; } /*static*/ -dh_key dh_key::import_parameters_pem(const std::string &pem) { +dh_key dh_key::import_parameters_pem(std::string_view pem) { auto source = bio{pem}; dh_key res{}; dh_key_accessor::set_impl( @@ -316,7 +316,7 @@ dh_key dh_key::import_parameters_pem(const std::string &pem) { } /*static*/ -dh_key dh_key::import_private_pem(const std::string &pem) { +dh_key dh_key::import_private_pem(std::string_view pem) { auto source = bio{pem}; evp_pkey_capsule pkey{PEM_read_bio_PrivateKey(bio_accessor::get_impl(source), nullptr, nullptr, nullptr)}; @@ -333,7 +333,7 @@ dh_key dh_key::import_private_pem(const std::string &pem) { } /*static*/ -dh_key dh_key::import_public_pem(const std::string &pem) { +dh_key dh_key::import_public_pem(std::string_view pem) { auto source = bio{pem}; evp_pkey_capsule pkey{PEM_read_bio_PUBKEY(bio_accessor::get_impl(source), nullptr, nullptr, nullptr)}; diff --git a/extra/opensslpp/src/opensslpp/digest_context.cpp b/extra/opensslpp/src/opensslpp/digest_context.cpp index 25b54853a40e..f4d1be218c2c 100644 --- a/extra/opensslpp/src/opensslpp/digest_context.cpp +++ b/extra/opensslpp/src/opensslpp/digest_context.cpp @@ -68,12 +68,14 @@ void digest_context::swap(digest_context &obj) noexcept { } std::size_t digest_context::get_size_in_bytes() const noexcept { + assert(!is_empty()); + return EVP_MD_CTX_size(digest_context_accessor::get_impl(*this)); } -void digest_context::update(const std::string &data) { +void digest_context::update(std::string_view data) { assert(!is_empty()); - if (EVP_DigestUpdate(digest_context_accessor::get_impl(*this), data.c_str(), + if (EVP_DigestUpdate(digest_context_accessor::get_impl(*this), data.data(), data.size()) == 0) throw core_error{"cannot hash data into digest context"}; } @@ -81,19 +83,19 @@ void digest_context::update(const std::string &data) { std::string digest_context::finalize() { assert(!is_empty()); - // TODO: use c++17 non-const std::string::data() member here - using buffer_type = std::array; - buffer_type res; + auto digest_size = EVP_MD_CTX_size(digest_context_accessor::get_impl(*this)); + assert(digest_size > 0 && digest_size <= EVP_MAX_MD_SIZE); + std::string res(static_cast(digest_size), '\0'); unsigned int res_size = 0; - if (EVP_DigestFinal_ex(digest_context_accessor::get_impl(*this), res.data(), + if (EVP_DigestFinal_ex(digest_context_accessor::get_impl(*this), + reinterpret_cast(res.data()), &res_size) == 0) throw core_error{"cannot finalize digest context"}; - assert(res_size <= res.size()); + assert(res_size == res.size()); digest_context_accessor::set_impl(*this, nullptr); - return {reinterpret_cast(res.data()), - static_cast(res_size)}; + return res; } } // namespace opensslpp diff --git a/extra/opensslpp/src/opensslpp/digest_operations.cpp b/extra/opensslpp/src/opensslpp/digest_operations.cpp index b9d423540884..b090e9884144 100644 --- a/extra/opensslpp/src/opensslpp/digest_operations.cpp +++ b/extra/opensslpp/src/opensslpp/digest_operations.cpp @@ -20,7 +20,7 @@ namespace opensslpp { -std::string calculate_digest(const std::string &type, const std::string &data) { +std::string calculate_digest(const std::string &type, std::string_view data) { digest_context ctx(type); ctx.update(data); return ctx.finalize(); diff --git a/extra/opensslpp/src/opensslpp/dsa_key.cpp b/extra/opensslpp/src/opensslpp/dsa_key.cpp index 78a0150af069..7ee57e4b5373 100644 --- a/extra/opensslpp/src/opensslpp/dsa_key.cpp +++ b/extra/opensslpp/src/opensslpp/dsa_key.cpp @@ -249,7 +249,7 @@ std::string dsa_key::export_parameters_pem(const dsa_key &key) { core_error::raise_with_error_string( "cannot export DSA key to PEM PARAMETERS"); - return sink.str(); + return std::string{sink.sv()}; } /*static*/ @@ -268,7 +268,7 @@ std::string dsa_key::export_private_pem(const dsa_key &key) { core_error::raise_with_error_string( "cannot export DSA key to PEM PRIVATE KEY"); - return sink.str(); + return std::string{sink.sv()}; } /*static*/ @@ -286,11 +286,11 @@ std::string dsa_key::export_public_pem(const dsa_key &key) { core_error::raise_with_error_string( "cannot export DSA key to PEM PUBLIC KEY"); - return sink.str(); + return std::string{sink.sv()}; } /*static*/ -dsa_key dsa_key::import_parameters_pem(const std::string &pem) { +dsa_key dsa_key::import_parameters_pem(std::string_view pem) { auto source = bio{pem}; dsa_key res{}; dsa_key_accessor::set_impl( @@ -304,7 +304,7 @@ dsa_key dsa_key::import_parameters_pem(const std::string &pem) { } /*static*/ -dsa_key dsa_key::import_private_pem(const std::string &pem) { +dsa_key dsa_key::import_private_pem(std::string_view pem) { auto source = bio{pem}; dsa_key res{}; dsa_key_accessor::set_impl( @@ -318,7 +318,7 @@ dsa_key dsa_key::import_private_pem(const std::string &pem) { } /*static*/ -dsa_key dsa_key::import_public_pem(const std::string &pem) { +dsa_key dsa_key::import_public_pem(std::string_view pem) { auto source = bio{pem}; dsa_key res{}; dsa_key_accessor::set_impl( diff --git a/extra/opensslpp/src/opensslpp/dsa_sign_verify_operations.cpp b/extra/opensslpp/src/opensslpp/dsa_sign_verify_operations.cpp index ddb8a6977d39..c5e04b14a6ec 100644 --- a/extra/opensslpp/src/opensslpp/dsa_sign_verify_operations.cpp +++ b/extra/opensslpp/src/opensslpp/dsa_sign_verify_operations.cpp @@ -30,7 +30,7 @@ namespace opensslpp { std::string sign_with_dsa_private_key(const std::string &digest_type, - const std::string &digest_data, + std::string_view digest_data, const dsa_key &key) { assert(!key.is_empty()); @@ -42,27 +42,26 @@ std::string sign_with_dsa_private_key(const std::string &digest_type, auto md_nid = EVP_MD_type(md); - // TODO: use c++17 non-const std::string::data() member here - using buffer_type = std::vector; - buffer_type res(key.get_size_in_bytes()); + std::string res(key.get_size_in_bytes(), '\0'); unsigned int signature_length = 0; auto sign_status = DSA_sign( - md_nid, reinterpret_cast(digest_data.c_str()), - digest_data.size(), res.data(), &signature_length, - dsa_key_accessor::get_impl_const_casted(key)); + md_nid, reinterpret_cast(digest_data.data()), + digest_data.size(), reinterpret_cast(res.data()), + &signature_length, dsa_key_accessor::get_impl_const_casted(key)); if (sign_status != 1) core_error::raise_with_error_string( "cannot sign message digest with the specified private DSA key"); - return {reinterpret_cast(res.data()), - static_cast(signature_length)}; + res.resize(signature_length); + + return res; } bool verify_with_dsa_public_key(const std::string &digest_type, - const std::string &digest_data, - const std::string &signature_data, + std::string_view digest_data, + std::string_view signature_data, const dsa_key &key) { assert(!key.is_empty()); @@ -72,9 +71,9 @@ bool verify_with_dsa_public_key(const std::string &digest_type, auto md_nid = EVP_MD_type(md); auto verify_status = DSA_verify( - md_nid, reinterpret_cast(digest_data.c_str()), + md_nid, reinterpret_cast(digest_data.data()), digest_data.size(), - reinterpret_cast(signature_data.c_str()), + reinterpret_cast(signature_data.data()), signature_data.size(), dsa_key_accessor::get_impl_const_casted(key)); assert(verify_status == -1 || verify_status == 0 || verify_status == 1); diff --git a/extra/opensslpp/src/opensslpp/evp_pkey.cpp b/extra/opensslpp/src/opensslpp/evp_pkey.cpp new file mode 100644 index 000000000000..5f1d60ab559c --- /dev/null +++ b/extra/opensslpp/src/opensslpp/evp_pkey.cpp @@ -0,0 +1,309 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include "opensslpp/bio.hpp" +#include "opensslpp/bio_accessor.hpp" +#include "opensslpp/evp_pkey_accessor.hpp" +#include "opensslpp/evp_pkey_algorithm_conversions.hpp" +#include "opensslpp/rsa_key_accessor.hpp" + +namespace { + +void duplicate_evp_pkey(opensslpp::evp_pkey &dest, + const opensslpp::evp_pkey &source, bool public_only) { + assert(!source.is_empty()); + + auto *casted_impl{ + opensslpp::evp_pkey_accessor::get_impl_const_casted(source)}; + unsigned char *der_raw{nullptr}; + const auto serializer{public_only ? &i2d_PublicKey : &i2d_PrivateKey}; + auto der_length{(*serializer)(casted_impl, &der_raw)}; + if (der_length < 0) { + opensslpp::core_error::raise_with_error_string( + "cannot serialize EVP_PKEY to DER format"); + } + + struct ossl_deleter { + void operator()(void *ptr) const noexcept { + if (ptr != nullptr) { + OPENSSL_free(ptr); + } + } + }; + using buffer_ptr = std::unique_ptr; + buffer_ptr der{der_raw}; + + const unsigned char *der_ptr{der_raw}; + const auto deserializer{public_only ? &d2i_PublicKey : &d2i_PrivateKey}; + opensslpp::evp_pkey_accessor::set_impl( + dest, (*deserializer)(EVP_PKEY_base_id(casted_impl), nullptr, &der_ptr, + der_length)); + if (dest.is_empty()) { + opensslpp::core_error::raise_with_error_string( + "cannot deserialize EVP_PKEY from DER format"); + } +} + +} // anonymous namespace + +namespace opensslpp { + +void evp_pkey::evp_pkey_deleter::operator()(void *evp_pkey) const noexcept { + if (evp_pkey != nullptr) EVP_PKEY_free(static_cast(evp_pkey)); +} + +evp_pkey::evp_pkey(const evp_pkey &obj) : impl_{} { + if (!obj.is_empty()) { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + // due to a bug in openssl interface, EVP_PKEY_dup() expects + // non-const parameter while it does not do any modifications with the + // object - it just performs duplication via ASN1_item_i2d/ASN1_item_d2i + // conversions + impl_.reset(EVP_PKEY_dup(evp_pkey_accessor::get_impl_const_casted(obj))); + if (!impl_) { + throw core_error{"cannot duplicate EVP_PKEY key"}; + } +#else + duplicate_evp_pkey(*this, obj, !obj.is_private()); +#endif + } +} + +evp_pkey &evp_pkey::operator=(const evp_pkey &obj) { + auto tmp = evp_pkey{obj}; + swap(tmp); + return *this; +} + +void evp_pkey::swap(evp_pkey &obj) noexcept { impl_.swap(obj.impl_); } + +evp_pkey_algorithm evp_pkey::get_algorithm() const noexcept { + assert(!is_empty()); + auto native_algorithm{EVP_PKEY_base_id(evp_pkey_accessor::get_impl(*this))}; + return native_algorithm_to_evp_pkey_algorithm(native_algorithm); +} + +bool evp_pkey::is_private() const noexcept { + assert(!is_empty()); + + // TODO: implement checks for other algorithms + const auto *native_rsa{ + EVP_PKEY_get0_RSA(evp_pkey_accessor::get_impl_const_casted(*this))}; + assert(native_rsa != nullptr); + rsa_key underlying_key; + rsa_key_accessor::set_impl(underlying_key, const_cast(native_rsa)); + const auto res{underlying_key.is_private()}; + rsa_key_accessor::release(underlying_key); + return res; +} + +std::size_t evp_pkey::get_size_in_bits() const noexcept { + assert(!is_empty()); + return EVP_PKEY_bits(evp_pkey_accessor::get_impl(*this)); +} + +std::size_t evp_pkey::get_size_in_bytes() const noexcept { + assert(!is_empty()); + return EVP_PKEY_size(evp_pkey_accessor::get_impl(*this)); +} + +evp_pkey evp_pkey::derive_public_key() const { + assert(!is_empty()); + + evp_pkey res{}; + duplicate_evp_pkey(res, *this, true); + + return res; +} + +class evp_pkey_keygen_ctx { + public: + evp_pkey_keygen_ctx( + int id, const key_generation_cancellation_callback &cancellation_callback) + : impl_{EVP_PKEY_CTX_new_id(id, nullptr)}, + cancellation_callback_{&cancellation_callback}, + cancelled_{false} { + assert(id == EVP_PKEY_RSA); + if (!impl_) { + throw core_error{"cannot create EVP_PKEY context for key generation"}; + } + + if (EVP_PKEY_keygen_init(impl_.get()) <= 0) { + throw core_error{"cannot initialize EVP_PKEY context for key generation"}; + } + } + + evp_pkey generate(std::size_t bits) { + // TODO: implement setting bit length for other algorithms + if (EVP_PKEY_CTX_set_rsa_keygen_bits(impl_.get(), bits) <= 0) { + throw core_error{"cannot set EVP_PKEY context key generation parameters"}; + } + + EVP_PKEY_CTX_set_cb(impl_.get(), + &evp_pkey_keygen_ctx::generate_pkey_callback); + EVP_PKEY_CTX_set_app_data(impl_.get(), this); + cancelled_ = false; + + EVP_PKEY *pkey{nullptr}; + auto generation_status{EVP_PKEY_keygen(impl_.get(), &pkey)}; + + if (cancelled_) { + throw operation_cancelled_error{"EVP_PKEY key generation cancelled"}; + } + + if (generation_status <= 0) { + core_error::raise_with_error_string("cannot generate EVP_PKEY"); + } + + evp_pkey res{}; + evp_pkey_accessor::set_impl(res, pkey); + + return res; + } + + private: + struct evp_pkey_ctx_deleter { + void operator()(EVP_PKEY_CTX *ctx) const noexcept { + if (ctx != nullptr) { + EVP_PKEY_CTX_free(ctx); + } + } + }; + using impl_ptr = std::unique_ptr; + impl_ptr impl_; + const key_generation_cancellation_callback *cancellation_callback_; + bool cancelled_; + + static int generate_pkey_callback(EVP_PKEY_CTX *ctx) { + auto &parent{ + *static_cast(EVP_PKEY_CTX_get_app_data(ctx))}; + try { + parent.cancelled_ = (*parent.cancellation_callback_)(); + } catch (...) { + parent.cancelled_ = true; + } + + return parent.cancelled_ ? 0 : 1; + } +}; + +/*static*/ +evp_pkey evp_pkey::generate( + evp_pkey_algorithm algorithm, std::uint32_t bits, + const key_generation_cancellation_callback + &cancellation_callback /* = key_generation_cancellation_callback{} */) { + validate_if_algorithm_supported(algorithm); + + evp_pkey_keygen_ctx ctx{evp_pkey_algorithm_to_native_algorithm(algorithm), + cancellation_callback}; + return ctx.generate(bits); +} + +/*static*/ +std::string evp_pkey::export_private_pem(const evp_pkey &key) { + assert(!key.is_empty()); + + if (!key.is_private()) + throw core_error{"EVP_PKEY does not have private components"}; + + auto sink = bio{}; + const int r = + PEM_write_bio_PrivateKey(bio_accessor::get_impl(sink), + evp_pkey_accessor::get_impl_const_casted(key), + nullptr, nullptr, 0, nullptr, nullptr); + + if (r <= 0) + core_error::raise_with_error_string( + "cannot export EVP_PKEY key to PEM PRIVATE KEY"); + + return std::string{sink.sv()}; +} + +/*static*/ +std::string evp_pkey::export_public_pem(const evp_pkey &key) { + assert(!key.is_empty()); + + auto sink = bio{}; + const int r = + PEM_write_bio_PUBKEY(bio_accessor::get_impl(sink), + evp_pkey_accessor::get_impl_const_casted(key)); + if (r == 0) + core_error::raise_with_error_string( + "cannot export EVP_PKEY key to PEM PUBLIC KEY"); + + return std::string{sink.sv()}; +} + +/*static*/ +evp_pkey evp_pkey::import_private_pem(std::string_view pem) { + auto source = bio{pem}; + evp_pkey res{}; + evp_pkey_accessor::set_impl( + res, PEM_read_bio_PrivateKey(bio_accessor::get_impl(source), nullptr, + nullptr, nullptr)); + if (res.is_empty()) + core_error::raise_with_error_string( + "cannot import EVP_PKEY from PEM PRIVATE KEY"); + + validate_if_algorithm_supported(res.get_algorithm()); + + return res; +} + +/*static*/ +evp_pkey evp_pkey::import_public_pem(std::string_view pem) { + auto source = bio{pem}; + evp_pkey res{}; + evp_pkey_accessor::set_impl( + res, PEM_read_bio_PUBKEY(bio_accessor::get_impl(source), nullptr, nullptr, + nullptr)); + if (res.is_empty()) + core_error::raise_with_error_string( + "cannot import EVP_PKEY from PEM PUBLIC KEY"); + + validate_if_algorithm_supported(res.get_algorithm()); + + return res; +} + +void evp_pkey::validate_if_algorithm_supported(evp_pkey_algorithm algorithm) { + if (algorithm != evp_pkey_algorithm::rsa) { + throw std::logic_error{ + "current implementation of EVP_PKEY wrapper does not support the " + "specified algorithm"}; + } +} + +std::ostream &operator<<(std::ostream &os, const evp_pkey &obj) { + assert(!obj.is_empty()); + return os << (obj.is_private() ? evp_pkey::export_private_pem(obj) + : evp_pkey::export_public_pem(obj)); +} + +} // namespace opensslpp diff --git a/extra/opensslpp/src/opensslpp/evp_pkey_sign_verify_operations.cpp b/extra/opensslpp/src/opensslpp/evp_pkey_sign_verify_operations.cpp new file mode 100644 index 000000000000..0855aa06dca6 --- /dev/null +++ b/extra/opensslpp/src/opensslpp/evp_pkey_sign_verify_operations.cpp @@ -0,0 +1,159 @@ +/* Copyright (c) 2022 Percona LLC and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include "opensslpp/evp_pkey_accessor.hpp" +#include "opensslpp/evp_pkey_signature_padding_conversions.hpp" + +namespace opensslpp { + +enum class sign_verify_operation_type { sign, verify }; + +class evp_pkey_sign_verify_ctx { + public: + evp_pkey_sign_verify_ctx(sign_verify_operation_type operation, + const evp_pkey &key, const std::string &digest_type) + : impl_{EVP_PKEY_CTX_new(evp_pkey_accessor::get_impl_const_casted(key), + nullptr)} { + if (!impl_) { + throw core_error{"cannot create EVP_PKEY context for sign/verify"}; + } + + if (operation == sign_verify_operation_type::sign) { + if (EVP_PKEY_sign_init(impl_.get()) <= 0) { + throw core_error{ + "cannot initialize EVP_PKEY context for sign operation"}; + } + } else if (operation == sign_verify_operation_type::verify) { + if (EVP_PKEY_verify_init(impl_.get()) <= 0) { + throw core_error{ + "cannot initialize EVP_PKEY context for verify operation"}; + } + } else { + assert(false); + } + + auto md = EVP_get_digestbyname(digest_type.c_str()); + if (md == nullptr) { + throw core_error{"unknown digest name"}; + } + + if (EVP_PKEY_CTX_set_signature_md(impl_.get(), md) <= 0) { + throw core_error{"cannot configure digest in EVP_PKEY context"}; + } + } + + void set_rsa_signature_padding_mode(int padding_mode) { + if (EVP_PKEY_CTX_set_rsa_padding(impl_.get(), padding_mode) <= 0) { + throw core_error{"cannot set RSA padding mode in EVP_PKEY context"}; + } + } + + std::string sign(std::string_view digest_data) { + std::string res; + std::size_t signature_length{0}; + + if (EVP_PKEY_sign( + impl_.get(), nullptr, &signature_length, + reinterpret_cast(std::data(digest_data)), + std::size(digest_data)) <= 0) { + throw core_error{"cannot determine EVP_PKEY signature length"}; + } + res.resize(signature_length, '\0'); + + if (EVP_PKEY_sign( + impl_.get(), reinterpret_cast(std::data(res)), + &signature_length, + reinterpret_cast(std::data(digest_data)), + std::size(digest_data)) <= 0) { + core_error::raise_with_error_string( + "cannot sign message digest with the specified private EVP_PKEY"); + } + res.resize(signature_length); + return res; + } + + bool verify(std::string_view digest_data, std::string_view signature_data) { + auto verification_status{EVP_PKEY_verify( + impl_.get(), + reinterpret_cast(std::data(signature_data)), + std::size(signature_data), + reinterpret_cast(std::data(digest_data)), + std::size(digest_data))}; + if (verification_status < 0) { + core_error::raise_with_error_string( + "cannot verify message digest with the specified public EVP_PKEY"); + } + return (verification_status != 0); + } + + private: + struct evp_pkey_ctx_deleter { + void operator()(EVP_PKEY_CTX *ctx) const noexcept { + if (ctx != nullptr) { + EVP_PKEY_CTX_free(ctx); + } + } + }; + using impl_ptr = std::unique_ptr; + impl_ptr impl_; +}; + +std::string sign_with_private_evp_pkey(const std::string &digest_type, + std::string_view digest_data, + const evp_pkey &key, + evp_pkey_signature_padding padding) { + assert(!key.is_empty()); + + if (!key.is_private()) + throw core_error{"EVP_PKEY key does not have private components"}; + + evp_pkey_sign_verify_ctx ctx{sign_verify_operation_type::sign, key, + digest_type}; + ctx.set_rsa_signature_padding_mode( + evp_pkey_signature_padding_to_native_padding(padding)); + + return ctx.sign(digest_data); +} + +bool verify_with_public_evp_pkey(const std::string &digest_type, + std::string_view digest_data, + std::string_view signature_data, + const evp_pkey &key, + evp_pkey_signature_padding padding) { + assert(!key.is_empty()); + + evp_pkey_sign_verify_ctx ctx{sign_verify_operation_type::verify, key, + digest_type}; + ctx.set_rsa_signature_padding_mode( + evp_pkey_signature_padding_to_native_padding(padding)); + + return ctx.verify(digest_data, signature_data); +} + +} // namespace opensslpp diff --git a/extra/opensslpp/src/opensslpp/rsa_encrypt_decrypt_operations.cpp b/extra/opensslpp/src/opensslpp/rsa_encrypt_decrypt_operations.cpp index 53e6c58f0e2e..41280418cc12 100644 --- a/extra/opensslpp/src/opensslpp/rsa_encrypt_decrypt_operations.cpp +++ b/extra/opensslpp/src/opensslpp/rsa_encrypt_decrypt_operations.cpp @@ -22,17 +22,17 @@ #include #include +#include #include -#include +#include "opensslpp/rsa_encryption_padding_conversions.hpp" #include "opensslpp/rsa_key_accessor.hpp" -#include "opensslpp/rsa_padding_conversions.hpp" namespace opensslpp { -std::string encrypt_with_rsa_public_key(const std::string &input, +std::string encrypt_with_rsa_public_key(std::string_view input, const rsa_key &key, - rsa_padding padding) { + rsa_encryption_padding padding) { assert(!key.is_empty()); if (input.size() > key.get_max_block_size_in_bytes(padding)) @@ -40,77 +40,85 @@ std::string encrypt_with_rsa_public_key(const std::string &input, "encryption block size is too long for the specified padding and RSA " "key"}; - // TODO: use c++17 non-const std::string::data() member here - using buffer_type = std::vector; - buffer_type res(key.get_size_in_bytes()); + std::string res(key.get_size_in_bytes(), '\0'); auto enc_status = RSA_public_encrypt( - input.size(), reinterpret_cast(input.c_str()), - res.data(), rsa_key_accessor::get_impl_const_casted(key), - rsa_padding_to_native_padding(padding)); + input.size(), reinterpret_cast(input.data()), + reinterpret_cast(res.data()), + rsa_key_accessor::get_impl_const_casted(key), + rsa_encryption_padding_to_native_padding(padding)); if (enc_status == -1) core_error::raise_with_error_string( "cannot encrypt data block with the specified public RSA key"); - return {reinterpret_cast(res.data()), res.size()}; + return res; } -std::string encrypt_with_rsa_private_key(const std::string &input, +std::string encrypt_with_rsa_private_key(std::string_view input, const rsa_key &key, - rsa_padding padding) { + rsa_encryption_padding padding) { assert(!key.is_empty()); if (!key.is_private()) throw core_error{"RSA key does not have private components"}; + if (padding == rsa_encryption_padding::pkcs1_oaep) + throw core_error{ + "encrypting with RSA private key is not supported for PKCS1 OAEP " + "padding"}; + if (input.size() > key.get_max_block_size_in_bytes(padding)) throw core_error{ "encryption block size is too long for the specified padding and RSA " "key"}; - // TODO: use c++17 non-const std::string::data() member here - using buffer_type = std::vector; - buffer_type res(key.get_size_in_bytes()); + std::string res(key.get_size_in_bytes(), '\0'); auto enc_status = RSA_private_encrypt( - input.size(), reinterpret_cast(input.c_str()), - res.data(), rsa_key_accessor::get_impl_const_casted(key), - rsa_padding_to_native_padding(padding)); + input.size(), reinterpret_cast(input.data()), + reinterpret_cast(res.data()), + rsa_key_accessor::get_impl_const_casted(key), + rsa_encryption_padding_to_native_padding(padding)); if (enc_status == -1) core_error::raise_with_error_string( "cannot encrypt data block with the specified private RSA key"); - return {reinterpret_cast(res.data()), res.size()}; + return res; } -std::string decrypt_with_rsa_public_key(const std::string &input, +std::string decrypt_with_rsa_public_key(std::string_view input, const rsa_key &key, - rsa_padding padding) { + rsa_encryption_padding padding) { assert(!key.is_empty()); + if (padding == rsa_encryption_padding::pkcs1_oaep) + throw core_error{ + "decrypting with RSA public key is not supported for PKCS1 OAEP " + "padding"}; + if (input.size() != key.get_size_in_bytes()) throw core_error{ "decryption block size is not the same as RSA key length in bytes"}; - // TODO: use c++17 non-const std::string::data() member here - using buffer_type = std::vector; - buffer_type res(key.get_size_in_bytes()); + std::string res(key.get_size_in_bytes(), '\0'); auto enc_status = RSA_public_decrypt( - input.size(), reinterpret_cast(input.c_str()), - res.data(), rsa_key_accessor::get_impl_const_casted(key), - rsa_padding_to_native_padding(padding)); + input.size(), reinterpret_cast(input.data()), + reinterpret_cast(res.data()), + rsa_key_accessor::get_impl_const_casted(key), + rsa_encryption_padding_to_native_padding(padding)); if (enc_status == -1) core_error::raise_with_error_string( - "cannot encrypt data block with the specified public RSA key"); + "cannot decrypt data block with the specified public RSA key"); - return {reinterpret_cast(res.data()), - static_cast(enc_status)}; + assert(enc_status >= 0); + res.resize(static_cast(enc_status)); + return res; } -std::string decrypt_with_rsa_private_key(const std::string &input, +std::string decrypt_with_rsa_private_key(std::string_view input, const rsa_key &key, - rsa_padding padding) { + rsa_encryption_padding padding) { assert(!key.is_empty()); if (!key.is_private()) @@ -120,20 +128,21 @@ std::string decrypt_with_rsa_private_key(const std::string &input, throw core_error{ "decryption block size is not the same as RSA key length in bytes"}; - // TODO: use c++17 non-const std::string::data() member here - using buffer_type = std::vector; - buffer_type res(key.get_size_in_bytes()); + std::string res(key.get_size_in_bytes(), '\0'); auto enc_status = RSA_private_decrypt( - input.size(), reinterpret_cast(input.c_str()), - res.data(), rsa_key_accessor::get_impl_const_casted(key), - rsa_padding_to_native_padding(padding)); + input.size(), reinterpret_cast(input.data()), + reinterpret_cast(res.data()), + rsa_key_accessor::get_impl_const_casted(key), + rsa_encryption_padding_to_native_padding(padding)); if (enc_status == -1) core_error::raise_with_error_string( - "cannot encrypt data block with the specified private RSA key"); + "cannot decrypt data block with the specified private RSA key"); + + assert(enc_status >= 0); + res.resize(static_cast(enc_status)); - return {reinterpret_cast(res.data()), - static_cast(enc_status)}; + return res; } } // namespace opensslpp diff --git a/extra/opensslpp/src/opensslpp/rsa_key.cpp b/extra/opensslpp/src/opensslpp/rsa_key.cpp index 744bf757f55e..71bfe090d247 100644 --- a/extra/opensslpp/src/opensslpp/rsa_key.cpp +++ b/extra/opensslpp/src/opensslpp/rsa_key.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include "opensslpp/big_number_accessor.hpp" #include "opensslpp/bio.hpp" @@ -98,16 +98,23 @@ std::size_t rsa_key::get_size_in_bytes() const noexcept { } std::size_t rsa_key::get_max_block_size_in_bytes( - rsa_padding padding) const noexcept { + rsa_encryption_padding padding) const noexcept { assert(!is_empty()); std::size_t padding_bytes = 0; switch (padding) { - case rsa_padding::no: + case rsa_encryption_padding::no: padding_bytes = 0; break; - case rsa_padding::pkcs1: + case rsa_encryption_padding::pkcs1: padding_bytes = RSA_PKCS1_PADDING_SIZE; break; + case rsa_encryption_padding::pkcs1_oaep: + // for some reason, does not have a constant for max padding + // size for RSA_PKCS1_OAEP_PADDING + // the number is taken from here + // https://www.openssl.org/docs/man1.1.1/man3/RSA_public_encrypt.html + padding_bytes = 42; + break; } std::size_t block_size = get_size_in_bytes(); return block_size > padding_bytes ? block_size - padding_bytes : 0; @@ -161,7 +168,7 @@ std::string rsa_key::export_private_pem(const rsa_key &key) { core_error::raise_with_error_string( "cannot export RSA key to PEM PRIVATE KEY"); - return sink.str(); + return std::string{sink.sv()}; } /*static*/ @@ -176,11 +183,11 @@ std::string rsa_key::export_public_pem(const rsa_key &key) { core_error::raise_with_error_string( "cannot export RSA key to PEM PUBLIC KEY"); - return sink.str(); + return std::string{sink.sv()}; } /*static*/ -rsa_key rsa_key::import_private_pem(const std::string &pem) { +rsa_key rsa_key::import_private_pem(std::string_view pem) { auto source = bio{pem}; rsa_key res{}; rsa_key_accessor::set_impl( @@ -194,7 +201,7 @@ rsa_key rsa_key::import_private_pem(const std::string &pem) { } /*static*/ -rsa_key rsa_key::import_public_pem(const std::string &pem) { +rsa_key rsa_key::import_public_pem(std::string_view pem) { auto source = bio{pem}; rsa_key res{}; rsa_key_accessor::set_impl( diff --git a/extra/opensslpp/src/opensslpp/rsa_sign_verify_operations.cpp b/extra/opensslpp/src/opensslpp/rsa_sign_verify_operations.cpp index e508fee7d7d7..c2704e9365d9 100644 --- a/extra/opensslpp/src/opensslpp/rsa_sign_verify_operations.cpp +++ b/extra/opensslpp/src/opensslpp/rsa_sign_verify_operations.cpp @@ -31,7 +31,7 @@ namespace opensslpp { std::string sign_with_rsa_private_key(const std::string &digest_type, - const std::string &digest_data, + std::string_view digest_data, const rsa_key &key) { assert(!key.is_empty()); @@ -43,27 +43,25 @@ std::string sign_with_rsa_private_key(const std::string &digest_type, auto md_nid = EVP_MD_type(md); - // TODO: use c++17 non-const std::string::data() member here - using buffer_type = std::vector; - buffer_type res(key.get_size_in_bytes()); + std::string res(key.get_size_in_bytes(), '\0'); unsigned int signature_length = 0; auto sign_status = RSA_sign( - md_nid, reinterpret_cast(digest_data.c_str()), - digest_data.size(), res.data(), &signature_length, - rsa_key_accessor::get_impl_const_casted(key)); + md_nid, reinterpret_cast(digest_data.data()), + digest_data.size(), reinterpret_cast(res.data()), + &signature_length, rsa_key_accessor::get_impl_const_casted(key)); if (sign_status != 1) core_error::raise_with_error_string( "cannot sign message digest with the specified private RSA key"); - return {reinterpret_cast(res.data()), - static_cast(signature_length)}; + res.resize(signature_length); + return res; } bool verify_with_rsa_public_key(const std::string &digest_type, - const std::string &digest_data, - const std::string &signature_data, + std::string_view digest_data, + std::string_view signature_data, const rsa_key &key) { assert(!key.is_empty()); @@ -73,12 +71,12 @@ bool verify_with_rsa_public_key(const std::string &digest_type, auto md_nid = EVP_MD_type(md); auto verify_status = RSA_verify( - md_nid, reinterpret_cast(digest_data.c_str()), + md_nid, reinterpret_cast(digest_data.data()), digest_data.size(), - reinterpret_cast(signature_data.c_str()), + reinterpret_cast(signature_data.data()), signature_data.size(), rsa_key_accessor::get_impl_const_casted(key)); - // RSA_verify() does not destinguish between "an error occurred" and + // RSA_verify() does not distinguish between "an error occurred" and // "invalid signature" - in both cases 0 is returned. // Therefore, we need to make sure that the OpenSSL error code queue // will be empty after this call, so that it would not affect invoking diff --git a/mysql-test/include/percona_encryption_udf_xsa.inc b/mysql-test/include/percona_encryption_udf_xsa.inc deleted file mode 100644 index 26b56c327c04..000000000000 --- a/mysql-test/include/percona_encryption_udf_xsa.inc +++ /dev/null @@ -1,200 +0,0 @@ -# -# Creating functions from encryption_udf -# -INSTALL COMPONENT 'file://component_encryption_udf'; - ---let $include_digests_with_no_ans1_ids = 0 ---source include/percona_encryption_udf_digest_table.inc - ---echo ---echo ** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality ---disable_query_log - ---echo ---echo ** [$algorithm] checking asymmertic algorithm functions -eval SET @algorithm = "$algorithm"; - ---echo ** [$algorithm][$key_length] checking asymmetric algorithm functions -if (!$use_openssl_binary) -{ - --echo **** [$algorithm][$key_length] generating private key - eval SET @priv = create_asymmetric_priv_key(@algorithm, $key_length); -} -if ($use_openssl_binary) -{ - --let $private_key_file_path = $MYSQLTEST_VARDIR/tmp/private.pem - --echo **** [$algorithm][$key_length] generating private key with openssl binary - if ($algorithm == 'RSA') - { - --let $subcommand = genrsa - } - if ($algorithm == 'DSA') - { - --let $subcommand = dsaparam -genkey -noout - } - --exec $OPENSSL_EXECUTABLE $subcommand -out $private_key_file_path $key_length - --replace_result $private_key_file_path - eval SET @priv = TRIM(TRAILING '\n' FROM LOAD_FILE('$private_key_file_path')); -} - -if (!$use_openssl_binary) -{ - --echo **** [$algorithm][$key_length] deriving public key - SET @pub = create_asymmetric_pub_key(@algorithm, @priv); -} -if ($use_openssl_binary) -{ - --let $public_key_file_path = $MYSQLTEST_VARDIR/tmp/public.pem - --echo **** [$algorithm][$key_length] deriving public key with openssl binary - if ($algorithm == 'RSA') - { - --let $subcommand = rsa - } - if ($algorithm == 'DSA') - { - --let $subcommand = dsa - } - --exec $OPENSSL_EXECUTABLE $subcommand -in $private_key_file_path -pubout -out $public_key_file_path - --replace_result $public_key_file_path - eval SET @pub = TRIM(TRAILING '\n' FROM LOAD_FILE('$public_key_file_path')); - --remove_file $public_key_file_path - --remove_file $private_key_file_path - - --let $assert_text = [$algorithm][$key_length] public key created with create_asymmetric_pub_key must be identical to the one created with openssl $subcommand - --let $assert_cond = @pub = create_asymmetric_pub_key(@algorithm, @priv) - --let $include_silent = 1 - --source include/assert.inc - --let $include_silent = -} - -# for RSA = - ---let $max_message_size = `SELECT $key_length DIV 8` -if ($algorithm == 'RSA') -{ - --let $max_message_size = `SELECT $max_message_size - 11` -} - -# size of MD5 hash in bytes is 32 -eval SET @random_pattern = REPEAT(MD5(42), $max_message_size DIV 32 + 1); - -if ($algorithm == 'RSA') -{ - --echo **** [$algorithm][$key_length] checking operations on NULL message - SET @message = NULL; - --echo ****** [$algorithm][$key_length] checking encryption with public key of NULL message - --error ER_UDF_ERROR - SELECT asymmetric_encrypt(@algorithm, @message, @pub); - --echo ****** [$algorithm][$key_length] checking encryption with private key of NULL message - --error ER_UDF_ERROR - SELECT asymmetric_encrypt(@algorithm, @message, @priv); -} - ---let $message_index = 1 -while ($message_index <= 4) -{ - --let $message_length = `SELECT ELT($message_index, 0, 1, $max_message_size DIV 2, $max_message_size)` - eval SET @message = LEFT(@random_pattern, $message_length); - --echo **** [$algorithm][$key_length][message_len=$message_length] checking operations - - if ($algorithm == 'RSA') - { - --echo ****** [$algorithm][$key_length][message_len=$message_length] checking encryption with public key - SET @message_enc_with_pub = asymmetric_encrypt(@algorithm, @message, @pub); - # RSA encryption with public key should include random bytes in padding and therefore - # calls to "asymmetric_encrypt('RSA', @message, @pub)" with the same arguments are expected to - # return different results - --let $assert_text = [$algorithm][$key_length][message_len=$message_length] message encrypted with public key for the second time must differ - --let $assert_cond = @message_enc_with_pub <> asymmetric_encrypt(@algorithm, @message, @pub) - --let $include_silent = 1 - --source include/assert.inc - --let $include_silent = - - --echo ****** [$algorithm][$key_length][message_len=$message_length] checking decryption with private key - SET @message_dec_with_priv = asymmetric_decrypt(@algorithm, @message_enc_with_pub, @priv); - --let $assert_text = [$algorithm][$key_length][message_len=$message_length] message decrypted with private key must match the original one - --let $assert_cond = @message_dec_with_priv = @message - --let $include_silent = 1 - --source include/assert.inc - --let $include_silent = - - --echo ****** [$algorithm][$key_length][message_len=$message_length] checking encryption with private key - SET @message_enc_with_priv = asymmetric_encrypt(@algorithm, @message, @priv); - # RSA encryption with private key should be deterministic and therefore - # calls to "asymmetric_encrypt('RSA', @message, @pub)" with the same arguments are expected to - # return identical results - --let $assert_text = [$algorithm][$key_length][message_len=$message_length] message encrypted with private key for the second time must not differ - --let $assert_cond = @message_enc_with_priv = asymmetric_encrypt(@algorithm, @message, @priv) - --let $include_silent = 1 - --source include/assert.inc - --let $include_silent = - - --echo ****** [$algorithm][$key_length][message_len=$message_length] checking decryption with public key - SET @message_dec_with_pub = asymmetric_decrypt(@algorithm, @message_enc_with_priv, @pub); - --let $assert_text = [$algorithm][$key_length][message_len=$message_length] message decrypted with public key must match the original one - --let $assert_cond = @message_dec_with_pub = @message - --let $include_silent = 1 - --source include/assert.inc - --let $include_silent = - } - - --echo ****** [$algorithm][$key_length][message_len=$message_length] checking sign/verify functionality - --let $digest_type_idx = 1 - while($digest_type_idx <= $number_of_digest_types) - { - --let $digest_name = `SELECT digest_name FROM digest_type WHERE id = $digest_type_idx` - eval SET @digest_type = '$digest_name'; - SET @message_digest = create_digest(@digest_type, @message); - SET @message_signature = asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type); - if ($algorithm == 'RSA') - { - # RSA signing with private key should be deterministic and therefore - # calls to "asymmetric_sign('RSA', @message_digest, @priv, @digest_type)" with the same arguments - # are expected to return identical results - --let $assert_text = [$algorithm][$key_length][message_len=$message_length][$digest_name] calculating signature for the second time must not differ - --let $assert_cond = @message_signature = asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type) - } - if ($algorithm == 'DSA') - { - # DSA signing with private key should include random bytes in padding and therefore - # calls to "asymmetric_sign('DSA', @message_digest, @priv, @digest_type)" with the same arguments - # are expected to return different results - --let $assert_text = [$algorithm][$key_length][message_len=$message_length][$digest_name] calculating signature for the second time must not differ - --let $assert_cond = @message_signature <> asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type) - } - --let $include_silent = 1 - --source include/assert.inc - --let $include_silent = - - SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @message_signature, @pub, @digest_type); - --let $assert_text = [$algorithm][$key_length][message_len=$message_length][$digest_name] signature must pass verification - --let $assert_cond = @verification_result = 1 - --let $include_silent = 1 - --source include/assert.inc - --let $include_silent = - - --inc $digest_type_idx - } - - --inc $message_index -} - -if ($algorithm == 'RSA') -{ - --let $message_length = $max_message_size + 1 - --echo **** [$algorithm][$key_length] checking operations on oversize message - eval SET @message = LEFT(@random_pattern, $message_length); - --echo ****** [$algorithm][$key_length] checking encryption of oversize message with public key - --error ER_UDF_ERROR - SELECT asymmetric_encrypt(@algorithm, @message, @pub); - --echo ****** [$algorithm][$key_length] checking encryption of oversize message with private key - --error ER_UDF_ERROR - SELECT asymmetric_encrypt(@algorithm, @message, @priv); -} - ---enable_query_log - - -# -# Dropping functions from encryption_udf -# -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 4604fe452605..d447ebdf9a5b 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -302,6 +302,7 @@ sub set_term_args { audit_log_filter binlog_57_decryption percona-pam-for-mysql + component_encryption_udf component_masking_functions data_masking procfs diff --git a/mysql-test/r/percona_encryption_udf_dsa_1024.result b/mysql-test/r/percona_encryption_udf_dsa_1024.result deleted file mode 100644 index 58631792774d..000000000000 --- a/mysql-test/r/percona_encryption_udf_dsa_1024.result +++ /dev/null @@ -1,17 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [DSA] checking asymmertic algorithm functions -** [DSA][1024] checking asymmetric algorithm functions -**** [DSA][1024] generating private key -**** [DSA][1024] deriving public key -**** [DSA][1024][message_len=0] checking operations -****** [DSA][1024][message_len=0] checking sign/verify functionality -**** [DSA][1024][message_len=1] checking operations -****** [DSA][1024][message_len=1] checking sign/verify functionality -**** [DSA][1024][message_len=64] checking operations -****** [DSA][1024][message_len=64] checking sign/verify functionality -**** [DSA][1024][message_len=128] checking operations -****** [DSA][1024][message_len=128] checking sign/verify functionality -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_dsa_1024_ext.result b/mysql-test/r/percona_encryption_udf_dsa_1024_ext.result deleted file mode 100644 index 493629b5068a..000000000000 --- a/mysql-test/r/percona_encryption_udf_dsa_1024_ext.result +++ /dev/null @@ -1,17 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [DSA] checking asymmertic algorithm functions -** [DSA][1024] checking asymmetric algorithm functions -**** [DSA][1024] generating private key with openssl binary -**** [DSA][1024] deriving public key with openssl binary -**** [DSA][1024][message_len=0] checking operations -****** [DSA][1024][message_len=0] checking sign/verify functionality -**** [DSA][1024][message_len=1] checking operations -****** [DSA][1024][message_len=1] checking sign/verify functionality -**** [DSA][1024][message_len=64] checking operations -****** [DSA][1024][message_len=64] checking sign/verify functionality -**** [DSA][1024][message_len=128] checking operations -****** [DSA][1024][message_len=128] checking sign/verify functionality -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_dsa_4096.result b/mysql-test/r/percona_encryption_udf_dsa_4096.result deleted file mode 100644 index 2f1b4e8eda6f..000000000000 --- a/mysql-test/r/percona_encryption_udf_dsa_4096.result +++ /dev/null @@ -1,17 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [DSA] checking asymmertic algorithm functions -** [DSA][4096] checking asymmetric algorithm functions -**** [DSA][4096] generating private key -**** [DSA][4096] deriving public key -**** [DSA][4096][message_len=0] checking operations -****** [DSA][4096][message_len=0] checking sign/verify functionality -**** [DSA][4096][message_len=1] checking operations -****** [DSA][4096][message_len=1] checking sign/verify functionality -**** [DSA][4096][message_len=256] checking operations -****** [DSA][4096][message_len=256] checking sign/verify functionality -**** [DSA][4096][message_len=512] checking operations -****** [DSA][4096][message_len=512] checking sign/verify functionality -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_dsa_4096_ext.result b/mysql-test/r/percona_encryption_udf_dsa_4096_ext.result deleted file mode 100644 index 14e4ae1c7f44..000000000000 --- a/mysql-test/r/percona_encryption_udf_dsa_4096_ext.result +++ /dev/null @@ -1,17 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [DSA] checking asymmertic algorithm functions -** [DSA][4096] checking asymmetric algorithm functions -**** [DSA][4096] generating private key with openssl binary -**** [DSA][4096] deriving public key with openssl binary -**** [DSA][4096][message_len=0] checking operations -****** [DSA][4096][message_len=0] checking sign/verify functionality -**** [DSA][4096][message_len=1] checking operations -****** [DSA][4096][message_len=1] checking sign/verify functionality -**** [DSA][4096][message_len=256] checking operations -****** [DSA][4096][message_len=256] checking sign/verify functionality -**** [DSA][4096][message_len=512] checking operations -****** [DSA][4096][message_len=512] checking sign/verify functionality -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_dsa_9984.result b/mysql-test/r/percona_encryption_udf_dsa_9984.result deleted file mode 100644 index c98a497c4380..000000000000 --- a/mysql-test/r/percona_encryption_udf_dsa_9984.result +++ /dev/null @@ -1,17 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [DSA] checking asymmertic algorithm functions -** [DSA][9984] checking asymmetric algorithm functions -**** [DSA][9984] generating private key -**** [DSA][9984] deriving public key -**** [DSA][9984][message_len=0] checking operations -****** [DSA][9984][message_len=0] checking sign/verify functionality -**** [DSA][9984][message_len=1] checking operations -****** [DSA][9984][message_len=1] checking sign/verify functionality -**** [DSA][9984][message_len=624] checking operations -****** [DSA][9984][message_len=624] checking sign/verify functionality -**** [DSA][9984][message_len=1248] checking operations -****** [DSA][9984][message_len=1248] checking sign/verify functionality -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_dsa_9984_ext.result b/mysql-test/r/percona_encryption_udf_dsa_9984_ext.result deleted file mode 100644 index 1b0d46d8eaa5..000000000000 --- a/mysql-test/r/percona_encryption_udf_dsa_9984_ext.result +++ /dev/null @@ -1,17 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [DSA] checking asymmertic algorithm functions -** [DSA][9984] checking asymmetric algorithm functions -**** [DSA][9984] generating private key with openssl binary -**** [DSA][9984] deriving public key with openssl binary -**** [DSA][9984][message_len=0] checking operations -****** [DSA][9984][message_len=0] checking sign/verify functionality -**** [DSA][9984][message_len=1] checking operations -****** [DSA][9984][message_len=1] checking sign/verify functionality -**** [DSA][9984][message_len=624] checking operations -****** [DSA][9984][message_len=624] checking sign/verify functionality -**** [DSA][9984][message_len=1248] checking operations -****** [DSA][9984][message_len=1248] checking sign/verify functionality -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_rsa_1024.result b/mysql-test/r/percona_encryption_udf_rsa_1024.result deleted file mode 100644 index 007d6ba77e08..000000000000 --- a/mysql-test/r/percona_encryption_udf_rsa_1024.result +++ /dev/null @@ -1,43 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [RSA] checking asymmertic algorithm functions -** [RSA][1024] checking asymmetric algorithm functions -**** [RSA][1024] generating private key -**** [RSA][1024] deriving public key -**** [RSA][1024] checking operations on NULL message -****** [RSA][1024] checking encryption with public key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -****** [RSA][1024] checking encryption with private key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -**** [RSA][1024][message_len=0] checking operations -****** [RSA][1024][message_len=0] checking encryption with public key -****** [RSA][1024][message_len=0] checking decryption with private key -****** [RSA][1024][message_len=0] checking encryption with private key -****** [RSA][1024][message_len=0] checking decryption with public key -****** [RSA][1024][message_len=0] checking sign/verify functionality -**** [RSA][1024][message_len=1] checking operations -****** [RSA][1024][message_len=1] checking encryption with public key -****** [RSA][1024][message_len=1] checking decryption with private key -****** [RSA][1024][message_len=1] checking encryption with private key -****** [RSA][1024][message_len=1] checking decryption with public key -****** [RSA][1024][message_len=1] checking sign/verify functionality -**** [RSA][1024][message_len=58] checking operations -****** [RSA][1024][message_len=58] checking encryption with public key -****** [RSA][1024][message_len=58] checking decryption with private key -****** [RSA][1024][message_len=58] checking encryption with private key -****** [RSA][1024][message_len=58] checking decryption with public key -****** [RSA][1024][message_len=58] checking sign/verify functionality -**** [RSA][1024][message_len=117] checking operations -****** [RSA][1024][message_len=117] checking encryption with public key -****** [RSA][1024][message_len=117] checking decryption with private key -****** [RSA][1024][message_len=117] checking encryption with private key -****** [RSA][1024][message_len=117] checking decryption with public key -****** [RSA][1024][message_len=117] checking sign/verify functionality -**** [RSA][1024] checking operations on oversize message -****** [RSA][1024] checking encryption of oversize message with public key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -****** [RSA][1024] checking encryption of oversize message with private key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_rsa_1024_ext.result b/mysql-test/r/percona_encryption_udf_rsa_1024_ext.result deleted file mode 100644 index 76c36bdc5f53..000000000000 --- a/mysql-test/r/percona_encryption_udf_rsa_1024_ext.result +++ /dev/null @@ -1,43 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [RSA] checking asymmertic algorithm functions -** [RSA][1024] checking asymmetric algorithm functions -**** [RSA][1024] generating private key with openssl binary -**** [RSA][1024] deriving public key with openssl binary -**** [RSA][1024] checking operations on NULL message -****** [RSA][1024] checking encryption with public key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -****** [RSA][1024] checking encryption with private key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -**** [RSA][1024][message_len=0] checking operations -****** [RSA][1024][message_len=0] checking encryption with public key -****** [RSA][1024][message_len=0] checking decryption with private key -****** [RSA][1024][message_len=0] checking encryption with private key -****** [RSA][1024][message_len=0] checking decryption with public key -****** [RSA][1024][message_len=0] checking sign/verify functionality -**** [RSA][1024][message_len=1] checking operations -****** [RSA][1024][message_len=1] checking encryption with public key -****** [RSA][1024][message_len=1] checking decryption with private key -****** [RSA][1024][message_len=1] checking encryption with private key -****** [RSA][1024][message_len=1] checking decryption with public key -****** [RSA][1024][message_len=1] checking sign/verify functionality -**** [RSA][1024][message_len=58] checking operations -****** [RSA][1024][message_len=58] checking encryption with public key -****** [RSA][1024][message_len=58] checking decryption with private key -****** [RSA][1024][message_len=58] checking encryption with private key -****** [RSA][1024][message_len=58] checking decryption with public key -****** [RSA][1024][message_len=58] checking sign/verify functionality -**** [RSA][1024][message_len=117] checking operations -****** [RSA][1024][message_len=117] checking encryption with public key -****** [RSA][1024][message_len=117] checking decryption with private key -****** [RSA][1024][message_len=117] checking encryption with private key -****** [RSA][1024][message_len=117] checking decryption with public key -****** [RSA][1024][message_len=117] checking sign/verify functionality -**** [RSA][1024] checking operations on oversize message -****** [RSA][1024] checking encryption of oversize message with public key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -****** [RSA][1024] checking encryption of oversize message with private key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_rsa_16384.result b/mysql-test/r/percona_encryption_udf_rsa_16384.result deleted file mode 100644 index 758c89da548d..000000000000 --- a/mysql-test/r/percona_encryption_udf_rsa_16384.result +++ /dev/null @@ -1,43 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [RSA] checking asymmertic algorithm functions -** [RSA][16384] checking asymmetric algorithm functions -**** [RSA][16384] generating private key -**** [RSA][16384] deriving public key -**** [RSA][16384] checking operations on NULL message -****** [RSA][16384] checking encryption with public key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -****** [RSA][16384] checking encryption with private key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -**** [RSA][16384][message_len=0] checking operations -****** [RSA][16384][message_len=0] checking encryption with public key -****** [RSA][16384][message_len=0] checking decryption with private key -****** [RSA][16384][message_len=0] checking encryption with private key -****** [RSA][16384][message_len=0] checking decryption with public key -****** [RSA][16384][message_len=0] checking sign/verify functionality -**** [RSA][16384][message_len=1] checking operations -****** [RSA][16384][message_len=1] checking encryption with public key -****** [RSA][16384][message_len=1] checking decryption with private key -****** [RSA][16384][message_len=1] checking encryption with private key -****** [RSA][16384][message_len=1] checking decryption with public key -****** [RSA][16384][message_len=1] checking sign/verify functionality -**** [RSA][16384][message_len=1018] checking operations -****** [RSA][16384][message_len=1018] checking encryption with public key -****** [RSA][16384][message_len=1018] checking decryption with private key -****** [RSA][16384][message_len=1018] checking encryption with private key -****** [RSA][16384][message_len=1018] checking decryption with public key -****** [RSA][16384][message_len=1018] checking sign/verify functionality -**** [RSA][16384][message_len=2037] checking operations -****** [RSA][16384][message_len=2037] checking encryption with public key -****** [RSA][16384][message_len=2037] checking decryption with private key -****** [RSA][16384][message_len=2037] checking encryption with private key -****** [RSA][16384][message_len=2037] checking decryption with public key -****** [RSA][16384][message_len=2037] checking sign/verify functionality -**** [RSA][16384] checking operations on oversize message -****** [RSA][16384] checking encryption of oversize message with public key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -****** [RSA][16384] checking encryption of oversize message with private key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_rsa_16384_ext.result b/mysql-test/r/percona_encryption_udf_rsa_16384_ext.result deleted file mode 100644 index 05068f226938..000000000000 --- a/mysql-test/r/percona_encryption_udf_rsa_16384_ext.result +++ /dev/null @@ -1,43 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [RSA] checking asymmertic algorithm functions -** [RSA][16384] checking asymmetric algorithm functions -**** [RSA][16384] generating private key with openssl binary -**** [RSA][16384] deriving public key with openssl binary -**** [RSA][16384] checking operations on NULL message -****** [RSA][16384] checking encryption with public key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -****** [RSA][16384] checking encryption with private key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -**** [RSA][16384][message_len=0] checking operations -****** [RSA][16384][message_len=0] checking encryption with public key -****** [RSA][16384][message_len=0] checking decryption with private key -****** [RSA][16384][message_len=0] checking encryption with private key -****** [RSA][16384][message_len=0] checking decryption with public key -****** [RSA][16384][message_len=0] checking sign/verify functionality -**** [RSA][16384][message_len=1] checking operations -****** [RSA][16384][message_len=1] checking encryption with public key -****** [RSA][16384][message_len=1] checking decryption with private key -****** [RSA][16384][message_len=1] checking encryption with private key -****** [RSA][16384][message_len=1] checking decryption with public key -****** [RSA][16384][message_len=1] checking sign/verify functionality -**** [RSA][16384][message_len=1018] checking operations -****** [RSA][16384][message_len=1018] checking encryption with public key -****** [RSA][16384][message_len=1018] checking decryption with private key -****** [RSA][16384][message_len=1018] checking encryption with private key -****** [RSA][16384][message_len=1018] checking decryption with public key -****** [RSA][16384][message_len=1018] checking sign/verify functionality -**** [RSA][16384][message_len=2037] checking operations -****** [RSA][16384][message_len=2037] checking encryption with public key -****** [RSA][16384][message_len=2037] checking decryption with private key -****** [RSA][16384][message_len=2037] checking encryption with private key -****** [RSA][16384][message_len=2037] checking decryption with public key -****** [RSA][16384][message_len=2037] checking sign/verify functionality -**** [RSA][16384] checking operations on oversize message -****** [RSA][16384] checking encryption of oversize message with public key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -****** [RSA][16384] checking encryption of oversize message with private key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_rsa_4096.result b/mysql-test/r/percona_encryption_udf_rsa_4096.result deleted file mode 100644 index 22b140000a1c..000000000000 --- a/mysql-test/r/percona_encryption_udf_rsa_4096.result +++ /dev/null @@ -1,43 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [RSA] checking asymmertic algorithm functions -** [RSA][4096] checking asymmetric algorithm functions -**** [RSA][4096] generating private key -**** [RSA][4096] deriving public key -**** [RSA][4096] checking operations on NULL message -****** [RSA][4096] checking encryption with public key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -****** [RSA][4096] checking encryption with private key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -**** [RSA][4096][message_len=0] checking operations -****** [RSA][4096][message_len=0] checking encryption with public key -****** [RSA][4096][message_len=0] checking decryption with private key -****** [RSA][4096][message_len=0] checking encryption with private key -****** [RSA][4096][message_len=0] checking decryption with public key -****** [RSA][4096][message_len=0] checking sign/verify functionality -**** [RSA][4096][message_len=1] checking operations -****** [RSA][4096][message_len=1] checking encryption with public key -****** [RSA][4096][message_len=1] checking decryption with private key -****** [RSA][4096][message_len=1] checking encryption with private key -****** [RSA][4096][message_len=1] checking decryption with public key -****** [RSA][4096][message_len=1] checking sign/verify functionality -**** [RSA][4096][message_len=250] checking operations -****** [RSA][4096][message_len=250] checking encryption with public key -****** [RSA][4096][message_len=250] checking decryption with private key -****** [RSA][4096][message_len=250] checking encryption with private key -****** [RSA][4096][message_len=250] checking decryption with public key -****** [RSA][4096][message_len=250] checking sign/verify functionality -**** [RSA][4096][message_len=501] checking operations -****** [RSA][4096][message_len=501] checking encryption with public key -****** [RSA][4096][message_len=501] checking decryption with private key -****** [RSA][4096][message_len=501] checking encryption with private key -****** [RSA][4096][message_len=501] checking decryption with public key -****** [RSA][4096][message_len=501] checking sign/verify functionality -**** [RSA][4096] checking operations on oversize message -****** [RSA][4096] checking encryption of oversize message with public key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -****** [RSA][4096] checking encryption of oversize message with private key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_rsa_4096_ext.result b/mysql-test/r/percona_encryption_udf_rsa_4096_ext.result deleted file mode 100644 index 8c627f03d7ab..000000000000 --- a/mysql-test/r/percona_encryption_udf_rsa_4096_ext.result +++ /dev/null @@ -1,43 +0,0 @@ -INSTALL COMPONENT 'file://component_encryption_udf'; - -** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality - -** [RSA] checking asymmertic algorithm functions -** [RSA][4096] checking asymmetric algorithm functions -**** [RSA][4096] generating private key with openssl binary -**** [RSA][4096] deriving public key with openssl binary -**** [RSA][4096] checking operations on NULL message -****** [RSA][4096] checking encryption with public key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -****** [RSA][4096] checking encryption with private key of NULL message -ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null -**** [RSA][4096][message_len=0] checking operations -****** [RSA][4096][message_len=0] checking encryption with public key -****** [RSA][4096][message_len=0] checking decryption with private key -****** [RSA][4096][message_len=0] checking encryption with private key -****** [RSA][4096][message_len=0] checking decryption with public key -****** [RSA][4096][message_len=0] checking sign/verify functionality -**** [RSA][4096][message_len=1] checking operations -****** [RSA][4096][message_len=1] checking encryption with public key -****** [RSA][4096][message_len=1] checking decryption with private key -****** [RSA][4096][message_len=1] checking encryption with private key -****** [RSA][4096][message_len=1] checking decryption with public key -****** [RSA][4096][message_len=1] checking sign/verify functionality -**** [RSA][4096][message_len=250] checking operations -****** [RSA][4096][message_len=250] checking encryption with public key -****** [RSA][4096][message_len=250] checking decryption with private key -****** [RSA][4096][message_len=250] checking encryption with private key -****** [RSA][4096][message_len=250] checking decryption with public key -****** [RSA][4096][message_len=250] checking sign/verify functionality -**** [RSA][4096][message_len=501] checking operations -****** [RSA][4096][message_len=501] checking encryption with public key -****** [RSA][4096][message_len=501] checking decryption with private key -****** [RSA][4096][message_len=501] checking encryption with private key -****** [RSA][4096][message_len=501] checking decryption with public key -****** [RSA][4096][message_len=501] checking sign/verify functionality -**** [RSA][4096] checking operations on oversize message -****** [RSA][4096] checking encryption of oversize message with public key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -****** [RSA][4096] checking encryption of oversize message with private key -ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key -UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/include/percona_encryption_udf_dh.inc b/mysql-test/suite/component_encryption_udf/include/dh.inc similarity index 100% rename from mysql-test/include/percona_encryption_udf_dh.inc rename to mysql-test/suite/component_encryption_udf/include/dh.inc diff --git a/mysql-test/include/percona_encryption_udf_digest_table.inc b/mysql-test/suite/component_encryption_udf/include/digest_table.inc similarity index 81% rename from mysql-test/include/percona_encryption_udf_digest_table.inc rename to mysql-test/suite/component_encryption_udf/include/digest_table.inc index 532bd6f2f85d..b1e9d4b3ff65 100644 --- a/mysql-test/include/percona_encryption_udf_digest_table.inc +++ b/mysql-test/suite/component_encryption_udf/include/digest_table.inc @@ -81,20 +81,29 @@ if (`select "$ssl_ver" like "OpenSSL 1.1.1%"`) ('md4' , NULL), ('md5-sha1' , NULL), ('ripemd160' , NULL), - ('sha512-224', NULL), - ('sha512-256', NULL), - ('whirlpool' , NULL), - ('sm3' , NULL), - ('blake2b512', NULL), - ('blake2s256', NULL), ('sha3-224' , NULL), ('sha3-256' , NULL), ('sha3-384' , NULL), - ('sha3-512' , NULL), - ('shake128' , NULL), - ('shake256' , NULL) + ('sha3-512' , NULL) ; + # the following digests can only be used in create_digest() and not in + # asymmetric_sign() as these digests do not have corresponding asn1 + # object identifiers + if ($include_digests_with_no_ans1_ids) + { + INSERT INTO digest_type(digest_name, builtin_template) VALUES + ('sha512-224', NULL), + ('sha512-256', NULL), + ('whirlpool' , NULL), + ('sm3' , NULL), + ('blake2b512', NULL), + ('blake2s256', NULL), + ('shake128' , NULL), + ('shake256' , NULL) + ; + } + --enable_query_log --enable_result_log } @@ -108,14 +117,12 @@ if (`select "$ssl_ver" like "OpenSSL 3.%"`) INSERT INTO digest_type(digest_name, builtin_template) VALUES ('md5' , 'MD5(@message)'), - ('sha1' , 'SHA(@message)'), ('sha224' , 'SHA2(@message, 224)'), ('sha256' , 'SHA2(@message, 256)'), ('sha384' , 'SHA2(@message, 384)'), ('sha512' , 'SHA2(@message, 512)'), - ('md5-sha1' , NULL), ('sha512-224', NULL), ('sha512-256', NULL), ('sha3-224' , NULL), @@ -127,9 +134,14 @@ if (`select "$ssl_ver" like "OpenSSL 3.%"`) # BLAKE2B512, BLAKE2S256, SHAKE128, SHAKE256 and SM3 can only be used in # create_digest() and not in asymmetric_sign() as these digests do not have # corresponding asn1 object identifiers + + # for some reason on Oracle Linux 9 (with default OpenSSL 3.0.7) 'sha1' and + # 'md5-sha1' cannot be used in RSA EVP_PKEY signing operations if ($include_digests_with_no_ans1_ids) { INSERT INTO digest_type(digest_name, builtin_template) VALUES + ('sha1' , 'SHA(@message)'), + ('md5-sha1' , NULL), ('sm3' , NULL), ('blake2b512', NULL), ('blake2s256', NULL), diff --git a/mysql-test/suite/component_encryption_udf/include/xsa.inc b/mysql-test/suite/component_encryption_udf/include/xsa.inc new file mode 100644 index 000000000000..2d07e720ac66 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/include/xsa.inc @@ -0,0 +1,272 @@ +# +# Creating functions from encryption_udf +# +INSTALL COMPONENT 'file://component_encryption_udf'; + +--let $include_digests_with_no_ans1_ids = 0 +--source digest_table.inc + +--echo +--echo ** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality +--disable_query_log + +--echo +--echo ** [$algorithm] checking asymmetric algorithm functions +eval SET @algorithm = "$algorithm"; + +--echo ** [$algorithm][$key_length] checking asymmetric algorithm functions +if (!$use_openssl_binary) +{ + --echo **** [$algorithm][$key_length] generating private key + eval SET @priv = create_asymmetric_priv_key(@algorithm, $key_length); +} +if ($use_openssl_binary) +{ + --let $private_key_file_path = $MYSQLTEST_VARDIR/tmp/private.pem + --echo **** [$algorithm][$key_length] generating private key with openssl binary + if ($algorithm == 'RSA') + { + --let $subcommand = genrsa + } + if ($algorithm == 'DSA') + { + --let $subcommand = dsaparam -genkey -noout + } + --exec $OPENSSL_EXECUTABLE $subcommand -out $private_key_file_path $key_length + --replace_result $private_key_file_path + eval SET @priv = TRIM(TRAILING '\n' FROM LOAD_FILE('$private_key_file_path')); +} + +if (!$use_openssl_binary) +{ + --echo **** [$algorithm][$key_length] deriving public key + SET @pub = create_asymmetric_pub_key(@algorithm, @priv); +} +if ($use_openssl_binary) +{ + --let $public_key_file_path = $MYSQLTEST_VARDIR/tmp/public.pem + --echo **** [$algorithm][$key_length] deriving public key with openssl binary + if ($algorithm == 'RSA') + { + --let $subcommand = rsa + } + if ($algorithm == 'DSA') + { + --let $subcommand = dsa + } + --exec $OPENSSL_EXECUTABLE $subcommand -in $private_key_file_path -pubout -out $public_key_file_path + --replace_result $public_key_file_path + eval SET @pub = TRIM(TRAILING '\n' FROM LOAD_FILE('$public_key_file_path')); + --remove_file $public_key_file_path + --remove_file $private_key_file_path + + --let $assert_text = [$algorithm][$key_length] public key created with create_asymmetric_pub_key must be identical to the one created with openssl $subcommand + --let $assert_cond = @pub = create_asymmetric_pub_key(@algorithm, @priv) + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = +} + +# = +--let $max_message_size = `SELECT $key_length DIV 8` + +# size of MD5 hash in bytes is 32 +eval SET @random_pattern = REPEAT(MD5(42), $max_message_size DIV 32 + 1); + +if ($algorithm == 'RSA') +{ + --let $padding_scheme_index = 1 + while ($padding_scheme_index <= 3) + { + --let $padding_scheme = `SELECT ELT($padding_scheme_index, 'no', 'pkcs1', 'oaep')` + eval SET @padding_scheme = '$padding_scheme'; + + --echo **** [$algorithm][$key_length][$padding_scheme] checking encrypt/decrypt operations on NULL message + SET @message = NULL; + --echo ****** [$algorithm][$key_length][$padding_scheme] checking encryption with public key of NULL message + --error ER_UDF_ERROR + SELECT asymmetric_encrypt(@algorithm, @message, @pub, @padding_scheme); + --echo ****** [$algorithm][$key_length][$padding_scheme] checking encryption with private key of NULL message + --error ER_UDF_ERROR + SELECT asymmetric_encrypt(@algorithm, @message, @priv, @padding_scheme); + + --let $max_unpadded_message_size = `SELECT $max_message_size - ELT($padding_scheme_index, 0, 11, 42)` + + --let $message_length = $max_unpadded_message_size + 1 + --echo **** [$algorithm][$key_length][$padding_scheme] checking encrypt/decrypt operations on oversize message + eval SET @message = LEFT(@random_pattern, $message_length); + --echo ****** [$algorithm][$key_length][$padding_scheme] checking encryption of oversize message with public key + --error ER_UDF_ERROR + SELECT asymmetric_encrypt(@algorithm, @message, @pub, @padding_scheme); + --echo ****** [$algorithm][$key_length][$padding_scheme] checking encryption of oversize message with private key + --error ER_UDF_ERROR + SELECT asymmetric_encrypt(@algorithm, @message, @priv, @padding_scheme); + + --let $message_index = 1 + if ($padding_scheme == 'no') { + # for encryption with no padding we can only encrypt messages of size equal to the key size + --let $message_index = 4 + } + while ($message_index <= 4) + { + --let $message_length = `SELECT ELT($message_index, 0, 1, $max_unpadded_message_size DIV 2, $max_unpadded_message_size)` + eval SET @message = LEFT(@random_pattern, $message_length); + --echo **** [$algorithm][$key_length][$padding_scheme][message_len=$message_length] checking encrypt/decrypt operations + + --echo ****** [$algorithm][$key_length][$padding_scheme][message_len=$message_length] checking encryption with public key + SET @message_enc_with_pub = asymmetric_encrypt(@algorithm, @message, @pub, @padding_scheme); + if ($padding_scheme != 'no') + { + # RSA encryption with public key with 'pkcs1'/ 'oaep' padding schemes should include random bytes in padding and therefore + # calls to "asymmetric_encrypt('RSA', @message, @pub, @padding_scheme)" with the same arguments are expected to + # return different results + --let $assert_text = [$algorithm][$key_length][message_len=$message_length] message encrypted with public key for the second time must differ + --let $assert_cond = @message_enc_with_pub <> asymmetric_encrypt(@algorithm, @message, @pub, @padding_scheme) + } + if ($padding_scheme == 'no') + { + # RSA encryption with public key with no padding should not include random bytes and therefore + # calls to "asymmetric_encrypt('RSA', @message, @pub, @padding_scheme)" with the same arguments are expected to + # return identical results + --let $assert_text = [$algorithm][$key_length][message_len=$message_length] message encrypted with public key for the second time must be the same + --let $assert_cond = @message_enc_with_pub = asymmetric_encrypt(@algorithm, @message, @pub, @padding_scheme) + } + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + + --echo ****** [$algorithm][$key_length][$padding_scheme][message_len=$message_length] checking decryption with private key + SET @message_dec_with_priv = asymmetric_decrypt(@algorithm, @message_enc_with_pub, @priv, @padding_scheme); + --let $assert_text = [$algorithm][$key_length][message_len=$message_length] message decrypted with private key must match the original one + --let $assert_cond = @message_dec_with_priv = @message + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + + if ($padding_scheme != 'oaep') + { + # encrypting with RSA private key is not supported for PKCS1 OAEP padding + + --echo ****** [$algorithm][$key_length][$padding_scheme][message_len=$message_length] checking encryption with private key + SET @message_enc_with_priv = asymmetric_encrypt(@algorithm, @message, @priv, @padding_scheme); + # RSA encryption with private key should be deterministic and therefore + # calls to "asymmetric_encrypt('RSA', @message, @pub, @padding_scheme)" with the same arguments are expected to + # return identical results + --let $assert_text = [$algorithm][$key_length][message_len=$message_length] message encrypted with private key for the second time must not differ + --let $assert_cond = @message_enc_with_priv = asymmetric_encrypt(@algorithm, @message, @priv, @padding_scheme) + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + + --echo ****** [$algorithm][$key_length][$padding_scheme][message_len=$message_length] checking decryption with public key + SET @message_dec_with_pub = asymmetric_decrypt(@algorithm, @message_enc_with_priv, @pub, @padding_scheme); + --let $assert_text = [$algorithm][$key_length][message_len=$message_length] message decrypted with public key must match the original one + --let $assert_cond = @message_dec_with_pub = @message + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + } + + --inc $message_index + } + + --inc $padding_scheme_index + } +} + + +--let $message_index = 1 +while ($message_index <= 4) +{ + --let $message_length = `SELECT ELT($message_index, 0, 1, $max_message_size DIV 2, $max_message_size)` + eval SET @message = LEFT(@random_pattern, $message_length); + + --echo **** [$algorithm][$key_length][message_len=$message_length] checking sign/verify operations + --let $digest_type_idx = 1 + while($digest_type_idx <= $number_of_digest_types) + { + --let $digest_name = `SELECT digest_name FROM digest_type WHERE id = $digest_type_idx` + eval SET @digest_type = '$digest_name'; + SET @message_digest = create_digest(@digest_type, @message); + if ($algorithm == 'RSA') + { + SET @primary_signature_padding = 'pkcs1'; + SET @message_signature = asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, @primary_signature_padding); + # RSA signing with private key should be deterministic and therefore + # calls to "asymmetric_sign('RSA', @message_digest, @priv, @digest_type, @primary_signature_padding)" with the same arguments + # are expected to return identical results + --let $assert_text = [$algorithm][$key_length][message_len=$message_length][$digest_name] calculating pkcs1 signature for the second time must not differ + --let $assert_cond = @message_signature = asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, @primary_signature_padding) + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + + SET @extra_signature_padding = 'pkcs1_pss'; + SET @extra_message_signature = asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, @extra_signature_padding); + --let $assert_text = [$algorithm][$key_length][message_len=$message_length][$digest_name] calculating pkcs1_pss signature for the second time must differ + --let $assert_cond = @extra_message_signature <> asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, @extra_signature_padding) + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + + SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @message_signature, @pub, @digest_type, @primary_signature_padding); + --let $assert_text = [$algorithm][$key_length][message_len=$message_length][$digest_name] pkcs1 signature must pass verification + --let $assert_cond = @verification_result = 1 + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + + SET @extra_verification_result = asymmetric_verify(@algorithm, @message_digest, @message_signature, @pub, @digest_type, @primary_signature_padding); + --let $assert_text = [$algorithm][$key_length][message_len=$message_length][$digest_name] pkcs1_pss signature must pass verification + --let $assert_cond = @extra_verification_result = 1 + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + + SET @first_cross_verification_result = asymmetric_verify(@algorithm, @message_digest, @extra_message_signature, @pub, @digest_type, @primary_signature_padding); + --let $assert_text = [$algorithm][$key_length][message_len=$message_length][$digest_name] cross pkcs1_pss-pkcs1 signature must not pass verification + --let $assert_cond = @first_cross_verification_result = 0 + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + + SET @second_cross_verification_result = asymmetric_verify(@algorithm, @message_digest, @message_signature, @pub, @digest_type, @extra_signature_padding); + --let $assert_text = [$algorithm][$key_length][message_len=$message_length][$digest_name] cross pkcs1-pkcs1_pss signature must not pass verification + --let $assert_cond = @second_cross_verification_result = 0 + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + } + if ($algorithm == 'DSA') + { + SET @message_signature = asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type); + # DSA signing with private key should include random bytes in padding and therefore + # calls to "asymmetric_sign('DSA', @message_digest, @priv, @digest_type)" with the same arguments + # are expected to return different results + --let $assert_text = [$algorithm][$key_length][message_len=$message_length][$digest_name] calculating signature for the second time must not differ + --let $assert_cond = @message_signature <> asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type) + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + + SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @message_signature, @pub, @digest_type); + --let $assert_text = [$algorithm][$key_length][message_len=$message_length][$digest_name] signature must pass verification + --let $assert_cond = @verification_result = 1 + --let $include_silent = 1 + --source include/assert.inc + --let $include_silent = + } + + --inc $digest_type_idx + } + + --inc $message_index +} + +--enable_query_log + + +# +# Dropping functions from encryption_udf +# +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_bits_threshold.result b/mysql-test/suite/component_encryption_udf/r/bits_threshold.result similarity index 100% rename from mysql-test/r/percona_encryption_udf_bits_threshold.result rename to mysql-test/suite/component_encryption_udf/r/bits_threshold.result diff --git a/mysql-test/r/percona_encryption_udf_dh_1024.result b/mysql-test/suite/component_encryption_udf/r/dh_1024.result similarity index 100% rename from mysql-test/r/percona_encryption_udf_dh_1024.result rename to mysql-test/suite/component_encryption_udf/r/dh_1024.result diff --git a/mysql-test/r/percona_encryption_udf_dh_1024_ext.result b/mysql-test/suite/component_encryption_udf/r/dh_1024_ext.result similarity index 100% rename from mysql-test/r/percona_encryption_udf_dh_1024_ext.result rename to mysql-test/suite/component_encryption_udf/r/dh_1024_ext.result diff --git a/mysql-test/r/percona_encryption_udf_dh_4096.result b/mysql-test/suite/component_encryption_udf/r/dh_4096.result similarity index 100% rename from mysql-test/r/percona_encryption_udf_dh_4096.result rename to mysql-test/suite/component_encryption_udf/r/dh_4096.result diff --git a/mysql-test/r/percona_encryption_udf_dh_4096_ext.result b/mysql-test/suite/component_encryption_udf/r/dh_4096_ext.result similarity index 100% rename from mysql-test/r/percona_encryption_udf_dh_4096_ext.result rename to mysql-test/suite/component_encryption_udf/r/dh_4096_ext.result diff --git a/mysql-test/r/percona_encryption_udf_dh_sanity.result b/mysql-test/suite/component_encryption_udf/r/dh_sanity.result similarity index 100% rename from mysql-test/r/percona_encryption_udf_dh_sanity.result rename to mysql-test/suite/component_encryption_udf/r/dh_sanity.result diff --git a/mysql-test/r/percona_encryption_udf_digests.result b/mysql-test/suite/component_encryption_udf/r/digests.result similarity index 100% rename from mysql-test/r/percona_encryption_udf_digests.result rename to mysql-test/suite/component_encryption_udf/r/digests.result diff --git a/mysql-test/r/percona_encryption_udf_digests_sanity.result b/mysql-test/suite/component_encryption_udf/r/digests_sanity.result similarity index 100% rename from mysql-test/r/percona_encryption_udf_digests_sanity.result rename to mysql-test/suite/component_encryption_udf/r/digests_sanity.result diff --git a/mysql-test/suite/component_encryption_udf/r/dsa_1024.result b/mysql-test/suite/component_encryption_udf/r/dsa_1024.result new file mode 100644 index 000000000000..6666058f49db --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/dsa_1024.result @@ -0,0 +1,13 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [DSA] checking asymmetric algorithm functions +** [DSA][1024] checking asymmetric algorithm functions +**** [DSA][1024] generating private key +**** [DSA][1024] deriving public key +**** [DSA][1024][message_len=0] checking sign/verify operations +**** [DSA][1024][message_len=1] checking sign/verify operations +**** [DSA][1024][message_len=64] checking sign/verify operations +**** [DSA][1024][message_len=128] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/suite/component_encryption_udf/r/dsa_1024_ext.result b/mysql-test/suite/component_encryption_udf/r/dsa_1024_ext.result new file mode 100644 index 000000000000..b975a6c8bf59 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/dsa_1024_ext.result @@ -0,0 +1,13 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [DSA] checking asymmetric algorithm functions +** [DSA][1024] checking asymmetric algorithm functions +**** [DSA][1024] generating private key with openssl binary +**** [DSA][1024] deriving public key with openssl binary +**** [DSA][1024][message_len=0] checking sign/verify operations +**** [DSA][1024][message_len=1] checking sign/verify operations +**** [DSA][1024][message_len=64] checking sign/verify operations +**** [DSA][1024][message_len=128] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/suite/component_encryption_udf/r/dsa_4096.result b/mysql-test/suite/component_encryption_udf/r/dsa_4096.result new file mode 100644 index 000000000000..4baaec41cfc0 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/dsa_4096.result @@ -0,0 +1,13 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [DSA] checking asymmetric algorithm functions +** [DSA][4096] checking asymmetric algorithm functions +**** [DSA][4096] generating private key +**** [DSA][4096] deriving public key +**** [DSA][4096][message_len=0] checking sign/verify operations +**** [DSA][4096][message_len=1] checking sign/verify operations +**** [DSA][4096][message_len=256] checking sign/verify operations +**** [DSA][4096][message_len=512] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/suite/component_encryption_udf/r/dsa_4096_ext.result b/mysql-test/suite/component_encryption_udf/r/dsa_4096_ext.result new file mode 100644 index 000000000000..8c5a4230f458 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/dsa_4096_ext.result @@ -0,0 +1,13 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [DSA] checking asymmetric algorithm functions +** [DSA][4096] checking asymmetric algorithm functions +**** [DSA][4096] generating private key with openssl binary +**** [DSA][4096] deriving public key with openssl binary +**** [DSA][4096][message_len=0] checking sign/verify operations +**** [DSA][4096][message_len=1] checking sign/verify operations +**** [DSA][4096][message_len=256] checking sign/verify operations +**** [DSA][4096][message_len=512] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/suite/component_encryption_udf/r/dsa_9984.result b/mysql-test/suite/component_encryption_udf/r/dsa_9984.result new file mode 100644 index 000000000000..ff4fe4df286a --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/dsa_9984.result @@ -0,0 +1,13 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [DSA] checking asymmetric algorithm functions +** [DSA][9984] checking asymmetric algorithm functions +**** [DSA][9984] generating private key +**** [DSA][9984] deriving public key +**** [DSA][9984][message_len=0] checking sign/verify operations +**** [DSA][9984][message_len=1] checking sign/verify operations +**** [DSA][9984][message_len=624] checking sign/verify operations +**** [DSA][9984][message_len=1248] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/suite/component_encryption_udf/r/dsa_9984_ext.result b/mysql-test/suite/component_encryption_udf/r/dsa_9984_ext.result new file mode 100644 index 000000000000..278f57359263 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/dsa_9984_ext.result @@ -0,0 +1,13 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [DSA] checking asymmetric algorithm functions +** [DSA][9984] checking asymmetric algorithm functions +**** [DSA][9984] generating private key with openssl binary +**** [DSA][9984] deriving public key with openssl binary +**** [DSA][9984][message_len=0] checking sign/verify operations +**** [DSA][9984][message_len=1] checking sign/verify operations +**** [DSA][9984][message_len=624] checking sign/verify operations +**** [DSA][9984][message_len=1248] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_kill_debug.result b/mysql-test/suite/component_encryption_udf/r/kill_debug.result similarity index 100% rename from mysql-test/r/percona_encryption_udf_kill_debug.result rename to mysql-test/suite/component_encryption_udf/r/kill_debug.result diff --git a/mysql-test/suite/component_encryption_udf/r/legacy_padding_scheme.result b/mysql-test/suite/component_encryption_udf/r/legacy_padding_scheme.result new file mode 100644 index 000000000000..05da3d1b513d --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/legacy_padding_scheme.result @@ -0,0 +1,77 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; +** +** checking legacy_padding_scheme +include/assert.inc [default legacy_padding_scheme must be OFF] +SET SESSION encryption_udf.legacy_padding_scheme = ON; +ERROR HY000: Variable 'encryption_udf.legacy_padding_scheme' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@session.encryption_udf.legacy_padding_scheme; +ERROR HY000: Variable 'encryption_udf.legacy_padding_scheme' is a GLOBAL variable +SET @algorithm = 'RSA'; +SET @priv_key = create_asymmetric_priv_key(@algorithm, 1024); +SET @pub_key = create_asymmetric_pub_key(@algorithm, @priv_key); +SET @message = 'secret_message'; +** +** checking explicit/implicit padding scheme for RSA encrypt/decrypt +SET @encrypted_message_oaep_explicit = asymmetric_encrypt(@algorithm, @message, @pub_key, 'oaep'); +SET @encrypted_message_pkcs1_explicit = asymmetric_encrypt(@algorithm, @message, @pub_key, 'pkcs1'); +SET @encrypted_message_oaep_imlicit = asymmetric_encrypt(@algorithm, @message, @pub_key); +SET GLOBAL encryption_udf.legacy_padding_scheme = ON; +SET @encrypted_message_pkcs1_imlicit = asymmetric_encrypt(@algorithm, @message, @pub_key); +SET GLOBAL encryption_udf.legacy_padding_scheme = OFF; +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_oaep_imlicit, @priv_key, 'oaep'); +include/assert.inc [decrypting @encrypted_message_oaep_imlicit with 'oaep' scheme specified explicitly must succeed] +SET @decrypted_message = ''; +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_pkcs1_imlicit, @priv_key, 'oaep'); +include/assert.inc [decrypting @encrypted_message_pkcs1_imlicit with 'oaep' scheme specified explicitly must fail] +SET @decrypted_message = ''; +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_oaep_imlicit, @priv_key, 'pkcs1'); +include/assert.inc [decrypting @encrypted_message_oaep_imlicit with 'pkcs1' scheme specified explicitly must fail] +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_pkcs1_imlicit, @priv_key, 'pkcs1'); +include/assert.inc [decrypting @encrypted_message_pkcs1_imlicit with 'pkcs1' scheme specified explicitly must succeed] +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_oaep_explicit, @priv_key); +include/assert.inc [decrypting @encrypted_message_oaep_explicit with 'oaep' scheme specified implicitly must succeed] +SET @decrypted_message = ''; +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_pkcs1_explicit, @priv_key); +include/assert.inc [decrypting @encrypted_message_pkcs1_explicit with 'oaep' scheme specified implicitly must fail] +SET GLOBAL encryption_udf.legacy_padding_scheme = ON; +SET @decrypted_message = ''; +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_oaep_explicit, @priv_key); +include/assert.inc [decrypting @encrypted_message_oaep_explicit with 'pkcs1' scheme specified implicitly must fail] +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_pkcs1_explicit, @priv_key); +include/assert.inc [decrypting @encrypted_message_pkcs1_explicit with 'pkcs1' scheme specified implicitly must succeed] +SET GLOBAL encryption_udf.legacy_padding_scheme = OFF; +** +** checking explicit/implicit padding scheme for RSA sign/verify +SET @digest_type = 'SHA256'; +SET @message_digest = create_digest(@digest_type, @message); +SET @signature_pkcs1_pss_explicit = asymmetric_sign(@algorithm, @message_digest, @priv_key, @digest_type, 'pkcs1_pss'); +SET @signature_pkcs1_explicit = asymmetric_sign(@algorithm, @message_digest, @priv_key, @digest_type, 'pkcs1'); +SET @signature_pkcs1_pss_imlicit = asymmetric_sign(@algorithm, @message_digest, @priv_key, @digest_type); +SET GLOBAL encryption_udf.legacy_padding_scheme = ON; +SET @signature_pkcs1_imlicit = asymmetric_sign(@algorithm, @message_digest, @priv_key, @digest_type); +SET GLOBAL encryption_udf.legacy_padding_scheme = OFF; +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_pss_imlicit, @pub_key, @digest_type, 'pkcs1_pss'); +include/assert.inc [verifying @signature_pkcs1_pss_imlicit with 'pkcs1_pss' scheme specified explicitly must succeed] +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_imlicit, @pub_key, @digest_type, 'pkcs1_pss'); +include/assert.inc [verifying @signature_pkcs1_imlicit with 'pkcs1_pss' scheme specified explicitly must fail] +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_pss_imlicit, @pub_key, @digest_type, 'pkcs1'); +include/assert.inc [verifying @signature_pkcs1_pss_imlicit with 'pkcs1' specified explicitly scheme must fail] +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_imlicit, @pub_key, @digest_type, 'pkcs1'); +include/assert.inc [verifying @signature_pkcs1_imlicit with 'pkcs1' specified explicitly scheme must succeed] +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_pss_explicit, @pub_key, @digest_type); +include/assert.inc [verifying @signature_pkcs1_pss_explicit with 'pkcs1_pss' scheme specified implicitly must succeed] +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_explicit, @pub_key, @digest_type); +include/assert.inc [verifying @signature_pkcs1_explicit with 'pkcs1_pss' scheme specified implicitly must fail] +SET GLOBAL encryption_udf.legacy_padding_scheme = ON; +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_pss_explicit, @pub_key, @digest_type); +include/assert.inc [verifying @signature_pkcs1_pss_explicit with 'pkcs1' specified implicitly scheme must fail] +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_explicit, @pub_key, @digest_type); +include/assert.inc [verifying @signature_pkcs1_explicit with 'pkcs1' specified implicitly scheme must succeed] +SET GLOBAL encryption_udf.legacy_padding_scheme = OFF; +** +** checking that non-privileged users cannot change legacy_padding_scheme variables +CREATE USER 'usr' IDENTIFIED BY 'password'; +SET GLOBAL encryption_udf.legacy_padding_scheme = ON; +ERROR 42000: Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation +DROP USER 'usr'; +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/suite/component_encryption_udf/r/rsa_1024.result b/mysql-test/suite/component_encryption_udf/r/rsa_1024.result new file mode 100644 index 000000000000..40734f7bd752 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/rsa_1024.result @@ -0,0 +1,80 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [RSA] checking asymmetric algorithm functions +** [RSA][1024] checking asymmetric algorithm functions +**** [RSA][1024] generating private key +**** [RSA][1024] deriving public key +**** [RSA][1024][no] checking encrypt/decrypt operations on NULL message +****** [RSA][1024][no] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][1024][no] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][1024][no] checking encrypt/decrypt operations on oversize message +****** [RSA][1024][no] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][1024][no] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][1024][no][message_len=128] checking encrypt/decrypt operations +****** [RSA][1024][no][message_len=128] checking encryption with public key +****** [RSA][1024][no][message_len=128] checking decryption with private key +****** [RSA][1024][no][message_len=128] checking encryption with private key +****** [RSA][1024][no][message_len=128] checking decryption with public key +**** [RSA][1024][pkcs1] checking encrypt/decrypt operations on NULL message +****** [RSA][1024][pkcs1] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][1024][pkcs1] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][1024][pkcs1] checking encrypt/decrypt operations on oversize message +****** [RSA][1024][pkcs1] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][1024][pkcs1] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][1024][pkcs1][message_len=0] checking encrypt/decrypt operations +****** [RSA][1024][pkcs1][message_len=0] checking encryption with public key +****** [RSA][1024][pkcs1][message_len=0] checking decryption with private key +****** [RSA][1024][pkcs1][message_len=0] checking encryption with private key +****** [RSA][1024][pkcs1][message_len=0] checking decryption with public key +**** [RSA][1024][pkcs1][message_len=1] checking encrypt/decrypt operations +****** [RSA][1024][pkcs1][message_len=1] checking encryption with public key +****** [RSA][1024][pkcs1][message_len=1] checking decryption with private key +****** [RSA][1024][pkcs1][message_len=1] checking encryption with private key +****** [RSA][1024][pkcs1][message_len=1] checking decryption with public key +**** [RSA][1024][pkcs1][message_len=58] checking encrypt/decrypt operations +****** [RSA][1024][pkcs1][message_len=58] checking encryption with public key +****** [RSA][1024][pkcs1][message_len=58] checking decryption with private key +****** [RSA][1024][pkcs1][message_len=58] checking encryption with private key +****** [RSA][1024][pkcs1][message_len=58] checking decryption with public key +**** [RSA][1024][pkcs1][message_len=117] checking encrypt/decrypt operations +****** [RSA][1024][pkcs1][message_len=117] checking encryption with public key +****** [RSA][1024][pkcs1][message_len=117] checking decryption with private key +****** [RSA][1024][pkcs1][message_len=117] checking encryption with private key +****** [RSA][1024][pkcs1][message_len=117] checking decryption with public key +**** [RSA][1024][oaep] checking encrypt/decrypt operations on NULL message +****** [RSA][1024][oaep] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][1024][oaep] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][1024][oaep] checking encrypt/decrypt operations on oversize message +****** [RSA][1024][oaep] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][1024][oaep] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encrypting with RSA private key is not supported for PKCS1 OAEP padding +**** [RSA][1024][oaep][message_len=0] checking encrypt/decrypt operations +****** [RSA][1024][oaep][message_len=0] checking encryption with public key +****** [RSA][1024][oaep][message_len=0] checking decryption with private key +**** [RSA][1024][oaep][message_len=1] checking encrypt/decrypt operations +****** [RSA][1024][oaep][message_len=1] checking encryption with public key +****** [RSA][1024][oaep][message_len=1] checking decryption with private key +**** [RSA][1024][oaep][message_len=43] checking encrypt/decrypt operations +****** [RSA][1024][oaep][message_len=43] checking encryption with public key +****** [RSA][1024][oaep][message_len=43] checking decryption with private key +**** [RSA][1024][oaep][message_len=86] checking encrypt/decrypt operations +****** [RSA][1024][oaep][message_len=86] checking encryption with public key +****** [RSA][1024][oaep][message_len=86] checking decryption with private key +**** [RSA][1024][message_len=0] checking sign/verify operations +**** [RSA][1024][message_len=1] checking sign/verify operations +**** [RSA][1024][message_len=64] checking sign/verify operations +**** [RSA][1024][message_len=128] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/suite/component_encryption_udf/r/rsa_1024_ext.result b/mysql-test/suite/component_encryption_udf/r/rsa_1024_ext.result new file mode 100644 index 000000000000..5049dd7e5660 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/rsa_1024_ext.result @@ -0,0 +1,80 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [RSA] checking asymmetric algorithm functions +** [RSA][1024] checking asymmetric algorithm functions +**** [RSA][1024] generating private key with openssl binary +**** [RSA][1024] deriving public key with openssl binary +**** [RSA][1024][no] checking encrypt/decrypt operations on NULL message +****** [RSA][1024][no] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][1024][no] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][1024][no] checking encrypt/decrypt operations on oversize message +****** [RSA][1024][no] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][1024][no] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][1024][no][message_len=128] checking encrypt/decrypt operations +****** [RSA][1024][no][message_len=128] checking encryption with public key +****** [RSA][1024][no][message_len=128] checking decryption with private key +****** [RSA][1024][no][message_len=128] checking encryption with private key +****** [RSA][1024][no][message_len=128] checking decryption with public key +**** [RSA][1024][pkcs1] checking encrypt/decrypt operations on NULL message +****** [RSA][1024][pkcs1] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][1024][pkcs1] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][1024][pkcs1] checking encrypt/decrypt operations on oversize message +****** [RSA][1024][pkcs1] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][1024][pkcs1] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][1024][pkcs1][message_len=0] checking encrypt/decrypt operations +****** [RSA][1024][pkcs1][message_len=0] checking encryption with public key +****** [RSA][1024][pkcs1][message_len=0] checking decryption with private key +****** [RSA][1024][pkcs1][message_len=0] checking encryption with private key +****** [RSA][1024][pkcs1][message_len=0] checking decryption with public key +**** [RSA][1024][pkcs1][message_len=1] checking encrypt/decrypt operations +****** [RSA][1024][pkcs1][message_len=1] checking encryption with public key +****** [RSA][1024][pkcs1][message_len=1] checking decryption with private key +****** [RSA][1024][pkcs1][message_len=1] checking encryption with private key +****** [RSA][1024][pkcs1][message_len=1] checking decryption with public key +**** [RSA][1024][pkcs1][message_len=58] checking encrypt/decrypt operations +****** [RSA][1024][pkcs1][message_len=58] checking encryption with public key +****** [RSA][1024][pkcs1][message_len=58] checking decryption with private key +****** [RSA][1024][pkcs1][message_len=58] checking encryption with private key +****** [RSA][1024][pkcs1][message_len=58] checking decryption with public key +**** [RSA][1024][pkcs1][message_len=117] checking encrypt/decrypt operations +****** [RSA][1024][pkcs1][message_len=117] checking encryption with public key +****** [RSA][1024][pkcs1][message_len=117] checking decryption with private key +****** [RSA][1024][pkcs1][message_len=117] checking encryption with private key +****** [RSA][1024][pkcs1][message_len=117] checking decryption with public key +**** [RSA][1024][oaep] checking encrypt/decrypt operations on NULL message +****** [RSA][1024][oaep] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][1024][oaep] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][1024][oaep] checking encrypt/decrypt operations on oversize message +****** [RSA][1024][oaep] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][1024][oaep] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encrypting with RSA private key is not supported for PKCS1 OAEP padding +**** [RSA][1024][oaep][message_len=0] checking encrypt/decrypt operations +****** [RSA][1024][oaep][message_len=0] checking encryption with public key +****** [RSA][1024][oaep][message_len=0] checking decryption with private key +**** [RSA][1024][oaep][message_len=1] checking encrypt/decrypt operations +****** [RSA][1024][oaep][message_len=1] checking encryption with public key +****** [RSA][1024][oaep][message_len=1] checking decryption with private key +**** [RSA][1024][oaep][message_len=43] checking encrypt/decrypt operations +****** [RSA][1024][oaep][message_len=43] checking encryption with public key +****** [RSA][1024][oaep][message_len=43] checking decryption with private key +**** [RSA][1024][oaep][message_len=86] checking encrypt/decrypt operations +****** [RSA][1024][oaep][message_len=86] checking encryption with public key +****** [RSA][1024][oaep][message_len=86] checking decryption with private key +**** [RSA][1024][message_len=0] checking sign/verify operations +**** [RSA][1024][message_len=1] checking sign/verify operations +**** [RSA][1024][message_len=64] checking sign/verify operations +**** [RSA][1024][message_len=128] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/suite/component_encryption_udf/r/rsa_16384.result b/mysql-test/suite/component_encryption_udf/r/rsa_16384.result new file mode 100644 index 000000000000..2fce0608d781 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/rsa_16384.result @@ -0,0 +1,80 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [RSA] checking asymmetric algorithm functions +** [RSA][16384] checking asymmetric algorithm functions +**** [RSA][16384] generating private key +**** [RSA][16384] deriving public key +**** [RSA][16384][no] checking encrypt/decrypt operations on NULL message +****** [RSA][16384][no] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][16384][no] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][16384][no] checking encrypt/decrypt operations on oversize message +****** [RSA][16384][no] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][16384][no] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][16384][no][message_len=2048] checking encrypt/decrypt operations +****** [RSA][16384][no][message_len=2048] checking encryption with public key +****** [RSA][16384][no][message_len=2048] checking decryption with private key +****** [RSA][16384][no][message_len=2048] checking encryption with private key +****** [RSA][16384][no][message_len=2048] checking decryption with public key +**** [RSA][16384][pkcs1] checking encrypt/decrypt operations on NULL message +****** [RSA][16384][pkcs1] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][16384][pkcs1] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][16384][pkcs1] checking encrypt/decrypt operations on oversize message +****** [RSA][16384][pkcs1] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][16384][pkcs1] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][16384][pkcs1][message_len=0] checking encrypt/decrypt operations +****** [RSA][16384][pkcs1][message_len=0] checking encryption with public key +****** [RSA][16384][pkcs1][message_len=0] checking decryption with private key +****** [RSA][16384][pkcs1][message_len=0] checking encryption with private key +****** [RSA][16384][pkcs1][message_len=0] checking decryption with public key +**** [RSA][16384][pkcs1][message_len=1] checking encrypt/decrypt operations +****** [RSA][16384][pkcs1][message_len=1] checking encryption with public key +****** [RSA][16384][pkcs1][message_len=1] checking decryption with private key +****** [RSA][16384][pkcs1][message_len=1] checking encryption with private key +****** [RSA][16384][pkcs1][message_len=1] checking decryption with public key +**** [RSA][16384][pkcs1][message_len=1018] checking encrypt/decrypt operations +****** [RSA][16384][pkcs1][message_len=1018] checking encryption with public key +****** [RSA][16384][pkcs1][message_len=1018] checking decryption with private key +****** [RSA][16384][pkcs1][message_len=1018] checking encryption with private key +****** [RSA][16384][pkcs1][message_len=1018] checking decryption with public key +**** [RSA][16384][pkcs1][message_len=2037] checking encrypt/decrypt operations +****** [RSA][16384][pkcs1][message_len=2037] checking encryption with public key +****** [RSA][16384][pkcs1][message_len=2037] checking decryption with private key +****** [RSA][16384][pkcs1][message_len=2037] checking encryption with private key +****** [RSA][16384][pkcs1][message_len=2037] checking decryption with public key +**** [RSA][16384][oaep] checking encrypt/decrypt operations on NULL message +****** [RSA][16384][oaep] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][16384][oaep] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][16384][oaep] checking encrypt/decrypt operations on oversize message +****** [RSA][16384][oaep] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][16384][oaep] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encrypting with RSA private key is not supported for PKCS1 OAEP padding +**** [RSA][16384][oaep][message_len=0] checking encrypt/decrypt operations +****** [RSA][16384][oaep][message_len=0] checking encryption with public key +****** [RSA][16384][oaep][message_len=0] checking decryption with private key +**** [RSA][16384][oaep][message_len=1] checking encrypt/decrypt operations +****** [RSA][16384][oaep][message_len=1] checking encryption with public key +****** [RSA][16384][oaep][message_len=1] checking decryption with private key +**** [RSA][16384][oaep][message_len=1003] checking encrypt/decrypt operations +****** [RSA][16384][oaep][message_len=1003] checking encryption with public key +****** [RSA][16384][oaep][message_len=1003] checking decryption with private key +**** [RSA][16384][oaep][message_len=2006] checking encrypt/decrypt operations +****** [RSA][16384][oaep][message_len=2006] checking encryption with public key +****** [RSA][16384][oaep][message_len=2006] checking decryption with private key +**** [RSA][16384][message_len=0] checking sign/verify operations +**** [RSA][16384][message_len=1] checking sign/verify operations +**** [RSA][16384][message_len=1024] checking sign/verify operations +**** [RSA][16384][message_len=2048] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/suite/component_encryption_udf/r/rsa_16384_ext.result b/mysql-test/suite/component_encryption_udf/r/rsa_16384_ext.result new file mode 100644 index 000000000000..8f3e0b7cfd81 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/rsa_16384_ext.result @@ -0,0 +1,80 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [RSA] checking asymmetric algorithm functions +** [RSA][16384] checking asymmetric algorithm functions +**** [RSA][16384] generating private key with openssl binary +**** [RSA][16384] deriving public key with openssl binary +**** [RSA][16384][no] checking encrypt/decrypt operations on NULL message +****** [RSA][16384][no] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][16384][no] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][16384][no] checking encrypt/decrypt operations on oversize message +****** [RSA][16384][no] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][16384][no] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][16384][no][message_len=2048] checking encrypt/decrypt operations +****** [RSA][16384][no][message_len=2048] checking encryption with public key +****** [RSA][16384][no][message_len=2048] checking decryption with private key +****** [RSA][16384][no][message_len=2048] checking encryption with private key +****** [RSA][16384][no][message_len=2048] checking decryption with public key +**** [RSA][16384][pkcs1] checking encrypt/decrypt operations on NULL message +****** [RSA][16384][pkcs1] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][16384][pkcs1] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][16384][pkcs1] checking encrypt/decrypt operations on oversize message +****** [RSA][16384][pkcs1] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][16384][pkcs1] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][16384][pkcs1][message_len=0] checking encrypt/decrypt operations +****** [RSA][16384][pkcs1][message_len=0] checking encryption with public key +****** [RSA][16384][pkcs1][message_len=0] checking decryption with private key +****** [RSA][16384][pkcs1][message_len=0] checking encryption with private key +****** [RSA][16384][pkcs1][message_len=0] checking decryption with public key +**** [RSA][16384][pkcs1][message_len=1] checking encrypt/decrypt operations +****** [RSA][16384][pkcs1][message_len=1] checking encryption with public key +****** [RSA][16384][pkcs1][message_len=1] checking decryption with private key +****** [RSA][16384][pkcs1][message_len=1] checking encryption with private key +****** [RSA][16384][pkcs1][message_len=1] checking decryption with public key +**** [RSA][16384][pkcs1][message_len=1018] checking encrypt/decrypt operations +****** [RSA][16384][pkcs1][message_len=1018] checking encryption with public key +****** [RSA][16384][pkcs1][message_len=1018] checking decryption with private key +****** [RSA][16384][pkcs1][message_len=1018] checking encryption with private key +****** [RSA][16384][pkcs1][message_len=1018] checking decryption with public key +**** [RSA][16384][pkcs1][message_len=2037] checking encrypt/decrypt operations +****** [RSA][16384][pkcs1][message_len=2037] checking encryption with public key +****** [RSA][16384][pkcs1][message_len=2037] checking decryption with private key +****** [RSA][16384][pkcs1][message_len=2037] checking encryption with private key +****** [RSA][16384][pkcs1][message_len=2037] checking decryption with public key +**** [RSA][16384][oaep] checking encrypt/decrypt operations on NULL message +****** [RSA][16384][oaep] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][16384][oaep] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][16384][oaep] checking encrypt/decrypt operations on oversize message +****** [RSA][16384][oaep] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][16384][oaep] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encrypting with RSA private key is not supported for PKCS1 OAEP padding +**** [RSA][16384][oaep][message_len=0] checking encrypt/decrypt operations +****** [RSA][16384][oaep][message_len=0] checking encryption with public key +****** [RSA][16384][oaep][message_len=0] checking decryption with private key +**** [RSA][16384][oaep][message_len=1] checking encrypt/decrypt operations +****** [RSA][16384][oaep][message_len=1] checking encryption with public key +****** [RSA][16384][oaep][message_len=1] checking decryption with private key +**** [RSA][16384][oaep][message_len=1003] checking encrypt/decrypt operations +****** [RSA][16384][oaep][message_len=1003] checking encryption with public key +****** [RSA][16384][oaep][message_len=1003] checking decryption with private key +**** [RSA][16384][oaep][message_len=2006] checking encrypt/decrypt operations +****** [RSA][16384][oaep][message_len=2006] checking encryption with public key +****** [RSA][16384][oaep][message_len=2006] checking decryption with private key +**** [RSA][16384][message_len=0] checking sign/verify operations +**** [RSA][16384][message_len=1] checking sign/verify operations +**** [RSA][16384][message_len=1024] checking sign/verify operations +**** [RSA][16384][message_len=2048] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/suite/component_encryption_udf/r/rsa_4096.result b/mysql-test/suite/component_encryption_udf/r/rsa_4096.result new file mode 100644 index 000000000000..4e0b0aef7803 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/rsa_4096.result @@ -0,0 +1,80 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [RSA] checking asymmetric algorithm functions +** [RSA][4096] checking asymmetric algorithm functions +**** [RSA][4096] generating private key +**** [RSA][4096] deriving public key +**** [RSA][4096][no] checking encrypt/decrypt operations on NULL message +****** [RSA][4096][no] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][4096][no] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][4096][no] checking encrypt/decrypt operations on oversize message +****** [RSA][4096][no] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][4096][no] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][4096][no][message_len=512] checking encrypt/decrypt operations +****** [RSA][4096][no][message_len=512] checking encryption with public key +****** [RSA][4096][no][message_len=512] checking decryption with private key +****** [RSA][4096][no][message_len=512] checking encryption with private key +****** [RSA][4096][no][message_len=512] checking decryption with public key +**** [RSA][4096][pkcs1] checking encrypt/decrypt operations on NULL message +****** [RSA][4096][pkcs1] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][4096][pkcs1] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][4096][pkcs1] checking encrypt/decrypt operations on oversize message +****** [RSA][4096][pkcs1] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][4096][pkcs1] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][4096][pkcs1][message_len=0] checking encrypt/decrypt operations +****** [RSA][4096][pkcs1][message_len=0] checking encryption with public key +****** [RSA][4096][pkcs1][message_len=0] checking decryption with private key +****** [RSA][4096][pkcs1][message_len=0] checking encryption with private key +****** [RSA][4096][pkcs1][message_len=0] checking decryption with public key +**** [RSA][4096][pkcs1][message_len=1] checking encrypt/decrypt operations +****** [RSA][4096][pkcs1][message_len=1] checking encryption with public key +****** [RSA][4096][pkcs1][message_len=1] checking decryption with private key +****** [RSA][4096][pkcs1][message_len=1] checking encryption with private key +****** [RSA][4096][pkcs1][message_len=1] checking decryption with public key +**** [RSA][4096][pkcs1][message_len=250] checking encrypt/decrypt operations +****** [RSA][4096][pkcs1][message_len=250] checking encryption with public key +****** [RSA][4096][pkcs1][message_len=250] checking decryption with private key +****** [RSA][4096][pkcs1][message_len=250] checking encryption with private key +****** [RSA][4096][pkcs1][message_len=250] checking decryption with public key +**** [RSA][4096][pkcs1][message_len=501] checking encrypt/decrypt operations +****** [RSA][4096][pkcs1][message_len=501] checking encryption with public key +****** [RSA][4096][pkcs1][message_len=501] checking decryption with private key +****** [RSA][4096][pkcs1][message_len=501] checking encryption with private key +****** [RSA][4096][pkcs1][message_len=501] checking decryption with public key +**** [RSA][4096][oaep] checking encrypt/decrypt operations on NULL message +****** [RSA][4096][oaep] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][4096][oaep] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][4096][oaep] checking encrypt/decrypt operations on oversize message +****** [RSA][4096][oaep] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][4096][oaep] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encrypting with RSA private key is not supported for PKCS1 OAEP padding +**** [RSA][4096][oaep][message_len=0] checking encrypt/decrypt operations +****** [RSA][4096][oaep][message_len=0] checking encryption with public key +****** [RSA][4096][oaep][message_len=0] checking decryption with private key +**** [RSA][4096][oaep][message_len=1] checking encrypt/decrypt operations +****** [RSA][4096][oaep][message_len=1] checking encryption with public key +****** [RSA][4096][oaep][message_len=1] checking decryption with private key +**** [RSA][4096][oaep][message_len=235] checking encrypt/decrypt operations +****** [RSA][4096][oaep][message_len=235] checking encryption with public key +****** [RSA][4096][oaep][message_len=235] checking decryption with private key +**** [RSA][4096][oaep][message_len=470] checking encrypt/decrypt operations +****** [RSA][4096][oaep][message_len=470] checking encryption with public key +****** [RSA][4096][oaep][message_len=470] checking decryption with private key +**** [RSA][4096][message_len=0] checking sign/verify operations +**** [RSA][4096][message_len=1] checking sign/verify operations +**** [RSA][4096][message_len=256] checking sign/verify operations +**** [RSA][4096][message_len=512] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/suite/component_encryption_udf/r/rsa_4096_ext.result b/mysql-test/suite/component_encryption_udf/r/rsa_4096_ext.result new file mode 100644 index 000000000000..0d6e52f27423 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/r/rsa_4096_ext.result @@ -0,0 +1,80 @@ +INSTALL COMPONENT 'file://component_encryption_udf'; + +** checking private key generation, public key derivation, encryption/decryption and sign/verify functionality + +** [RSA] checking asymmetric algorithm functions +** [RSA][4096] checking asymmetric algorithm functions +**** [RSA][4096] generating private key with openssl binary +**** [RSA][4096] deriving public key with openssl binary +**** [RSA][4096][no] checking encrypt/decrypt operations on NULL message +****** [RSA][4096][no] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][4096][no] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][4096][no] checking encrypt/decrypt operations on oversize message +****** [RSA][4096][no] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][4096][no] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][4096][no][message_len=512] checking encrypt/decrypt operations +****** [RSA][4096][no][message_len=512] checking encryption with public key +****** [RSA][4096][no][message_len=512] checking decryption with private key +****** [RSA][4096][no][message_len=512] checking encryption with private key +****** [RSA][4096][no][message_len=512] checking decryption with public key +**** [RSA][4096][pkcs1] checking encrypt/decrypt operations on NULL message +****** [RSA][4096][pkcs1] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][4096][pkcs1] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][4096][pkcs1] checking encrypt/decrypt operations on oversize message +****** [RSA][4096][pkcs1] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][4096][pkcs1] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +**** [RSA][4096][pkcs1][message_len=0] checking encrypt/decrypt operations +****** [RSA][4096][pkcs1][message_len=0] checking encryption with public key +****** [RSA][4096][pkcs1][message_len=0] checking decryption with private key +****** [RSA][4096][pkcs1][message_len=0] checking encryption with private key +****** [RSA][4096][pkcs1][message_len=0] checking decryption with public key +**** [RSA][4096][pkcs1][message_len=1] checking encrypt/decrypt operations +****** [RSA][4096][pkcs1][message_len=1] checking encryption with public key +****** [RSA][4096][pkcs1][message_len=1] checking decryption with private key +****** [RSA][4096][pkcs1][message_len=1] checking encryption with private key +****** [RSA][4096][pkcs1][message_len=1] checking decryption with public key +**** [RSA][4096][pkcs1][message_len=250] checking encrypt/decrypt operations +****** [RSA][4096][pkcs1][message_len=250] checking encryption with public key +****** [RSA][4096][pkcs1][message_len=250] checking decryption with private key +****** [RSA][4096][pkcs1][message_len=250] checking encryption with private key +****** [RSA][4096][pkcs1][message_len=250] checking decryption with public key +**** [RSA][4096][pkcs1][message_len=501] checking encrypt/decrypt operations +****** [RSA][4096][pkcs1][message_len=501] checking encryption with public key +****** [RSA][4096][pkcs1][message_len=501] checking decryption with private key +****** [RSA][4096][pkcs1][message_len=501] checking encryption with private key +****** [RSA][4096][pkcs1][message_len=501] checking decryption with public key +**** [RSA][4096][oaep] checking encrypt/decrypt operations on NULL message +****** [RSA][4096][oaep] checking encryption with public key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +****** [RSA][4096][oaep] checking encryption with private key of NULL message +ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +**** [RSA][4096][oaep] checking encrypt/decrypt operations on oversize message +****** [RSA][4096][oaep] checking encryption of oversize message with public key +ERROR HY000: asymmetric_encrypt UDF failed; encryption block size is too long for the specified padding and RSA key +****** [RSA][4096][oaep] checking encryption of oversize message with private key +ERROR HY000: asymmetric_encrypt UDF failed; encrypting with RSA private key is not supported for PKCS1 OAEP padding +**** [RSA][4096][oaep][message_len=0] checking encrypt/decrypt operations +****** [RSA][4096][oaep][message_len=0] checking encryption with public key +****** [RSA][4096][oaep][message_len=0] checking decryption with private key +**** [RSA][4096][oaep][message_len=1] checking encrypt/decrypt operations +****** [RSA][4096][oaep][message_len=1] checking encryption with public key +****** [RSA][4096][oaep][message_len=1] checking decryption with private key +**** [RSA][4096][oaep][message_len=235] checking encrypt/decrypt operations +****** [RSA][4096][oaep][message_len=235] checking encryption with public key +****** [RSA][4096][oaep][message_len=235] checking decryption with private key +**** [RSA][4096][oaep][message_len=470] checking encrypt/decrypt operations +****** [RSA][4096][oaep][message_len=470] checking encryption with public key +****** [RSA][4096][oaep][message_len=470] checking decryption with private key +**** [RSA][4096][message_len=0] checking sign/verify operations +**** [RSA][4096][message_len=1] checking sign/verify operations +**** [RSA][4096][message_len=256] checking sign/verify operations +**** [RSA][4096][message_len=512] checking sign/verify operations +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/r/percona_encryption_udf_xsa_sanity.result b/mysql-test/suite/component_encryption_udf/r/xsa_sanity.result similarity index 68% rename from mysql-test/r/percona_encryption_udf_xsa_sanity.result rename to mysql-test/suite/component_encryption_udf/r/xsa_sanity.result index 0d81ca02e246..e1b77bcf2368 100644 --- a/mysql-test/r/percona_encryption_udf_xsa_sanity.result +++ b/mysql-test/suite/component_encryption_udf/r/xsa_sanity.result @@ -33,19 +33,23 @@ ERROR HY000: Can't initialize function 'create_asymmetric_pub_key'; Function req SELECT create_asymmetric_pub_key(@algorithm, NULL); ERROR HY000: create_asymmetric_pub_key UDF failed; argument 2 cannot be null SELECT create_asymmetric_pub_key(@algorithm, 42); -ERROR HY000: create_asymmetric_pub_key UDF failed; cannot import RSA key from PEM PRIVATE KEY +ERROR HY000: create_asymmetric_pub_key UDF failed; cannot import EVP_PKEY from PEM PRIVATE KEY SELECT create_asymmetric_pub_key(@algorithm, 'blah-blah'); -ERROR HY000: create_asymmetric_pub_key UDF failed; cannot import RSA key from PEM PRIVATE KEY +ERROR HY000: create_asymmetric_pub_key UDF failed; cannot import EVP_PKEY from PEM PRIVATE KEY SELECT create_asymmetric_priv_key('FOO', 2048); ERROR HY000: create_asymmetric_priv_key UDF failed; Invalid algorithm specified +** creating sample key pair +SET @priv = create_asymmetric_priv_key(@algorithm, 1024); +SET @pub = create_asymmetric_pub_key(@algorithm, @priv); + ** checking 'asymmetric_encrypt()' function basics SELECT asymmetric_encrypt(); -ERROR HY000: Can't initialize function 'asymmetric_encrypt'; Function requires exactly three arguments +ERROR HY000: Can't initialize function 'asymmetric_encrypt'; Function requires three or four arguments SELECT asymmetric_encrypt(@algorithm); -ERROR HY000: Can't initialize function 'asymmetric_encrypt'; Function requires exactly three arguments +ERROR HY000: Can't initialize function 'asymmetric_encrypt'; Function requires three or four arguments SELECT asymmetric_encrypt(@algorithm, @message); -ERROR HY000: Can't initialize function 'asymmetric_encrypt'; Function requires exactly three arguments +ERROR HY000: Can't initialize function 'asymmetric_encrypt'; Function requires three or four arguments SELECT asymmetric_encrypt(@algorithm, @message, NULL); ERROR HY000: asymmetric_encrypt UDF failed; argument 3 cannot be null SELECT asymmetric_encrypt(@algorithm, @message, 42); @@ -54,14 +58,24 @@ SELECT asymmetric_encrypt(@algorithm, @message, 'blah-blah'); ERROR HY000: asymmetric_encrypt UDF failed; cannot import RSA key from PEM PUBLIC KEY SELECT asymmetric_encrypt(@algorithm, NULL, NULL); ERROR HY000: asymmetric_encrypt UDF failed; argument 2 cannot be null +SELECT asymmetric_encrypt(@algorithm, @message, @pub, NULL); +ERROR HY000: asymmetric_encrypt UDF failed; argument 4 cannot be null +SELECT asymmetric_encrypt(@algorithm, @message, @pub, ''); +ERROR HY000: asymmetric_encrypt UDF failed; Invalid RSA encryption padding scheme specified +SELECT asymmetric_encrypt(@algorithm, @message, @pub, 'unknown'); +ERROR HY000: asymmetric_encrypt UDF failed; Invalid RSA encryption padding scheme specified +SELECT asymmetric_encrypt(@algorithm, @message, @priv, 'oaep'); +ERROR HY000: asymmetric_encrypt UDF failed; encrypting with RSA private key is not supported for PKCS1 OAEP padding +SELECT asymmetric_encrypt(@algorithm, @message, @pub, 'oaep', ''); +ERROR HY000: Can't initialize function 'asymmetric_encrypt'; Function requires three or four arguments ** checking 'asymmetric_decrypt()' function basics SELECT asymmetric_decrypt(); -ERROR HY000: Can't initialize function 'asymmetric_decrypt'; Function requires exactly three arguments +ERROR HY000: Can't initialize function 'asymmetric_decrypt'; Function requires three or four arguments SELECT asymmetric_decrypt(@algorithm); -ERROR HY000: Can't initialize function 'asymmetric_decrypt'; Function requires exactly three arguments +ERROR HY000: Can't initialize function 'asymmetric_decrypt'; Function requires three or four arguments SELECT asymmetric_decrypt(@algorithm, @message); -ERROR HY000: Can't initialize function 'asymmetric_decrypt'; Function requires exactly three arguments +ERROR HY000: Can't initialize function 'asymmetric_decrypt'; Function requires three or four arguments SELECT asymmetric_decrypt(@algorithm, @message, NULL); ERROR HY000: asymmetric_decrypt UDF failed; argument 3 cannot be null SELECT asymmetric_decrypt(@algorithm, @message, 42); @@ -70,18 +84,29 @@ SELECT asymmetric_decrypt(@algorithm, @message, 'blah-blah'); ERROR HY000: asymmetric_decrypt UDF failed; cannot import RSA key from PEM PUBLIC KEY SELECT asymmetric_decrypt(@algorithm, NULL, NULL); ERROR HY000: asymmetric_decrypt UDF failed; argument 2 cannot be null +SELECT asymmetric_decrypt(@algorithm, @message, @priv, NULL); +ERROR HY000: asymmetric_decrypt UDF failed; argument 4 cannot be null +SELECT asymmetric_decrypt(@algorithm, @message, @priv, ''); +ERROR HY000: asymmetric_decrypt UDF failed; Invalid RSA encryption padding scheme specified +SELECT asymmetric_decrypt(@algorithm, @message, @priv, 'unknown'); +ERROR HY000: asymmetric_decrypt UDF failed; Invalid RSA encryption padding scheme specified +SELECT asymmetric_decrypt(@algorithm, @message, @pub, 'oaep'); +ERROR HY000: asymmetric_decrypt UDF failed; decrypting with RSA public key is not supported for PKCS1 OAEP padding +SELECT asymmetric_decrypt(@algorithm, @message, @priv, 'oaep', ''); +ERROR HY000: Can't initialize function 'asymmetric_decrypt'; Function requires three or four arguments -** checking 'asymmetric_sign()' function basics +** creating sample digest SET @message_digest = create_digest(@digest_type, @message); -SET @priv = create_asymmetric_priv_key(@algorithm, 1024); + +** checking 'asymmetric_sign()' function basics SELECT asymmetric_sign(); -ERROR HY000: Can't initialize function 'asymmetric_sign'; Function requires exactly four arguments +ERROR HY000: Can't initialize function 'asymmetric_sign'; Function requires four or five arguments SELECT asymmetric_sign(@algorithm); -ERROR HY000: Can't initialize function 'asymmetric_sign'; Function requires exactly four arguments +ERROR HY000: Can't initialize function 'asymmetric_sign'; Function requires four or five arguments SELECT asymmetric_sign(@algorithm, @message_digest); -ERROR HY000: Can't initialize function 'asymmetric_sign'; Function requires exactly four arguments +ERROR HY000: Can't initialize function 'asymmetric_sign'; Function requires four or five arguments SELECT asymmetric_sign(@algorithm, @message_digest, @priv); -ERROR HY000: Can't initialize function 'asymmetric_sign'; Function requires exactly four arguments +ERROR HY000: Can't initialize function 'asymmetric_sign'; Function requires four or five arguments SELECT asymmetric_sign(NULL, @message_digest, @priv, @digest_type); ERROR HY000: asymmetric_sign UDF failed; argument 1 cannot be null SELECT asymmetric_sign(42, @message_digest, @priv, @digest_type); @@ -93,29 +118,37 @@ ERROR HY000: asymmetric_sign UDF failed; argument 2 cannot be null SELECT asymmetric_sign(@algorithm, @message_digest, NULL, @digest_type); ERROR HY000: asymmetric_sign UDF failed; argument 3 cannot be null SELECT asymmetric_sign(@algorithm, @message_digest, 42, @digest_type); -ERROR HY000: asymmetric_sign UDF failed; cannot import RSA key from PEM PRIVATE KEY +ERROR HY000: asymmetric_sign UDF failed; cannot import EVP_PKEY from PEM PRIVATE KEY SELECT asymmetric_sign(@algorithm, @message_digest, 'blah-blah', @digest_type); -ERROR HY000: asymmetric_sign UDF failed; cannot import RSA key from PEM PRIVATE KEY +ERROR HY000: asymmetric_sign UDF failed; cannot import EVP_PKEY from PEM PRIVATE KEY SELECT asymmetric_sign(@algorithm, @message_digest, @priv, NULL); ERROR HY000: asymmetric_sign UDF failed; argument 4 cannot be null SELECT asymmetric_sign(@algorithm, @message_digest, @priv, 42); ERROR HY000: asymmetric_sign UDF failed; unknown digest name SELECT asymmetric_sign(@algorithm, @message_digest, @priv, 'SHAX'); ERROR HY000: asymmetric_sign UDF failed; unknown digest name +SELECT asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, NULL); +ERROR HY000: asymmetric_sign UDF failed; argument 5 cannot be null +SELECT asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, 42); +ERROR HY000: asymmetric_sign UDF failed; Invalid RSA signature padding scheme specified +SELECT asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, 'pkcs2'); +ERROR HY000: asymmetric_sign UDF failed; Invalid RSA signature padding scheme specified -** checking 'asymmetric_verify()' function basics +** creating sample signature SET @signature = asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type); -SET @pub = create_asymmetric_pub_key(@algorithm, @priv); +SET @signature_pss = asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, 'pkcs1_pss'); + +** checking 'asymmetric_verify()' function basics SELECT asymmetric_verify(); -ERROR HY000: Can't initialize function 'asymmetric_verify'; Function requires exactly five arguments +ERROR HY000: Can't initialize function 'asymmetric_verify'; Function requires five or six arguments SELECT asymmetric_verify(@algorithm); -ERROR HY000: Can't initialize function 'asymmetric_verify'; Function requires exactly five arguments +ERROR HY000: Can't initialize function 'asymmetric_verify'; Function requires five or six arguments SELECT asymmetric_verify(@algorithm, @message_digest); -ERROR HY000: Can't initialize function 'asymmetric_verify'; Function requires exactly five arguments +ERROR HY000: Can't initialize function 'asymmetric_verify'; Function requires five or six arguments SELECT asymmetric_verify(@algorithm, @message_digest, @signature); -ERROR HY000: Can't initialize function 'asymmetric_verify'; Function requires exactly five arguments +ERROR HY000: Can't initialize function 'asymmetric_verify'; Function requires five or six arguments SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub); -ERROR HY000: Can't initialize function 'asymmetric_verify'; Function requires exactly five arguments +ERROR HY000: Can't initialize function 'asymmetric_verify'; Function requires five or six arguments SELECT asymmetric_verify(NULL, @message_digest, @signature, @pub, @digest_type); ERROR HY000: asymmetric_verify UDF failed; argument 1 cannot be null SELECT asymmetric_verify(42, @message_digest, @signature, @pub, @digest_type); @@ -129,13 +162,19 @@ ERROR HY000: asymmetric_verify UDF failed; argument 3 cannot be null SELECT asymmetric_verify(@algorithm, @message_digest, @signature, NULL, @digest_type); ERROR HY000: asymmetric_verify UDF failed; argument 4 cannot be null SELECT asymmetric_verify(@algorithm, @message_digest, @signature, 42, @digest_type); -ERROR HY000: asymmetric_verify UDF failed; cannot import RSA key from PEM PUBLIC KEY +ERROR HY000: asymmetric_verify UDF failed; cannot import EVP_PKEY from PEM PUBLIC KEY SELECT asymmetric_verify(@algorithm, @message_digest, @signature, 'blah-blah', @digest_type); -ERROR HY000: asymmetric_verify UDF failed; cannot import RSA key from PEM PUBLIC KEY +ERROR HY000: asymmetric_verify UDF failed; cannot import EVP_PKEY from PEM PUBLIC KEY SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub, NULL); ERROR HY000: asymmetric_verify UDF failed; argument 5 cannot be null SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub, 42); ERROR HY000: asymmetric_verify UDF failed; unknown digest name SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub, 'SHAX'); ERROR HY000: asymmetric_verify UDF failed; unknown digest name +SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub, @digest_type, NULL); +ERROR HY000: asymmetric_verify UDF failed; argument 6 cannot be null +SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub, @digest_type, 42); +ERROR HY000: asymmetric_verify UDF failed; Invalid RSA signature padding scheme specified +SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub, @digest_type, 'SHAX'); +ERROR HY000: asymmetric_verify UDF failed; Invalid RSA signature padding scheme specified UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/t/percona_encryption_udf_bits_threshold.test b/mysql-test/suite/component_encryption_udf/t/bits_threshold.test similarity index 100% rename from mysql-test/t/percona_encryption_udf_bits_threshold.test rename to mysql-test/suite/component_encryption_udf/t/bits_threshold.test diff --git a/mysql-test/t/percona_encryption_udf_dh_1024.test b/mysql-test/suite/component_encryption_udf/t/dh_1024.test similarity index 62% rename from mysql-test/t/percona_encryption_udf_dh_1024.test rename to mysql-test/suite/component_encryption_udf/t/dh_1024.test index 1128ca2f92ba..2c64ecceea47 100644 --- a/mysql-test/t/percona_encryption_udf_dh_1024.test +++ b/mysql-test/suite/component_encryption_udf/t/dh_1024.test @@ -2,4 +2,4 @@ --let $key_length = 1024 ---source include/percona_encryption_udf_dh.inc +--source ../include/dh.inc diff --git a/mysql-test/t/percona_encryption_udf_dh_1024_ext.test b/mysql-test/suite/component_encryption_udf/t/dh_1024_ext.test similarity index 57% rename from mysql-test/t/percona_encryption_udf_dh_1024_ext.test rename to mysql-test/suite/component_encryption_udf/t/dh_1024_ext.test index 07f9fafef7ce..61682800062e 100644 --- a/mysql-test/t/percona_encryption_udf_dh_1024_ext.test +++ b/mysql-test/suite/component_encryption_udf/t/dh_1024_ext.test @@ -1,8 +1,8 @@ --source include/have_encryption_udf_component.inc ---let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.0\\.\\d+ +--let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.\\d+\\.\\d+ --source include/have_openssl_binary_version.inc --let $key_length = 1024 --let $use_openssl_binary = 1 ---source include/percona_encryption_udf_dh.inc +--source ../include/dh.inc diff --git a/mysql-test/t/percona_encryption_udf_dh_4096.test b/mysql-test/suite/component_encryption_udf/t/dh_4096.test similarity index 69% rename from mysql-test/t/percona_encryption_udf_dh_4096.test rename to mysql-test/suite/component_encryption_udf/t/dh_4096.test index f21512335d57..c7e090404129 100644 --- a/mysql-test/t/percona_encryption_udf_dh_4096.test +++ b/mysql-test/suite/component_encryption_udf/t/dh_4096.test @@ -3,4 +3,4 @@ --let $key_length = 4096 ---source include/percona_encryption_udf_dh.inc +--source ../include/dh.inc diff --git a/mysql-test/t/percona_encryption_udf_dh_4096_ext.test b/mysql-test/suite/component_encryption_udf/t/dh_4096_ext.test similarity index 61% rename from mysql-test/t/percona_encryption_udf_dh_4096_ext.test rename to mysql-test/suite/component_encryption_udf/t/dh_4096_ext.test index 24d8f4defbdd..4e5012611a8d 100644 --- a/mysql-test/t/percona_encryption_udf_dh_4096_ext.test +++ b/mysql-test/suite/component_encryption_udf/t/dh_4096_ext.test @@ -1,9 +1,9 @@ --source include/big_test.inc --source include/have_encryption_udf_component.inc ---let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.0\\.\\d+ +--let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.\\d+\\.\\d+ --source include/have_openssl_binary_version.inc --let $key_length = 4096 --let $use_openssl_binary = 1 ---source include/percona_encryption_udf_dh.inc +--source ../include/dh.inc diff --git a/mysql-test/t/percona_encryption_udf_dh_sanity.test b/mysql-test/suite/component_encryption_udf/t/dh_sanity.test similarity index 100% rename from mysql-test/t/percona_encryption_udf_dh_sanity.test rename to mysql-test/suite/component_encryption_udf/t/dh_sanity.test diff --git a/mysql-test/t/percona_encryption_udf_digests.test b/mysql-test/suite/component_encryption_udf/t/digests.test similarity index 96% rename from mysql-test/t/percona_encryption_udf_digests.test rename to mysql-test/suite/component_encryption_udf/t/digests.test index ed64e700be86..2f28edfee57d 100644 --- a/mysql-test/t/percona_encryption_udf_digests.test +++ b/mysql-test/suite/component_encryption_udf/t/digests.test @@ -9,7 +9,7 @@ INSTALL COMPONENT 'file://component_encryption_udf'; eval SET @random_pattern = REPEAT(MD5(42), $number_of_length_iterations * $length_increment DIV 32 + 1); --let $include_digests_with_no_ans1_ids = 1 ---source include/percona_encryption_udf_digest_table.inc +--source ../include/digest_table.inc --disable_query_log --let $digest_type_idx = 1 diff --git a/mysql-test/t/percona_encryption_udf_digests_sanity.test b/mysql-test/suite/component_encryption_udf/t/digests_sanity.test similarity index 100% rename from mysql-test/t/percona_encryption_udf_digests_sanity.test rename to mysql-test/suite/component_encryption_udf/t/digests_sanity.test diff --git a/mysql-test/t/percona_encryption_udf_dsa_1024.test b/mysql-test/suite/component_encryption_udf/t/dsa_1024.test similarity index 67% rename from mysql-test/t/percona_encryption_udf_dsa_1024.test rename to mysql-test/suite/component_encryption_udf/t/dsa_1024.test index a643293c6c12..adadd01a9e3c 100644 --- a/mysql-test/t/percona_encryption_udf_dsa_1024.test +++ b/mysql-test/suite/component_encryption_udf/t/dsa_1024.test @@ -3,4 +3,4 @@ --let $algorithm = DSA --let $key_length = 1024 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_dsa_1024_ext.test b/mysql-test/suite/component_encryption_udf/t/dsa_1024_ext.test similarity index 60% rename from mysql-test/t/percona_encryption_udf_dsa_1024_ext.test rename to mysql-test/suite/component_encryption_udf/t/dsa_1024_ext.test index 278d1447c4f9..573c560facb7 100644 --- a/mysql-test/t/percona_encryption_udf_dsa_1024_ext.test +++ b/mysql-test/suite/component_encryption_udf/t/dsa_1024_ext.test @@ -1,9 +1,9 @@ --source include/have_encryption_udf_component.inc ---let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.0\\.\\d+ +--let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.\\d+\\.\\d+ --source include/have_openssl_binary_version.inc --let $algorithm = DSA --let $key_length = 1024 --let $use_openssl_binary = 1 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_dsa_4096.test b/mysql-test/suite/component_encryption_udf/t/dsa_4096.test similarity index 67% rename from mysql-test/t/percona_encryption_udf_dsa_4096.test rename to mysql-test/suite/component_encryption_udf/t/dsa_4096.test index 7772ef4fff77..e0ba0cd95e4e 100644 --- a/mysql-test/t/percona_encryption_udf_dsa_4096.test +++ b/mysql-test/suite/component_encryption_udf/t/dsa_4096.test @@ -3,4 +3,4 @@ --let $algorithm = DSA --let $key_length = 4096 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_dsa_4096_ext.test b/mysql-test/suite/component_encryption_udf/t/dsa_4096_ext.test similarity index 60% rename from mysql-test/t/percona_encryption_udf_dsa_4096_ext.test rename to mysql-test/suite/component_encryption_udf/t/dsa_4096_ext.test index e218e2248c92..6cf351d59a6c 100644 --- a/mysql-test/t/percona_encryption_udf_dsa_4096_ext.test +++ b/mysql-test/suite/component_encryption_udf/t/dsa_4096_ext.test @@ -1,9 +1,9 @@ --source include/have_encryption_udf_component.inc ---let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.0\\.\\d+ +--let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.\\d+\\.\\d+ --source include/have_openssl_binary_version.inc --let $algorithm = DSA --let $key_length = 4096 --let $use_openssl_binary = 1 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_dsa_9984.test b/mysql-test/suite/component_encryption_udf/t/dsa_9984.test similarity index 73% rename from mysql-test/t/percona_encryption_udf_dsa_9984.test rename to mysql-test/suite/component_encryption_udf/t/dsa_9984.test index 4fdab7924f95..afe3d5531c79 100644 --- a/mysql-test/t/percona_encryption_udf_dsa_9984.test +++ b/mysql-test/suite/component_encryption_udf/t/dsa_9984.test @@ -4,4 +4,4 @@ --let $algorithm = DSA --let $key_length = 9984 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_dsa_9984_ext.test b/mysql-test/suite/component_encryption_udf/t/dsa_9984_ext.test similarity index 64% rename from mysql-test/t/percona_encryption_udf_dsa_9984_ext.test rename to mysql-test/suite/component_encryption_udf/t/dsa_9984_ext.test index 1c55a505a539..ca0cb9a8bc08 100644 --- a/mysql-test/t/percona_encryption_udf_dsa_9984_ext.test +++ b/mysql-test/suite/component_encryption_udf/t/dsa_9984_ext.test @@ -1,10 +1,10 @@ --source include/big_test.inc --source include/have_encryption_udf_component.inc ---let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.0\\.\\d+ +--let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.\\d+\\.\\d+ --source include/have_openssl_binary_version.inc --let $algorithm = DSA --let $key_length = 9984 --let $use_openssl_binary = 1 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_kill_debug.test b/mysql-test/suite/component_encryption_udf/t/kill_debug.test similarity index 100% rename from mysql-test/t/percona_encryption_udf_kill_debug.test rename to mysql-test/suite/component_encryption_udf/t/kill_debug.test diff --git a/mysql-test/suite/component_encryption_udf/t/legacy_padding_scheme.test b/mysql-test/suite/component_encryption_udf/t/legacy_padding_scheme.test new file mode 100644 index 000000000000..16b629bf02e9 --- /dev/null +++ b/mysql-test/suite/component_encryption_udf/t/legacy_padding_scheme.test @@ -0,0 +1,174 @@ +--source include/have_encryption_udf_component.inc + +INSTALL COMPONENT 'file://component_encryption_udf'; + +--echo ** +--echo ** checking legacy_padding_scheme +--let $assert_text = default legacy_padding_scheme must be OFF +--let $assert_cond = @@global.encryption_udf.legacy_padding_scheme IS FALSE +--source include/assert.inc +--error ER_GLOBAL_VARIABLE +SET SESSION encryption_udf.legacy_padding_scheme = ON; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@session.encryption_udf.legacy_padding_scheme; + +SET @algorithm = 'RSA'; +SET @priv_key = create_asymmetric_priv_key(@algorithm, 1024); +SET @pub_key = create_asymmetric_pub_key(@algorithm, @priv_key); +SET @message = 'secret_message'; + + +--echo ** +--echo ** checking explicit/implicit padding scheme for RSA encrypt/decrypt + +SET @encrypted_message_oaep_explicit = asymmetric_encrypt(@algorithm, @message, @pub_key, 'oaep'); +SET @encrypted_message_pkcs1_explicit = asymmetric_encrypt(@algorithm, @message, @pub_key, 'pkcs1'); + +SET @encrypted_message_oaep_imlicit = asymmetric_encrypt(@algorithm, @message, @pub_key); +SET GLOBAL encryption_udf.legacy_padding_scheme = ON; +SET @encrypted_message_pkcs1_imlicit = asymmetric_encrypt(@algorithm, @message, @pub_key); +SET GLOBAL encryption_udf.legacy_padding_scheme = OFF; + + +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_oaep_imlicit, @priv_key, 'oaep'); +--let $assert_text = decrypting @encrypted_message_oaep_imlicit with 'oaep' scheme specified explicitly must succeed +--let $assert_cond = @decrypted_message = @message +--source include/assert.inc + +# Note that decrypting messages with different padding scheme may either fail with an error +# or succeed but produce garbage depending on random bytes inserted into the encrypted message. + +# Therefore adding '--error 0,ER_UDF_ERROR' to handle both cases. +SET @decrypted_message = ''; +--replace_regex /(cannot decrypt data block with the specified private RSA key).*/\1/ +--error 0,ER_UDF_ERROR +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_pkcs1_imlicit, @priv_key, 'oaep'); +--let $assert_text = decrypting @encrypted_message_pkcs1_imlicit with 'oaep' scheme specified explicitly must fail +--let $assert_cond = HEX(@message) <> HEX(@decrypted_message) +--source include/assert.inc + +SET @decrypted_message = ''; +--replace_regex /(cannot decrypt data block with the specified private RSA key).*/\1/ +--error 0,ER_UDF_ERROR +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_oaep_imlicit, @priv_key, 'pkcs1'); +--let $assert_text = decrypting @encrypted_message_oaep_imlicit with 'pkcs1' scheme specified explicitly must fail +--let $assert_cond = HEX(@message) <> HEX(@decrypted_message) +--source include/assert.inc + +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_pkcs1_imlicit, @priv_key, 'pkcs1'); +--let $assert_text = decrypting @encrypted_message_pkcs1_imlicit with 'pkcs1' scheme specified explicitly must succeed +--let $assert_cond = @decrypted_message = @message +--source include/assert.inc + + +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_oaep_explicit, @priv_key); +--let $assert_text = decrypting @encrypted_message_oaep_explicit with 'oaep' scheme specified implicitly must succeed +--let $assert_cond = @decrypted_message = @message +--source include/assert.inc + +SET @decrypted_message = ''; +--replace_regex /(cannot decrypt data block with the specified private RSA key).*/\1/ +--error 0,ER_UDF_ERROR +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_pkcs1_explicit, @priv_key); +--let $assert_text = decrypting @encrypted_message_pkcs1_explicit with 'oaep' scheme specified implicitly must fail +--let $assert_cond = HEX(@message) <> HEX(@decrypted_message) +--source include/assert.inc + +SET GLOBAL encryption_udf.legacy_padding_scheme = ON; + +SET @decrypted_message = ''; +--replace_regex /(cannot decrypt data block with the specified private RSA key).*/\1/ +--error 0,ER_UDF_ERROR +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_oaep_explicit, @priv_key); +--let $assert_text = decrypting @encrypted_message_oaep_explicit with 'pkcs1' scheme specified implicitly must fail +--let $assert_cond = HEX(@message) <> HEX(@decrypted_message) +--source include/assert.inc + +SET @decrypted_message = asymmetric_decrypt(@algorithm, @encrypted_message_pkcs1_explicit, @priv_key); +--let $assert_text = decrypting @encrypted_message_pkcs1_explicit with 'pkcs1' scheme specified implicitly must succeed +--let $assert_cond = @decrypted_message = @message +--source include/assert.inc + +SET GLOBAL encryption_udf.legacy_padding_scheme = OFF; + + +--echo ** +--echo ** checking explicit/implicit padding scheme for RSA sign/verify + +SET @digest_type = 'SHA256'; +SET @message_digest = create_digest(@digest_type, @message); + +SET @signature_pkcs1_pss_explicit = asymmetric_sign(@algorithm, @message_digest, @priv_key, @digest_type, 'pkcs1_pss'); +SET @signature_pkcs1_explicit = asymmetric_sign(@algorithm, @message_digest, @priv_key, @digest_type, 'pkcs1'); + +SET @signature_pkcs1_pss_imlicit = asymmetric_sign(@algorithm, @message_digest, @priv_key, @digest_type); +SET GLOBAL encryption_udf.legacy_padding_scheme = ON; +SET @signature_pkcs1_imlicit = asymmetric_sign(@algorithm, @message_digest, @priv_key, @digest_type); +SET GLOBAL encryption_udf.legacy_padding_scheme = OFF; + + +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_pss_imlicit, @pub_key, @digest_type, 'pkcs1_pss'); +--let $assert_text = verifying @signature_pkcs1_pss_imlicit with 'pkcs1_pss' scheme specified explicitly must succeed +--let $assert_cond = @verification_result = 1 +--source include/assert.inc + +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_imlicit, @pub_key, @digest_type, 'pkcs1_pss'); +--let $assert_text = verifying @signature_pkcs1_imlicit with 'pkcs1_pss' scheme specified explicitly must fail +--let $assert_cond = @verification_result = 0 +--source include/assert.inc + +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_pss_imlicit, @pub_key, @digest_type, 'pkcs1'); +--let $assert_text = verifying @signature_pkcs1_pss_imlicit with 'pkcs1' specified explicitly scheme must fail +--let $assert_cond = @verification_result = 0 +--source include/assert.inc + +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_imlicit, @pub_key, @digest_type, 'pkcs1'); +--let $assert_text = verifying @signature_pkcs1_imlicit with 'pkcs1' specified explicitly scheme must succeed +--let $assert_cond = @verification_result = 1 +--source include/assert.inc + + +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_pss_explicit, @pub_key, @digest_type); +--let $assert_text = verifying @signature_pkcs1_pss_explicit with 'pkcs1_pss' scheme specified implicitly must succeed +--let $assert_cond = @verification_result = 1 +--source include/assert.inc + +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_explicit, @pub_key, @digest_type); +--let $assert_text = verifying @signature_pkcs1_explicit with 'pkcs1_pss' scheme specified implicitly must fail +--let $assert_cond = @verification_result = 0 +--source include/assert.inc + +SET GLOBAL encryption_udf.legacy_padding_scheme = ON; + +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_pss_explicit, @pub_key, @digest_type); +--let $assert_text = verifying @signature_pkcs1_pss_explicit with 'pkcs1' specified implicitly scheme must fail +--let $assert_cond = @verification_result = 0 +--source include/assert.inc + +SET @verification_result = asymmetric_verify(@algorithm, @message_digest, @signature_pkcs1_explicit, @pub_key, @digest_type); +--let $assert_text = verifying @signature_pkcs1_explicit with 'pkcs1' specified implicitly scheme must succeed +--let $assert_cond = @verification_result = 1 +--source include/assert.inc + +SET GLOBAL encryption_udf.legacy_padding_scheme = OFF; + + +--echo ** +--echo ** checking that non-privileged users cannot change legacy_padding_scheme variables +--source include/count_sessions.inc +CREATE USER 'usr' IDENTIFIED BY 'password'; +--connect (con1, localhost, usr, password) +--connection con1 + +--error ER_SPECIFIC_ACCESS_DENIED_ERROR +SET GLOBAL encryption_udf.legacy_padding_scheme = ON; + +--disconnect con1 +--connection default +DROP USER 'usr'; +--source include/wait_until_count_sessions.inc + +# +# Dropping functions from encryption_udf +# +UNINSTALL COMPONENT 'file://component_encryption_udf'; diff --git a/mysql-test/t/percona_encryption_udf_rsa_1024.test b/mysql-test/suite/component_encryption_udf/t/rsa_1024.test similarity index 67% rename from mysql-test/t/percona_encryption_udf_rsa_1024.test rename to mysql-test/suite/component_encryption_udf/t/rsa_1024.test index 89a147b4582e..b048b449d920 100644 --- a/mysql-test/t/percona_encryption_udf_rsa_1024.test +++ b/mysql-test/suite/component_encryption_udf/t/rsa_1024.test @@ -3,4 +3,4 @@ --let $algorithm = RSA --let $key_length = 1024 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_rsa_1024_ext.test b/mysql-test/suite/component_encryption_udf/t/rsa_1024_ext.test similarity index 60% rename from mysql-test/t/percona_encryption_udf_rsa_1024_ext.test rename to mysql-test/suite/component_encryption_udf/t/rsa_1024_ext.test index 1274b64717cc..7a061e87c8dd 100644 --- a/mysql-test/t/percona_encryption_udf_rsa_1024_ext.test +++ b/mysql-test/suite/component_encryption_udf/t/rsa_1024_ext.test @@ -1,9 +1,9 @@ --source include/have_encryption_udf_component.inc ---let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.0\\.\\d+ +--let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.\\d+\\.\\d+ --source include/have_openssl_binary_version.inc --let $algorithm = RSA --let $key_length = 1024 --let $use_openssl_binary = 1 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_rsa_16384.test b/mysql-test/suite/component_encryption_udf/t/rsa_16384.test similarity index 73% rename from mysql-test/t/percona_encryption_udf_rsa_16384.test rename to mysql-test/suite/component_encryption_udf/t/rsa_16384.test index cc56d4016472..916eb17e79c7 100644 --- a/mysql-test/t/percona_encryption_udf_rsa_16384.test +++ b/mysql-test/suite/component_encryption_udf/t/rsa_16384.test @@ -4,4 +4,4 @@ --let $algorithm = RSA --let $key_length = 16384 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_rsa_16384_ext.test b/mysql-test/suite/component_encryption_udf/t/rsa_16384_ext.test similarity index 64% rename from mysql-test/t/percona_encryption_udf_rsa_16384_ext.test rename to mysql-test/suite/component_encryption_udf/t/rsa_16384_ext.test index 2988a196f7b1..c6b42916cd36 100644 --- a/mysql-test/t/percona_encryption_udf_rsa_16384_ext.test +++ b/mysql-test/suite/component_encryption_udf/t/rsa_16384_ext.test @@ -1,10 +1,10 @@ --source include/big_test.inc --source include/have_encryption_udf_component.inc ---let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.0\\.\\d+ +--let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.\\d+\\.\\d+ --source include/have_openssl_binary_version.inc --let $algorithm = RSA --let $key_length = 16384 --let $use_openssl_binary = 1 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_rsa_4096.test b/mysql-test/suite/component_encryption_udf/t/rsa_4096.test similarity index 67% rename from mysql-test/t/percona_encryption_udf_rsa_4096.test rename to mysql-test/suite/component_encryption_udf/t/rsa_4096.test index f196f7434c37..e7afc96588f8 100644 --- a/mysql-test/t/percona_encryption_udf_rsa_4096.test +++ b/mysql-test/suite/component_encryption_udf/t/rsa_4096.test @@ -3,4 +3,4 @@ --let $algorithm = RSA --let $key_length = 4096 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_rsa_4096_ext.test b/mysql-test/suite/component_encryption_udf/t/rsa_4096_ext.test similarity index 60% rename from mysql-test/t/percona_encryption_udf_rsa_4096_ext.test rename to mysql-test/suite/component_encryption_udf/t/rsa_4096_ext.test index dbd10c44742c..bef1511841ff 100644 --- a/mysql-test/t/percona_encryption_udf_rsa_4096_ext.test +++ b/mysql-test/suite/component_encryption_udf/t/rsa_4096_ext.test @@ -1,9 +1,9 @@ --source include/have_encryption_udf_component.inc ---let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.0\\.\\d+ +--let $openssl_binary_version = 1\\.0\\.2|1\\.1\\.\\d+|3\\.\\d+\\.\\d+ --source include/have_openssl_binary_version.inc --let $algorithm = RSA --let $key_length = 4096 --let $use_openssl_binary = 1 ---source include/percona_encryption_udf_xsa.inc +--source ../include/xsa.inc diff --git a/mysql-test/t/percona_encryption_udf_bits_threshold-master.opt b/mysql-test/suite/component_encryption_udf/t/suite.opt similarity index 100% rename from mysql-test/t/percona_encryption_udf_bits_threshold-master.opt rename to mysql-test/suite/component_encryption_udf/t/suite.opt diff --git a/mysql-test/t/percona_encryption_udf_xsa_sanity.test b/mysql-test/suite/component_encryption_udf/t/xsa_sanity.test similarity index 74% rename from mysql-test/t/percona_encryption_udf_xsa_sanity.test rename to mysql-test/suite/component_encryption_udf/t/xsa_sanity.test index 6e03825e71f2..cf7aa92e58f7 100644 --- a/mysql-test/t/percona_encryption_udf_xsa_sanity.test +++ b/mysql-test/suite/component_encryption_udf/t/xsa_sanity.test @@ -48,13 +48,13 @@ SELECT create_asymmetric_pub_key(); --error ER_CANT_INITIALIZE_UDF SELECT create_asymmetric_pub_key(@algorithm); ---replace_regex /(cannot import RSA key from PEM PRIVATE KEY).*/\1/ +--replace_regex /(cannot import EVP_PKEY from PEM PRIVATE KEY).*/\1/ --error ER_UDF_ERROR SELECT create_asymmetric_pub_key(@algorithm, NULL); ---replace_regex /(cannot import RSA key from PEM PRIVATE KEY).*/\1/ +--replace_regex /(cannot import EVP_PKEY from PEM PRIVATE KEY).*/\1/ --error ER_UDF_ERROR SELECT create_asymmetric_pub_key(@algorithm, 42); ---replace_regex /(cannot import RSA key from PEM PRIVATE KEY).*/\1/ +--replace_regex /(cannot import EVP_PKEY from PEM PRIVATE KEY).*/\1/ --error ER_UDF_ERROR SELECT create_asymmetric_pub_key(@algorithm, 'blah-blah'); @@ -62,6 +62,11 @@ SELECT create_asymmetric_pub_key(@algorithm, 'blah-blah'); SELECT create_asymmetric_priv_key('FOO', 2048); +--echo +--echo ** creating sample key pair +SET @priv = create_asymmetric_priv_key(@algorithm, 1024); +SET @pub = create_asymmetric_pub_key(@algorithm, @priv); + --echo --echo ** checking 'asymmetric_encrypt()' function basics --error ER_CANT_INITIALIZE_UDF @@ -85,6 +90,18 @@ SELECT asymmetric_encrypt(@algorithm, @message, 'blah-blah'); --error ER_UDF_ERROR SELECT asymmetric_encrypt(@algorithm, NULL, NULL); +--error ER_UDF_ERROR +SELECT asymmetric_encrypt(@algorithm, @message, @pub, NULL); +--error ER_UDF_ERROR +SELECT asymmetric_encrypt(@algorithm, @message, @pub, ''); +--error ER_UDF_ERROR +SELECT asymmetric_encrypt(@algorithm, @message, @pub, 'unknown'); + +--error ER_UDF_ERROR +SELECT asymmetric_encrypt(@algorithm, @message, @priv, 'oaep'); + +--error ER_CANT_INITIALIZE_UDF +SELECT asymmetric_encrypt(@algorithm, @message, @pub, 'oaep', ''); --echo --echo ** checking 'asymmetric_decrypt()' function basics @@ -109,12 +126,26 @@ SELECT asymmetric_decrypt(@algorithm, @message, 'blah-blah'); --error ER_UDF_ERROR SELECT asymmetric_decrypt(@algorithm, NULL, NULL); +--error ER_UDF_ERROR +SELECT asymmetric_decrypt(@algorithm, @message, @priv, NULL); +--error ER_UDF_ERROR +SELECT asymmetric_decrypt(@algorithm, @message, @priv, ''); +--error ER_UDF_ERROR +SELECT asymmetric_decrypt(@algorithm, @message, @priv, 'unknown'); + +--error ER_UDF_ERROR +SELECT asymmetric_decrypt(@algorithm, @message, @pub, 'oaep'); + +--error ER_CANT_INITIALIZE_UDF +SELECT asymmetric_decrypt(@algorithm, @message, @priv, 'oaep', ''); + --echo ---echo ** checking 'asymmetric_sign()' function basics +--echo ** creating sample digest SET @message_digest = create_digest(@digest_type, @message); -SET @priv = create_asymmetric_priv_key(@algorithm, 1024); +--echo +--echo ** checking 'asymmetric_sign()' function basics --error ER_CANT_INITIALIZE_UDF SELECT asymmetric_sign(); @@ -139,10 +170,10 @@ SELECT asymmetric_sign(@algorithm, NULL, @priv, @digest_type); --error ER_UDF_ERROR SELECT asymmetric_sign(@algorithm, @message_digest, NULL, @digest_type); ---replace_regex /(cannot import RSA key from PEM PRIVATE KEY).*/\1/ +--replace_regex /(cannot import EVP_PKEY from PEM PRIVATE KEY).*/\1/ --error ER_UDF_ERROR SELECT asymmetric_sign(@algorithm, @message_digest, 42, @digest_type); ---replace_regex /(cannot import RSA key from PEM PRIVATE KEY).*/\1/ +--replace_regex /(cannot import EVP_PKEY from PEM PRIVATE KEY).*/\1/ --error ER_UDF_ERROR SELECT asymmetric_sign(@algorithm, @message_digest, 'blah-blah', @digest_type); @@ -153,12 +184,21 @@ SELECT asymmetric_sign(@algorithm, @message_digest, @priv, 42); --error ER_UDF_ERROR SELECT asymmetric_sign(@algorithm, @message_digest, @priv, 'SHAX'); +--error ER_UDF_ERROR +SELECT asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, NULL); +--error ER_UDF_ERROR +SELECT asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, 42); +--error ER_UDF_ERROR +SELECT asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, 'pkcs2'); + --echo ---echo ** checking 'asymmetric_verify()' function basics +--echo ** creating sample signature SET @signature = asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type); -SET @pub = create_asymmetric_pub_key(@algorithm, @priv); +SET @signature_pss = asymmetric_sign(@algorithm, @message_digest, @priv, @digest_type, 'pkcs1_pss'); +--echo +--echo ** checking 'asymmetric_verify()' function basics --error ER_CANT_INITIALIZE_UDF SELECT asymmetric_verify(); @@ -189,10 +229,10 @@ SELECT asymmetric_verify(@algorithm, @message_digest, NULL, @pub, @digest_type); --error ER_UDF_ERROR SELECT asymmetric_verify(@algorithm, @message_digest, @signature, NULL, @digest_type); ---replace_regex /(cannot import RSA key from PEM PUBLIC KEY).*/\1/ +--replace_regex /(cannot import EVP_PKEY from PEM PUBLIC KEY).*/\1/ --error ER_UDF_ERROR SELECT asymmetric_verify(@algorithm, @message_digest, @signature, 42, @digest_type); ---replace_regex /(cannot import RSA key from PEM PUBLIC KEY).*/\1/ +--replace_regex /(cannot import EVP_PKEY from PEM PUBLIC KEY).*/\1/ --error ER_UDF_ERROR SELECT asymmetric_verify(@algorithm, @message_digest, @signature, 'blah-blah', @digest_type); @@ -203,6 +243,13 @@ SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub, 42); --error ER_UDF_ERROR SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub, 'SHAX'); +--error ER_UDF_ERROR +SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub, @digest_type, NULL); +--error ER_UDF_ERROR +SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub, @digest_type, 42); +--error ER_UDF_ERROR +SELECT asymmetric_verify(@algorithm, @message_digest, @signature, @pub, @digest_type, 'SHAX'); + # # Dropping functions from encryption_udf diff --git a/mysql-test/t/percona_encryption_udf_dh_1024-master.opt b/mysql-test/t/percona_encryption_udf_dh_1024-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_dh_1024-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_dh_1024_ext-master.opt b/mysql-test/t/percona_encryption_udf_dh_1024_ext-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_dh_1024_ext-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_dh_4096-master.opt b/mysql-test/t/percona_encryption_udf_dh_4096-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_dh_4096-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_dh_4096_ext-master.opt b/mysql-test/t/percona_encryption_udf_dh_4096_ext-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_dh_4096_ext-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_dh_sanity-master.opt b/mysql-test/t/percona_encryption_udf_dh_sanity-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_dh_sanity-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_digests-master.opt b/mysql-test/t/percona_encryption_udf_digests-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_digests-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_digests_sanity-master.opt b/mysql-test/t/percona_encryption_udf_digests_sanity-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_digests_sanity-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_dsa_1024-master.opt b/mysql-test/t/percona_encryption_udf_dsa_1024-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_dsa_1024-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_dsa_1024_ext-master.opt b/mysql-test/t/percona_encryption_udf_dsa_1024_ext-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_dsa_1024_ext-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_dsa_4096-master.opt b/mysql-test/t/percona_encryption_udf_dsa_4096-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_dsa_4096-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_dsa_4096_ext-master.opt b/mysql-test/t/percona_encryption_udf_dsa_4096_ext-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_dsa_4096_ext-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_dsa_9984-master.opt b/mysql-test/t/percona_encryption_udf_dsa_9984-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_dsa_9984-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_dsa_9984_ext-master.opt b/mysql-test/t/percona_encryption_udf_dsa_9984_ext-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_dsa_9984_ext-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_kill_debug-master.opt b/mysql-test/t/percona_encryption_udf_kill_debug-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_kill_debug-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_rsa_1024-master.opt b/mysql-test/t/percona_encryption_udf_rsa_1024-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_rsa_1024-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_rsa_1024_ext-master.opt b/mysql-test/t/percona_encryption_udf_rsa_1024_ext-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_rsa_1024_ext-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_rsa_16384-master.opt b/mysql-test/t/percona_encryption_udf_rsa_16384-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_rsa_16384-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_rsa_16384_ext-master.opt b/mysql-test/t/percona_encryption_udf_rsa_16384_ext-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_rsa_16384_ext-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_rsa_4096-master.opt b/mysql-test/t/percona_encryption_udf_rsa_4096-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_rsa_4096-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_rsa_4096_ext-master.opt b/mysql-test/t/percona_encryption_udf_rsa_4096_ext-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_rsa_4096_ext-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT diff --git a/mysql-test/t/percona_encryption_udf_xsa_sanity-master.opt b/mysql-test/t/percona_encryption_udf_xsa_sanity-master.opt deleted file mode 100644 index 18a68cb0ada0..000000000000 --- a/mysql-test/t/percona_encryption_udf_xsa_sanity-master.opt +++ /dev/null @@ -1 +0,0 @@ -$ENCRYPTION_UDF_COMPONENT_OPT