From fcc5470fd7ec9579363be008715cb42b7f32f775 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Mon, 29 Apr 2024 10:21:44 +0100 Subject: [PATCH 01/27] Intial squashed work in progress --- RSA.xs | 451 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 434 insertions(+), 17 deletions(-) diff --git a/RSA.xs b/RSA.xs index 5f5cfae..0aaa24a 100644 --- a/RSA.xs +++ b/RSA.xs @@ -14,14 +14,30 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#include +#include +//#include +#endif typedef struct { +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY* rsa; +#else RSA* rsa; +#endif int padding; int hashMode; } rsaData; +enum { + DECRYPT, + ENCRYPT, + PUBLIC_DECRYPT, + PRIVATE_ENCRYPT +}; + /* Key names for the rsa hash structure */ #define KEY_KEY "_Key" @@ -52,16 +68,25 @@ void croakSsl(char* p_file, int p_line) char _is_private(rsaData* p_rsa) { - const BIGNUM *d; #if OLD_CRUFTY_SSL_VERSION d = p_rsa->rsa->d; #else +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + BIGNUM* d = NULL; + EVP_PKEY_get_bn_param(p_rsa->rsa, OSSL_PKEY_PARAM_RSA_D, &d); +#else + const BIGNUM* d; RSA_get0_key(p_rsa->rsa, NULL, NULL, &d); +#endif #endif return(d != NULL); } +#if OPENSSL_VERSION_NUMBER >= 0x00908000L +SV* make_rsa_obj(SV* p_proto, EVP_PKEY* p_rsa) +#else SV* make_rsa_obj(SV* p_proto, RSA* p_rsa) +#endif { rsaData* rsa; @@ -112,6 +137,46 @@ int get_digest_length(int hash_method) } } +#if OPENSSL_VERSION_NUMBER >= 0x00908000L +EVP_MD *get_md_bynid(int hash_method) +{ + switch(hash_method) + { + case NID_md5: + return EVP_MD_fetch(NULL, "md5", NULL); + break; + case NID_sha1: + return EVP_MD_fetch(NULL, "sha1", NULL); + break; +#ifdef SHA512_DIGEST_LENGTH + case NID_sha224: + return EVP_MD_fetch(NULL, "sha224", NULL); + break; + case NID_sha256: + return EVP_MD_fetch(NULL, "sha256", NULL); + break; + case NID_sha384: + return EVP_MD_fetch(NULL, "sha384", NULL); + break; + case NID_sha512: + return EVP_MD_fetch(NULL, "sha512", NULL); + break; +#endif + case NID_ripemd160: + return EVP_MD_fetch(NULL, "ripemd160", NULL); + break; +#ifdef WHIRLPOOL_DIGEST_LENGTH + case NID_whirlpool: + return EVP_MD_fetch(NULL, "whirlpool", NULL); + break; +#endif + default: + croak("Unknown digest hash mode %u", hash_method); + break; + } +} +#endif + unsigned char* get_message_digest(SV* text_SV, int hash_method) { STRLEN text_length; @@ -176,15 +241,35 @@ SV* extractBioString(BIO* p_stringBio) return sv; } +int get_key_size(rsaData* p_rsa) { + int size = 0; +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + size = EVP_PKEY_get_size(p_rsa->rsa); +#else + size = RSA_size(p_rsa->rsa); +#endif + return size; +} + +#if OPENSSL_VERSION_NUMBER >= 0x00908000L +EVP_PKEY* _load_rsa_key(SV* p_keyStringSv, + EVP_PKEY*(*p_loader)(BIO *, EVP_PKEY**, pem_password_cb*, void*), + SV* p_passphaseSv) + +#else RSA* _load_rsa_key(SV* p_keyStringSv, RSA*(*p_loader)(BIO*, RSA**, pem_password_cb*, void*), SV* p_passphaseSv) +#endif { STRLEN keyStringLength; char* keyString; char* passphase = NULL; - +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY* rsa; +#else RSA* rsa; +#endif BIO* stringBIO; keyString = SvPV(p_keyStringSv, keyStringLength); @@ -204,23 +289,92 @@ RSA* _load_rsa_key(SV* p_keyStringSv, return rsa; } +#if OPENSSL_VERSION_NUMBER >= 0x00908000L +SV* rsa_crypt(rsaData* p_rsa, SV* p_from, + int (*p_crypt)(EVP_PKEY_CTX*, unsigned char*, size_t*, const unsigned char*, size_t), int enc) +#else SV* rsa_crypt(rsaData* p_rsa, SV* p_from, int (*p_crypt)(int, const unsigned char*, unsigned char*, RSA*, int)) +#endif { +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + STRLEN from_length; + size_t to_length; +#else STRLEN from_length; int to_length; +#endif int size; unsigned char* from; char* to; SV* sv; from = (unsigned char*) SvPV(p_from, from_length); - size = RSA_size(p_rsa->rsa); + size = get_key_size(p_rsa); CHECK_NEW(to, size, char); +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY_CTX *ctx; + ctx = EVP_PKEY_CTX_new((EVP_PKEY *)p_rsa->rsa, NULL); + if (!ctx) { + printf("Failed to create ctx\n"); + } + int success; + switch (enc) { + case DECRYPT: + if (EVP_PKEY_decrypt_init(ctx) <= 0) { + printf("DECRYPT: Failed to intialize encryption\n"); + } + if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0){ + printf("DECRYPT: Failed to set padding: %i\n", p_rsa->padding); + } + if (p_crypt(ctx, NULL, &to_length, from, from_length) <=0) + printf("DECRYPT: Failed to determine buffer length\n"); + if (p_crypt(ctx, to, &to_length, from, from_length) <=0) + printf("DECRYPT: Failed to decrypt\n"); + break; + case ENCRYPT: + if (EVP_PKEY_encrypt_init(ctx) <= 0) { + printf("ENCRYPT: Failed to intialize encryption\n"); + } + if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0){ + printf("ENCRYPT: Failed to set padding\n"); + } + if (p_crypt(ctx, NULL, &to_length, from, from_length) <=0) + printf("ENCRYPT: Failed to determine buffer length\n"); + if (p_crypt(ctx, to, &to_length, from, from_length) <=0) + printf("ENCRYPT: Failed to encrypt\n"); + break; + case PUBLIC_DECRYPT: + if (EVP_PKEY_verify_recover_init(ctx) <= 0) { + printf("Failed to intialize signature\n"); + } + if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0) + printf("Failed to set the PADDING\n"); + if (success = p_crypt(ctx, NULL, &to_length, from, from_length) <= 0) + printf("Failed to determine buffer length\n"); + if ((success = p_crypt(ctx, to, &to_length, from, from_length)) <= 0) + printf("Failed to public decrypt: %i\n", success); + + break; + case PRIVATE_ENCRYPT: + if (EVP_PKEY_sign_init(ctx) <= 0) { + printf("Failed to intialize signature\n"); + } + if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0) + printf("Failed to set the PADDING\n"); + if ((success = p_crypt(ctx, NULL, &to_length, from, from_length)) <= 0) + printf("Failed to determine buffer length\n"); + if ((success = p_crypt(ctx, to, &to_length, from, from_length)) <= 0) + printf("Failed to private encrypt %i\n", success); + break; + } + + EVP_PKEY_CTX_free(ctx); +#else to_length = p_crypt( from_length, from, (unsigned char*) to, p_rsa->rsa, p_rsa->padding); - +#endif if (to_length < 0) { Safefree(to); @@ -231,6 +385,20 @@ SV* rsa_crypt(rsaData* p_rsa, SV* p_from, return sv; } +void print_parameter(const EVP_PKEY *pkey, const char *key_name) { + BIGNUM *param = NULL; + char *str = NULL; + if (EVP_PKEY_get_bn_param(pkey, key_name, ¶m)) { + str = BN_bn2dec(param); + fprintf(stdout, "%s: %s\n", key_name, str); + OPENSSL_free(str); + BN_free(param); + } + else { + fprintf(stderr, "Failed to fetch %s\n", key_name); + } +} + MODULE = Crypt::OpenSSL::RSA PACKAGE = Crypt::OpenSSL::RSA PROTOTYPES: DISABLE @@ -251,8 +419,13 @@ new_private_key(proto, key_string_SV, passphase_SV=&PL_sv_undef) SV* key_string_SV; SV* passphase_SV; CODE: +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + RETVAL = make_rsa_obj( + proto, _load_rsa_key(key_string_SV, PEM_read_bio_PrivateKey, passphase_SV)); +#else RETVAL = make_rsa_obj( proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSAPrivateKey, passphase_SV)); +#endif OUTPUT: RETVAL @@ -261,8 +434,13 @@ _new_public_key_pkcs1(proto, key_string_SV) SV* proto; SV* key_string_SV; CODE: +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + RETVAL = make_rsa_obj( + proto, _load_rsa_key(key_string_SV, PEM_read_bio_PUBKEY, &PL_sv_undef)); +#else RETVAL = make_rsa_obj( proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSAPublicKey, &PL_sv_undef)); +#endif OUTPUT: RETVAL @@ -271,8 +449,13 @@ _new_public_key_x509(proto, key_string_SV) SV* proto; SV* key_string_SV; CODE: +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + RETVAL = make_rsa_obj( + proto, _load_rsa_key(key_string_SV, PEM_read_bio_PUBKEY, &PL_sv_undef)); +#else RETVAL = make_rsa_obj( proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSA_PUBKEY, &PL_sv_undef)); +#endif OUTPUT: RETVAL @@ -280,7 +463,11 @@ void DESTROY(p_rsa) rsaData* p_rsa; CODE: +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY_free(p_rsa->rsa); +#else RSA_free(p_rsa->rsa); +#endif Safefree(p_rsa); SV* @@ -313,8 +500,14 @@ get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_u } CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem())); +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + PEM_write_bio_PrivateKey_traditional(stringBIO, p_rsa->rsa, enc, + passphase, passphaseLength, + NULL, NULL); +#else PEM_write_bio_RSAPrivateKey( stringBIO, p_rsa->rsa, enc, passphase, passphaseLength, NULL, NULL); +#endif RETVAL = extractBioString(stringBIO); OUTPUT: @@ -327,7 +520,11 @@ get_public_key_string(p_rsa) BIO* stringBIO; CODE: CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem())); +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + PEM_write_bio_PUBKEY(stringBIO, p_rsa->rsa); +#else PEM_write_bio_RSAPublicKey(stringBIO, p_rsa->rsa); +#endif RETVAL = extractBioString(stringBIO); OUTPUT: @@ -340,7 +537,11 @@ get_public_key_x509_string(p_rsa) BIO* stringBIO; CODE: CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem())); +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + PEM_write_bio_PUBKEY(stringBIO, p_rsa->rsa); +#else PEM_write_bio_RSA_PUBKEY(stringBIO, p_rsa->rsa); +#endif RETVAL = extractBioString(stringBIO); OUTPUT: @@ -352,20 +553,34 @@ generate_key(proto, bitsSV, exponent = 65537) SV* bitsSV; unsigned long exponent; PREINIT: +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY_CTX *ctx; + EVP_PKEY *rsa = NULL; +#else RSA* rsa; +#endif CODE: #if OPENSSL_VERSION_NUMBER >= 0x00908000L - BIGNUM *e; - int rc; - e = BN_new(); - BN_set_word(e, exponent); - rsa = RSA_new(); - rc = RSA_generate_key_ex(rsa, SvIV(bitsSV), e, NULL); - BN_free(e); - e = NULL; - CHECK_OPEN_SSL(rc != -1); + //ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + + if (!ctx) + croak("Unable to create a CTX instance"); + if (EVP_PKEY_keygen_init(ctx) <= 0) + croak("Unable to initialize a keygen"); + if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, SvIV(bitsSV)) <= 0) + croak("Unable to set the rsa bits"); + + /* Generate key */ + if (EVP_PKEY_generate(ctx, &rsa) <= 0) + croak("Unable to generate the key"); + /* Error */ + + CHECK_OPEN_SSL(rsa != NULL); + EVP_PKEY_CTX_free(ctx); #else rsa = RSA_generate_key(SvIV(bitsSV), exponent, NULL, NULL); + CHECK_OPEN_SSL(rsa != -1); #endif CHECK_OPEN_SSL(rsa); RETVAL = make_rsa_obj(proto, rsa); @@ -382,7 +597,11 @@ _new_key_from_parameters(proto, n, e, d, p, q) BIGNUM* p; BIGNUM* q; PREINIT: +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY *rsa = NULL; +#else RSA* rsa; +#endif BN_CTX* ctx; BIGNUM* p_minus_1 = NULL; BIGNUM* q_minus_1 = NULL; @@ -396,10 +615,29 @@ _new_key_from_parameters(proto, n, e, d, p, q) { croak("At least a modulus and public key must be provided"); } +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + if (pctx == NULL) + croak("Error: failed to construct params from build"); + if ( EVP_PKEY_fromdata_init(pctx) <= 0) + croak("Error: EVP_PKEY_fromdata_init failed"); + OSSL_PARAM_BLD *params_build = OSSL_PARAM_BLD_new(); + if ( ! params_build ) + croak ("OSSL_PARAM_BLD_new error"); + BIGNUM* nt = BN_new(); +#else CHECK_OPEN_SSL(rsa = RSA_new()); +#endif #if OLD_CRUFTY_SSL_VERSION rsa->n = n; rsa->e = e; +#endif +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_N, n) ) + croak ("OSSL_PARAM_BLD_push_BN 'n' error"); + + if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_E, e) ) + croak ("OSSL_PARAM_BLD_push_BN 'e' error"); #endif if (p || q) { @@ -418,8 +656,11 @@ _new_key_from_parameters(proto, n, e, d, p, q) #if OLD_CRUFTY_SSL_VERSION rsa->p = p; rsa->q = q; +#else +#if OPENSSL_VERSION_NUMBER >= 0x00908000L #else THROW(RSA_set0_factors(rsa, p, q)); +#endif #endif THROW(p_minus_1 = BN_new()); THROW(BN_sub(p_minus_1, p, BN_value_one())); @@ -433,8 +674,17 @@ _new_key_from_parameters(proto, n, e, d, p, q) } #if OLD_CRUFTY_SSL_VERSION rsa->d = d; +#else +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_D, d) ) + croak ("OSSL_PARAM_BLD_push_BN 'd' error"); + if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_FACTOR1, p) ) + croak ("OSSL_PARAM_BLD_push_BN 'p' error"); + if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_FACTOR2, q) ) + croak ("OSSL_PARAM_BLD_push_BN 'q' error"); #else THROW(RSA_set0_key(rsa, n, e, d)); +#endif #endif THROW(dmp1 = BN_new()); THROW(BN_mod(dmp1, d, p_minus_1, ctx)); @@ -446,11 +696,49 @@ _new_key_from_parameters(proto, n, e, d, p, q) rsa->dmp1 = dmp1; rsa->dmq1 = dmq1; rsa->iqmp = iqmp; +#else +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1) ) + croak ("OSSL_PARAM_BLD_push_BN 'dmp1' error"); + if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1) ) + croak ("OSSL_PARAM_BLD_push_BN 'dmq1' error"); + if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp) ) + croak ("OSSL_PARAM_BLD_push_BN 'iqmp' error"); + + OSSL_PARAM *params = NULL; + params = OSSL_PARAM_BLD_to_param(params_build); + if ( params == NULL ) + croak("Error: failed to construct params from build"); + + int status = EVP_PKEY_fromdata(pctx, &rsa, EVP_PKEY_KEYPAIR, params); + if ( status <= 0 || rsa == NULL ) + croak("Unable to build key"); + EVP_PKEY_CTX* testctx = EVP_PKEY_CTX_new(rsa, NULL); + if (!testctx) croak("Testing key failed"); + EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_N, &nt); + //BIGNUM *n2; + //if (EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_N, &n2) <= 0) + // croak("Unable VP_PKEY_get_bn_param"); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_N); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_FACTOR1); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_FACTOR2); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_D); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_E); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT1); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT2); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_COEFFICIENT1); + //printf("========================================================================\n"); #else THROW(RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)); +#endif #endif dmp1 = dmq1 = iqmp = NULL; +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + OSSL_PARAM_BLD_free(params_build); + OSSL_PARAM_free(params); +#else THROW(RSA_check_key(rsa) == 1); +#endif err: if (p_minus_1) BN_clear_free(p_minus_1); if (q_minus_1) BN_clear_free(q_minus_1); @@ -460,7 +748,11 @@ _new_key_from_parameters(proto, n, e, d, p, q) if (ctx) BN_CTX_free(ctx); if (error) { +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY_free(rsa); +#else RSA_free(rsa); +#endif CHECK_OPEN_SSL(0); } } @@ -468,8 +760,11 @@ _new_key_from_parameters(proto, n, e, d, p, q) { #if OLD_CRUFTY_SSL_VERSION rsa->d = d; +#else +#if OPENSSL_VERSION_NUMBER >= 0x00908000L #else CHECK_OPEN_SSL(RSA_set0_key(rsa, n, e, d)); +#endif #endif } RETVAL = make_rsa_obj(proto, rsa); @@ -481,6 +776,16 @@ void _get_key_parameters(p_rsa) rsaData* p_rsa; PREINIT: +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + BIGNUM* n = NULL; + BIGNUM* e = NULL; + BIGNUM* d = NULL; + BIGNUM* p = NULL; + BIGNUM* q = NULL; + BIGNUM* dmp1 = NULL; + BIGNUM* dmq1 = NULL; + BIGNUM* iqmp = NULL; +#else const BIGNUM* n; const BIGNUM* e; const BIGNUM* d; @@ -489,9 +794,14 @@ PREINIT: const BIGNUM* dmp1; const BIGNUM* dmq1; const BIGNUM* iqmp; +#endif PPCODE: { +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY* rsa; +#else RSA* rsa; +#endif rsa = p_rsa->rsa; #if OLD_CRUFTY_SSL_VERSION n = rsa->n; @@ -502,10 +812,29 @@ PPCODE: dmp1 = rsa->dmp1; dmq1 = rsa->dmq1; iqmp = rsa->iqmp; +#else +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_N); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_D); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_E); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_FACTOR1); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_FACTOR2); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT1); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT2); + //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_COEFFICIENT1); + EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_N, &n); + EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_E, &e); + EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_D, &d); + EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_FACTOR1, &p); + EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_FACTOR2, &q); + EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT1, &dmp1); + EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT2, &dmq1); + EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &iqmp); #else RSA_get0_key(rsa, &n, &e, &d); RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); +#endif #endif XPUSHs(cor_bn2sv(n)); XPUSHs(cor_bn2sv(e)); @@ -522,7 +851,11 @@ encrypt(p_rsa, p_plaintext) rsaData* p_rsa; SV* p_plaintext; CODE: +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_encrypt, ENCRYPT); +#else RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_public_encrypt); +#endif OUTPUT: RETVAL @@ -535,7 +868,11 @@ decrypt(p_rsa, p_ciphertext) { croak("Public keys cannot decrypt"); } +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_decrypt, DECRYPT); +#else RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_private_decrypt); +#endif OUTPUT: RETVAL @@ -548,7 +885,11 @@ private_encrypt(p_rsa, p_plaintext) { croak("Public keys cannot private_encrypt"); } +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_sign, PRIVATE_ENCRYPT); +#else RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_private_encrypt); +#endif OUTPUT: RETVAL @@ -557,7 +898,11 @@ public_decrypt(p_rsa, p_ciphertext) rsaData* p_rsa; SV* p_ciphertext; CODE: +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_verify_recover, PUBLIC_DECRYPT); +#else RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_public_decrypt); +#endif OUTPUT: RETVAL @@ -565,7 +910,7 @@ int size(p_rsa) rsaData* p_rsa; CODE: - RETVAL = RSA_size(p_rsa->rsa); + RETVAL = get_key_size(p_rsa); OUTPUT: RETVAL @@ -577,7 +922,12 @@ check_key(p_rsa) { croak("Public keys cannot be checked"); } +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_pkey(NULL, p_rsa->rsa, NULL); + RETVAL = EVP_PKEY_private_check(pctx); +#else RETVAL = RSA_check_key(p_rsa->rsa); +#endif OUTPUT: RETVAL @@ -643,7 +993,6 @@ use_sha512_hash(p_rsa) rsaData* p_rsa; CODE: p_rsa->hashMode = NID_sha512; - #endif void @@ -699,7 +1048,11 @@ sign(p_rsa, text_SV) PREINIT: char* signature; unsigned char* digest; +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + size_t signature_length; +#else unsigned int signature_length; +#endif CODE: { if (!_is_private(p_rsa)) @@ -707,15 +1060,57 @@ sign(p_rsa, text_SV) croak("Public keys cannot sign messages"); } - CHECK_NEW(signature, RSA_size(p_rsa->rsa), char); + CHECK_NEW(signature, get_key_size(p_rsa), char); CHECK_OPEN_SSL(digest = get_message_digest(text_SV, p_rsa->hashMode)); +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY_CTX *ctx; + ctx = EVP_PKEY_CTX_new(p_rsa->rsa, NULL /* no engine */); + if (!ctx) + printf("sign: Failed to create ctx EVP_PKEY_CTX_new()\n"); + if(!EVP_PKEY_sign_init(ctx)) { + printf("sign: Failed to initialize signing\n"); + } + if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0) { + printf("sign: Failed to set padding EVP_PKEY_CTX_set_rsa_padding\n"); + } + EVP_MD* md = get_md_bynid(p_rsa->hashMode); + if (md == NULL) { + printf("Unknown message digest %i\n", p_rsa->hashMode); + } + int md_status; + if ((md_status = EVP_PKEY_CTX_set_signature_md(ctx, md)) <= 0) { + + printf("sign: Failed to set signature md: %i\n", md_status); + } + /* Determine buffer length */ + if (EVP_PKEY_sign(ctx, NULL, &signature_length, digest, get_digest_length(p_rsa->hashMode)) <= 0) + printf("sign: Failed to determine buffer length\n"); + + signature = OPENSSL_malloc(signature_length); + + if (!signature) + printf("sign: Failed to alocate length\n"); + /* malloc failure */ + + if (EVP_PKEY_sign(ctx, signature, &signature_length, digest, get_digest_length(p_rsa->hashMode)) <= 0) + printf("sign: failed calling EVP_PKEY_sign %s\n", signature); + /* Error */ + /* + EVP_PKEY_sign(ctx, + (unsigned char*) signature, &signature_length, + const unsigned char *tbs, size_t tbslen); + + Error */ + CHECK_OPEN_SSL(signature); +#else CHECK_OPEN_SSL(RSA_sign(p_rsa->hashMode, digest, get_digest_length(p_rsa->hashMode), (unsigned char*) signature, &signature_length, p_rsa->rsa)); +#endif RETVAL = newSVpvn(signature, signature_length); Safefree(signature); } @@ -736,18 +1131,40 @@ PPCODE: STRLEN sig_length; sig = (unsigned char*) SvPV(sig_SV, sig_length); - if (RSA_size(p_rsa->rsa) < sig_length) + if (get_key_size(p_rsa) < sig_length) { croak("Signature longer than key"); } CHECK_OPEN_SSL(digest = get_message_digest(text_SV, p_rsa->hashMode)); +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + EVP_PKEY_CTX *ctx; + ctx = EVP_PKEY_CTX_new(p_rsa->rsa, NULL /* no engine */); + if (!ctx) + printf("sign: Failed to create ctx EVP_PKEY_CTX_new()\n"); + if (EVP_PKEY_verify_init(ctx) <= 0) { + printf("verify: Failed to intialize EVP_PKEY_verify_init\n"); + } + if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0) + printf("verify: Failed to set the PADDING\n"); + EVP_MD* md = get_md_bynid(p_rsa->hashMode); + if (md == NULL) { + printf("Unknown message digest %i\n", p_rsa->hashMode); + } + int md_status; + if ((md_status = EVP_PKEY_CTX_set_signature_md(ctx, md)) <= 0) { + + printf("sign: Failed to set signature md: %i\n", md_status); + } + switch (EVP_PKEY_verify(ctx, sig, sig_length, digest, get_digest_length(p_rsa->hashMode))) +#else switch(RSA_verify(p_rsa->hashMode, digest, get_digest_length(p_rsa->hashMode), sig, sig_length, p_rsa->rsa)) +#endif { case 0: ERR_clear_error(); From 07e2a94d7c5f01a7f563e8254c37e507a2a5642a Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sat, 4 May 2024 13:50:57 -0300 Subject: [PATCH 02/27] Fix the get_public_key_string to encode the key in the old format --- RSA.xs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/RSA.xs b/RSA.xs index 0aaa24a..3a19661 100644 --- a/RSA.xs +++ b/RSA.xs @@ -17,7 +17,7 @@ #if OPENSSL_VERSION_NUMBER >= 0x00908000L #include #include -//#include +#include #endif typedef struct @@ -521,7 +521,16 @@ get_public_key_string(p_rsa) CODE: CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem())); #if OPENSSL_VERSION_NUMBER >= 0x00908000L - PEM_write_bio_PUBKEY(stringBIO, p_rsa->rsa); + OSSL_ENCODER_CTX *ctx = NULL; + + ctx = OSSL_ENCODER_CTX_new_for_pkey(p_rsa->rsa, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, + "PEM", "PKCS1", NULL); + if (ctx == NULL || !OSSL_ENCODER_CTX_get_num_encoders(ctx)) { + croak("Failed to get an encoder context"); + } + OSSL_ENCODER_to_bio(ctx, stringBIO); + + OSSL_ENCODER_CTX_free(ctx); #else PEM_write_bio_RSAPublicKey(stringBIO, p_rsa->rsa); #endif @@ -575,7 +584,7 @@ generate_key(proto, bitsSV, exponent = 65537) if (EVP_PKEY_generate(ctx, &rsa) <= 0) croak("Unable to generate the key"); /* Error */ - + CHECK_OPEN_SSL(rsa != NULL); EVP_PKEY_CTX_free(ctx); #else From 2277304b49475625d5771dbfe0a97a29cfe3e1af Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sat, 4 May 2024 15:58:02 -0300 Subject: [PATCH 03/27] Replace deprecated MD5 and RIPEMD160 calls --- RSA.xs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/RSA.xs b/RSA.xs index 3a19661..03ac90f 100644 --- a/RSA.xs +++ b/RSA.xs @@ -176,18 +176,24 @@ EVP_MD *get_md_bynid(int hash_method) } } #endif - unsigned char* get_message_digest(SV* text_SV, int hash_method) { STRLEN text_length; unsigned char* text; - +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + unsigned char *md; + size_t *mdlen; + CHECK_NEW(md, get_digest_length(hash_method), unsigned char); +#endif text = (unsigned char*) SvPV(text_SV, text_length); - switch(hash_method) { case NID_md5: +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + return EVP_Q_digest(NULL, "MD5", NULL, text, text_length, md, NULL) ? md : NULL; +#else return MD5(text, text_length, NULL); +#endif break; case NID_sha1: return SHA1(text, text_length, NULL); @@ -207,7 +213,11 @@ unsigned char* get_message_digest(SV* text_SV, int hash_method) break; #endif case NID_ripemd160: +#if OPENSSL_VERSION_NUMBER >= 0x00908000L + return EVP_Q_digest(NULL, "RIPEMD160", NULL, text, text_length, md, NULL) ? md : NULL; +#else return RIPEMD160(text, text_length, NULL); +#endif break; #ifdef WHIRLPOOL_DIGEST_LENGTH case NID_whirlpool: From 52a00fcbf9759ee6e2a3cedb9ac1bc2a09790710 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sat, 4 May 2024 19:49:56 -0300 Subject: [PATCH 04/27] Cleanup the error messaging use Module's style --- RSA.xs | 312 +++++++++++++++++++-------------------------------------- 1 file changed, 101 insertions(+), 211 deletions(-) diff --git a/RSA.xs b/RSA.xs index 03ac90f..be2b8d3 100644 --- a/RSA.xs +++ b/RSA.xs @@ -14,7 +14,7 @@ #include #include #include -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L #include #include #include @@ -22,7 +22,7 @@ typedef struct { -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY* rsa; #else RSA* rsa; @@ -71,7 +71,7 @@ char _is_private(rsaData* p_rsa) #if OLD_CRUFTY_SSL_VERSION d = p_rsa->rsa->d; #else -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L BIGNUM* d = NULL; EVP_PKEY_get_bn_param(p_rsa->rsa, OSSL_PKEY_PARAM_RSA_D, &d); #else @@ -82,7 +82,7 @@ char _is_private(rsaData* p_rsa) return(d != NULL); } -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L SV* make_rsa_obj(SV* p_proto, EVP_PKEY* p_rsa) #else SV* make_rsa_obj(SV* p_proto, RSA* p_rsa) @@ -137,7 +137,7 @@ int get_digest_length(int hash_method) } } -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_MD *get_md_bynid(int hash_method) { switch(hash_method) @@ -180,7 +180,7 @@ unsigned char* get_message_digest(SV* text_SV, int hash_method) { STRLEN text_length; unsigned char* text; -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L unsigned char *md; size_t *mdlen; CHECK_NEW(md, get_digest_length(hash_method), unsigned char); @@ -189,7 +189,7 @@ unsigned char* get_message_digest(SV* text_SV, int hash_method) switch(hash_method) { case NID_md5: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L return EVP_Q_digest(NULL, "MD5", NULL, text, text_length, md, NULL) ? md : NULL; #else return MD5(text, text_length, NULL); @@ -213,7 +213,7 @@ unsigned char* get_message_digest(SV* text_SV, int hash_method) break; #endif case NID_ripemd160: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L return EVP_Q_digest(NULL, "RIPEMD160", NULL, text, text_length, md, NULL) ? md : NULL; #else return RIPEMD160(text, text_length, NULL); @@ -253,7 +253,7 @@ SV* extractBioString(BIO* p_stringBio) int get_key_size(rsaData* p_rsa) { int size = 0; -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L size = EVP_PKEY_get_size(p_rsa->rsa); #else size = RSA_size(p_rsa->rsa); @@ -261,7 +261,7 @@ int get_key_size(rsaData* p_rsa) { return size; } -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY* _load_rsa_key(SV* p_keyStringSv, EVP_PKEY*(*p_loader)(BIO *, EVP_PKEY**, pem_password_cb*, void*), SV* p_passphaseSv) @@ -275,7 +275,7 @@ RSA* _load_rsa_key(SV* p_keyStringSv, STRLEN keyStringLength; char* keyString; char* passphase = NULL; -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY* rsa; #else RSA* rsa; @@ -299,7 +299,7 @@ RSA* _load_rsa_key(SV* p_keyStringSv, return rsa; } -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L SV* rsa_crypt(rsaData* p_rsa, SV* p_from, int (*p_crypt)(EVP_PKEY_CTX*, unsigned char*, size_t*, const unsigned char*, size_t), int enc) #else @@ -307,7 +307,7 @@ SV* rsa_crypt(rsaData* p_rsa, SV* p_from, int (*p_crypt)(int, const unsigned char*, unsigned char*, RSA*, int)) #endif { -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L STRLEN from_length; size_t to_length; #else @@ -322,61 +322,36 @@ SV* rsa_crypt(rsaData* p_rsa, SV* p_from, from = (unsigned char*) SvPV(p_from, from_length); size = get_key_size(p_rsa); CHECK_NEW(to, size, char); -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *ctx; ctx = EVP_PKEY_CTX_new((EVP_PKEY *)p_rsa->rsa, NULL); - if (!ctx) { - printf("Failed to create ctx\n"); - } - int success; + CHECK_OPEN_SSL(ctx); + switch (enc) { case DECRYPT: - if (EVP_PKEY_decrypt_init(ctx) <= 0) { - printf("DECRYPT: Failed to intialize encryption\n"); - } - if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0){ - printf("DECRYPT: Failed to set padding: %i\n", p_rsa->padding); - } - if (p_crypt(ctx, NULL, &to_length, from, from_length) <=0) - printf("DECRYPT: Failed to determine buffer length\n"); - if (p_crypt(ctx, to, &to_length, from, from_length) <=0) - printf("DECRYPT: Failed to decrypt\n"); + CHECK_OPEN_SSL(EVP_PKEY_decrypt_init(ctx) == 1); + CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0); + CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1); + CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1); break; case ENCRYPT: - if (EVP_PKEY_encrypt_init(ctx) <= 0) { - printf("ENCRYPT: Failed to intialize encryption\n"); - } - if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0){ - printf("ENCRYPT: Failed to set padding\n"); - } - if (p_crypt(ctx, NULL, &to_length, from, from_length) <=0) - printf("ENCRYPT: Failed to determine buffer length\n"); - if (p_crypt(ctx, to, &to_length, from, from_length) <=0) - printf("ENCRYPT: Failed to encrypt\n"); + CHECK_OPEN_SSL(EVP_PKEY_encrypt_init(ctx) == 1); + CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0); + CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1); + CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1); break; case PUBLIC_DECRYPT: - if (EVP_PKEY_verify_recover_init(ctx) <= 0) { - printf("Failed to intialize signature\n"); - } - if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0) - printf("Failed to set the PADDING\n"); - if (success = p_crypt(ctx, NULL, &to_length, from, from_length) <= 0) - printf("Failed to determine buffer length\n"); - if ((success = p_crypt(ctx, to, &to_length, from, from_length)) <= 0) - printf("Failed to public decrypt: %i\n", success); - + CHECK_OPEN_SSL(EVP_PKEY_verify_recover_init(ctx) == 1); + CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0); + CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1); + CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1); break; case PRIVATE_ENCRYPT: - if (EVP_PKEY_sign_init(ctx) <= 0) { - printf("Failed to intialize signature\n"); - } - if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0) - printf("Failed to set the PADDING\n"); - if ((success = p_crypt(ctx, NULL, &to_length, from, from_length)) <= 0) - printf("Failed to determine buffer length\n"); - if ((success = p_crypt(ctx, to, &to_length, from, from_length)) <= 0) - printf("Failed to private encrypt %i\n", success); + CHECK_OPEN_SSL(EVP_PKEY_sign_init(ctx) == 1); + CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0); + CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1); + CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1); break; } @@ -395,21 +370,6 @@ SV* rsa_crypt(rsaData* p_rsa, SV* p_from, return sv; } -void print_parameter(const EVP_PKEY *pkey, const char *key_name) { - BIGNUM *param = NULL; - char *str = NULL; - if (EVP_PKEY_get_bn_param(pkey, key_name, ¶m)) { - str = BN_bn2dec(param); - fprintf(stdout, "%s: %s\n", key_name, str); - OPENSSL_free(str); - BN_free(param); - } - else { - fprintf(stderr, "Failed to fetch %s\n", key_name); - } -} - - MODULE = Crypt::OpenSSL::RSA PACKAGE = Crypt::OpenSSL::RSA PROTOTYPES: DISABLE @@ -429,7 +389,7 @@ new_private_key(proto, key_string_SV, passphase_SV=&PL_sv_undef) SV* key_string_SV; SV* passphase_SV; CODE: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L RETVAL = make_rsa_obj( proto, _load_rsa_key(key_string_SV, PEM_read_bio_PrivateKey, passphase_SV)); #else @@ -444,7 +404,7 @@ _new_public_key_pkcs1(proto, key_string_SV) SV* proto; SV* key_string_SV; CODE: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L RETVAL = make_rsa_obj( proto, _load_rsa_key(key_string_SV, PEM_read_bio_PUBKEY, &PL_sv_undef)); #else @@ -459,7 +419,7 @@ _new_public_key_x509(proto, key_string_SV) SV* proto; SV* key_string_SV; CODE: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L RETVAL = make_rsa_obj( proto, _load_rsa_key(key_string_SV, PEM_read_bio_PUBKEY, &PL_sv_undef)); #else @@ -473,7 +433,7 @@ void DESTROY(p_rsa) rsaData* p_rsa; CODE: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_free(p_rsa->rsa); #else RSA_free(p_rsa->rsa); @@ -510,7 +470,7 @@ get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_u } CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem())); -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L PEM_write_bio_PrivateKey_traditional(stringBIO, p_rsa->rsa, enc, passphase, passphaseLength, NULL, NULL); @@ -530,15 +490,14 @@ get_public_key_string(p_rsa) BIO* stringBIO; CODE: CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem())); -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L OSSL_ENCODER_CTX *ctx = NULL; ctx = OSSL_ENCODER_CTX_new_for_pkey(p_rsa->rsa, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, "PEM", "PKCS1", NULL); - if (ctx == NULL || !OSSL_ENCODER_CTX_get_num_encoders(ctx)) { - croak("Failed to get an encoder context"); - } - OSSL_ENCODER_to_bio(ctx, stringBIO); + CHECK_OPEN_SSL(ctx != NULL && OSSL_ENCODER_CTX_get_num_encoders(ctx)); + + CHECK_OPEN_SSL(OSSL_ENCODER_to_bio(ctx, stringBIO) == 1); OSSL_ENCODER_CTX_free(ctx); #else @@ -556,7 +515,7 @@ get_public_key_x509_string(p_rsa) BIO* stringBIO; CODE: CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem())); -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L PEM_write_bio_PUBKEY(stringBIO, p_rsa->rsa); #else PEM_write_bio_RSA_PUBKEY(stringBIO, p_rsa->rsa); @@ -572,30 +531,22 @@ generate_key(proto, bitsSV, exponent = 65537) SV* bitsSV; unsigned long exponent; PREINIT: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *ctx; EVP_PKEY *rsa = NULL; #else RSA* rsa; #endif CODE: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L - //ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); - if (!ctx) - croak("Unable to create a CTX instance"); - if (EVP_PKEY_keygen_init(ctx) <= 0) - croak("Unable to initialize a keygen"); - if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, SvIV(bitsSV)) <= 0) - croak("Unable to set the rsa bits"); - - /* Generate key */ - if (EVP_PKEY_generate(ctx, &rsa) <= 0) - croak("Unable to generate the key"); - /* Error */ - + CHECK_OPEN_SSL(ctx); + CHECK_OPEN_SSL(EVP_PKEY_keygen_init(ctx) == 1); + CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, SvIV(bitsSV)) > 0); + CHECK_OPEN_SSL(EVP_PKEY_generate(ctx, &rsa) == 1); CHECK_OPEN_SSL(rsa != NULL); + EVP_PKEY_CTX_free(ctx); #else rsa = RSA_generate_key(SvIV(bitsSV), exponent, NULL, NULL); @@ -616,7 +567,7 @@ _new_key_from_parameters(proto, n, e, d, p, q) BIGNUM* p; BIGNUM* q; PREINIT: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY *rsa = NULL; #else RSA* rsa; @@ -634,16 +585,12 @@ _new_key_from_parameters(proto, n, e, d, p, q) { croak("At least a modulus and public key must be provided"); } -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); - if (pctx == NULL) - croak("Error: failed to construct params from build"); - if ( EVP_PKEY_fromdata_init(pctx) <= 0) - croak("Error: EVP_PKEY_fromdata_init failed"); + CHECK_OPEN_SSL(pctx != NULL); + CHECK_OPEN_SSL(EVP_PKEY_fromdata_init(pctx) > 0); OSSL_PARAM_BLD *params_build = OSSL_PARAM_BLD_new(); - if ( ! params_build ) - croak ("OSSL_PARAM_BLD_new error"); - BIGNUM* nt = BN_new(); + CHECK_OPEN_SSL(params_build) #else CHECK_OPEN_SSL(rsa = RSA_new()); #endif @@ -651,12 +598,9 @@ _new_key_from_parameters(proto, n, e, d, p, q) rsa->n = n; rsa->e = e; #endif -#if OPENSSL_VERSION_NUMBER >= 0x00908000L - if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_N, n) ) - croak ("OSSL_PARAM_BLD_push_BN 'n' error"); - - if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_E, e) ) - croak ("OSSL_PARAM_BLD_push_BN 'e' error"); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + CHECK_OPEN_SSL(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_N, n)); + CHECK_OPEN_SSL(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_E, e)); #endif if (p || q) { @@ -676,7 +620,7 @@ _new_key_from_parameters(proto, n, e, d, p, q) rsa->p = p; rsa->q = q; #else -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L #else THROW(RSA_set0_factors(rsa, p, q)); #endif @@ -694,13 +638,10 @@ _new_key_from_parameters(proto, n, e, d, p, q) #if OLD_CRUFTY_SSL_VERSION rsa->d = d; #else -#if OPENSSL_VERSION_NUMBER >= 0x00908000L - if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_D, d) ) - croak ("OSSL_PARAM_BLD_push_BN 'd' error"); - if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_FACTOR1, p) ) - croak ("OSSL_PARAM_BLD_push_BN 'p' error"); - if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_FACTOR2, q) ) - croak ("OSSL_PARAM_BLD_push_BN 'q' error"); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_D, d)); + THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_FACTOR1, p)); + THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_FACTOR2, q)); #else THROW(RSA_set0_key(rsa, n, e, d)); #endif @@ -716,43 +657,23 @@ _new_key_from_parameters(proto, n, e, d, p, q) rsa->dmq1 = dmq1; rsa->iqmp = iqmp; #else -#if OPENSSL_VERSION_NUMBER >= 0x00908000L - if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1) ) - croak ("OSSL_PARAM_BLD_push_BN 'dmp1' error"); - if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1) ) - croak ("OSSL_PARAM_BLD_push_BN 'dmq1' error"); - if ( !OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp) ) - croak ("OSSL_PARAM_BLD_push_BN 'iqmp' error"); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1)); + THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1)); + THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp)); OSSL_PARAM *params = NULL; params = OSSL_PARAM_BLD_to_param(params_build); - if ( params == NULL ) - croak("Error: failed to construct params from build"); + THROW(params != NULL); int status = EVP_PKEY_fromdata(pctx, &rsa, EVP_PKEY_KEYPAIR, params); - if ( status <= 0 || rsa == NULL ) - croak("Unable to build key"); - EVP_PKEY_CTX* testctx = EVP_PKEY_CTX_new(rsa, NULL); - if (!testctx) croak("Testing key failed"); - EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_N, &nt); - //BIGNUM *n2; - //if (EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_N, &n2) <= 0) - // croak("Unable VP_PKEY_get_bn_param"); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_N); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_FACTOR1); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_FACTOR2); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_D); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_E); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT1); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT2); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_COEFFICIENT1); - //printf("========================================================================\n"); + THROW( status > 0 && rsa != NULL ); #else THROW(RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)); #endif #endif dmp1 = dmq1 = iqmp = NULL; -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L OSSL_PARAM_BLD_free(params_build); OSSL_PARAM_free(params); #else @@ -767,7 +688,7 @@ _new_key_from_parameters(proto, n, e, d, p, q) if (ctx) BN_CTX_free(ctx); if (error) { -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_free(rsa); #else RSA_free(rsa); @@ -780,7 +701,7 @@ _new_key_from_parameters(proto, n, e, d, p, q) #if OLD_CRUFTY_SSL_VERSION rsa->d = d; #else -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L #else CHECK_OPEN_SSL(RSA_set0_key(rsa, n, e, d)); #endif @@ -795,7 +716,7 @@ void _get_key_parameters(p_rsa) rsaData* p_rsa; PREINIT: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L BIGNUM* n = NULL; BIGNUM* e = NULL; BIGNUM* d = NULL; @@ -816,7 +737,7 @@ PREINIT: #endif PPCODE: { -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY* rsa; #else RSA* rsa; @@ -832,15 +753,7 @@ PPCODE: dmq1 = rsa->dmq1; iqmp = rsa->iqmp; #else -#if OPENSSL_VERSION_NUMBER >= 0x00908000L - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_N); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_D); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_E); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_FACTOR1); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_FACTOR2); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT1); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT2); - //print_parameter(rsa, OSSL_PKEY_PARAM_RSA_COEFFICIENT1); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_N, &n); EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_E, &e); EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_D, &d); @@ -870,7 +783,7 @@ encrypt(p_rsa, p_plaintext) rsaData* p_rsa; SV* p_plaintext; CODE: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_encrypt, ENCRYPT); #else RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_public_encrypt); @@ -887,7 +800,7 @@ decrypt(p_rsa, p_ciphertext) { croak("Public keys cannot decrypt"); } -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_decrypt, DECRYPT); #else RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_private_decrypt); @@ -904,7 +817,7 @@ private_encrypt(p_rsa, p_plaintext) { croak("Public keys cannot private_encrypt"); } -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_sign, PRIVATE_ENCRYPT); #else RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_private_encrypt); @@ -917,7 +830,7 @@ public_decrypt(p_rsa, p_ciphertext) rsaData* p_rsa; SV* p_ciphertext; CODE: -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_verify_recover, PUBLIC_DECRYPT); #else RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_public_decrypt); @@ -941,7 +854,7 @@ check_key(p_rsa) { croak("Public keys cannot be checked"); } -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_pkey(NULL, p_rsa->rsa, NULL); RETVAL = EVP_PKEY_private_check(pctx); #else @@ -1067,7 +980,7 @@ sign(p_rsa, text_SV) PREINIT: char* signature; unsigned char* digest; -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L size_t signature_length; #else unsigned int signature_length; @@ -1082,45 +995,27 @@ sign(p_rsa, text_SV) CHECK_NEW(signature, get_key_size(p_rsa), char); CHECK_OPEN_SSL(digest = get_message_digest(text_SV, p_rsa->hashMode)); -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *ctx; ctx = EVP_PKEY_CTX_new(p_rsa->rsa, NULL /* no engine */); - if (!ctx) - printf("sign: Failed to create ctx EVP_PKEY_CTX_new()\n"); - if(!EVP_PKEY_sign_init(ctx)) { - printf("sign: Failed to initialize signing\n"); - } - if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0) { - printf("sign: Failed to set padding EVP_PKEY_CTX_set_rsa_padding\n"); - } + CHECK_OPEN_SSL(ctx); + CHECK_OPEN_SSL(EVP_PKEY_sign_init(ctx)); + /* FIXME: Issue setting padding in some cases */ + EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding); + EVP_MD* md = get_md_bynid(p_rsa->hashMode); - if (md == NULL) { - printf("Unknown message digest %i\n", p_rsa->hashMode); - } + CHECK_OPEN_SSL(md != NULL); + int md_status; - if ((md_status = EVP_PKEY_CTX_set_signature_md(ctx, md)) <= 0) { + CHECK_OPEN_SSL((md_status = EVP_PKEY_CTX_set_signature_md(ctx, md)) > 0); - printf("sign: Failed to set signature md: %i\n", md_status); - } - /* Determine buffer length */ - if (EVP_PKEY_sign(ctx, NULL, &signature_length, digest, get_digest_length(p_rsa->hashMode)) <= 0) - printf("sign: Failed to determine buffer length\n"); + CHECK_OPEN_SSL(EVP_PKEY_sign(ctx, NULL, &signature_length, digest, get_digest_length(p_rsa->hashMode)) == 1); signature = OPENSSL_malloc(signature_length); - if (!signature) - printf("sign: Failed to alocate length\n"); - /* malloc failure */ - - if (EVP_PKEY_sign(ctx, signature, &signature_length, digest, get_digest_length(p_rsa->hashMode)) <= 0) - printf("sign: failed calling EVP_PKEY_sign %s\n", signature); - /* Error */ - /* - EVP_PKEY_sign(ctx, - (unsigned char*) signature, &signature_length, - const unsigned char *tbs, size_t tbslen); + CHECK_OPEN_SSL(signature); - Error */ + CHECK_OPEN_SSL(EVP_PKEY_sign(ctx, signature, &signature_length, digest, get_digest_length(p_rsa->hashMode)) == 1); CHECK_OPEN_SSL(signature); #else CHECK_OPEN_SSL(RSA_sign(p_rsa->hashMode, @@ -1156,25 +1051,20 @@ PPCODE: } CHECK_OPEN_SSL(digest = get_message_digest(text_SV, p_rsa->hashMode)); -#if OPENSSL_VERSION_NUMBER >= 0x00908000L +#if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *ctx; ctx = EVP_PKEY_CTX_new(p_rsa->rsa, NULL /* no engine */); - if (!ctx) - printf("sign: Failed to create ctx EVP_PKEY_CTX_new()\n"); - if (EVP_PKEY_verify_init(ctx) <= 0) { - printf("verify: Failed to intialize EVP_PKEY_verify_init\n"); - } - if (EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) <= 0) - printf("verify: Failed to set the PADDING\n"); + CHECK_OPEN_SSL(ctx); + CHECK_OPEN_SSL(EVP_PKEY_verify_init(ctx) == 1); + /* FIXME: Issue setting padding in some cases */ + EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding); + EVP_MD* md = get_md_bynid(p_rsa->hashMode); - if (md == NULL) { - printf("Unknown message digest %i\n", p_rsa->hashMode); - } + CHECK_OPEN_SSL(md != NULL); + int md_status; - if ((md_status = EVP_PKEY_CTX_set_signature_md(ctx, md)) <= 0) { + CHECK_OPEN_SSL((md_status = EVP_PKEY_CTX_set_signature_md(ctx, md)) > 0); - printf("sign: Failed to set signature md: %i\n", md_status); - } switch (EVP_PKEY_verify(ctx, sig, sig_length, digest, get_digest_length(p_rsa->hashMode))) #else switch(RSA_verify(p_rsa->hashMode, From 702072438b8c89ed1b98b2694dc77a3a2764f525 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sat, 4 May 2024 20:20:17 -0300 Subject: [PATCH 05/27] Fix the exponent not being set --- RSA.xs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/RSA.xs b/RSA.xs index be2b8d3..1cbf068 100644 --- a/RSA.xs +++ b/RSA.xs @@ -539,14 +539,21 @@ generate_key(proto, bitsSV, exponent = 65537) #endif CODE: #if OPENSSL_VERSION_NUMBER >= 0x30000000L + BIGNUM *e; + e = BN_new(); + BN_set_word(e, exponent); + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); CHECK_OPEN_SSL(ctx); CHECK_OPEN_SSL(EVP_PKEY_keygen_init(ctx) == 1); CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, SvIV(bitsSV)) > 0); + CHECK_OPEN_SSL(EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, e) >0); CHECK_OPEN_SSL(EVP_PKEY_generate(ctx, &rsa) == 1); CHECK_OPEN_SSL(rsa != NULL); + e = NULL; + BN_free(e); EVP_PKEY_CTX_free(ctx); #else rsa = RSA_generate_key(SvIV(bitsSV), exponent, NULL, NULL); From 254d6536d5785befa2c76969fe19104c4820a5b8 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sat, 4 May 2024 21:47:36 -0300 Subject: [PATCH 06/27] Fix missing check key that caused two test failures in bigone.t --- RSA.xs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RSA.xs b/RSA.xs index 1cbf068..abdf8b3 100644 --- a/RSA.xs +++ b/RSA.xs @@ -675,6 +675,8 @@ _new_key_from_parameters(proto, n, e, d, p, q) int status = EVP_PKEY_fromdata(pctx, &rsa, EVP_PKEY_KEYPAIR, params); THROW( status > 0 && rsa != NULL ); + EVP_PKEY_CTX* test_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, rsa, NULL); + THROW(EVP_PKEY_check(test_ctx) == 1); #else THROW(RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)); #endif From 13dd92ca0022ac7c2124f1d4887f04dc3deff166 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 5 May 2024 10:51:32 -0300 Subject: [PATCH 07/27] Also need to create key when p and q are not provided --- RSA.xs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/RSA.xs b/RSA.xs index abdf8b3..1895fe2 100644 --- a/RSA.xs +++ b/RSA.xs @@ -593,6 +593,7 @@ _new_key_from_parameters(proto, n, e, d, p, q) croak("At least a modulus and public key must be provided"); } #if OPENSSL_VERSION_NUMBER >= 0x30000000L + OSSL_PARAM *params = NULL; EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); CHECK_OPEN_SSL(pctx != NULL); CHECK_OPEN_SSL(EVP_PKEY_fromdata_init(pctx) > 0); @@ -669,7 +670,6 @@ _new_key_from_parameters(proto, n, e, d, p, q) THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1)); THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp)); - OSSL_PARAM *params = NULL; params = OSSL_PARAM_BLD_to_param(params_build); THROW(params != NULL); @@ -711,6 +711,13 @@ _new_key_from_parameters(proto, n, e, d, p, q) rsa->d = d; #else #if OPENSSL_VERSION_NUMBER >= 0x30000000L + params = OSSL_PARAM_BLD_to_param(params_build); + THROW(params != NULL); + + int status = EVP_PKEY_fromdata(pctx, &rsa, EVP_PKEY_KEYPAIR, params); + THROW( status > 0 && rsa != NULL ); + //EVP_PKEY_CTX* test_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, rsa, NULL); + //THROW(EVP_PKEY_check(test_ctx) == 1); #else CHECK_OPEN_SSL(RSA_set0_key(rsa, n, e, d)); #endif From 8c2bb32a9fb941b66ca3f1d1c74a293662262c1a Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 5 May 2024 11:00:06 -0300 Subject: [PATCH 08/27] Fix final issue with bignum tests --- RSA.xs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RSA.xs b/RSA.xs index 1895fe2..75ea567 100644 --- a/RSA.xs +++ b/RSA.xs @@ -186,6 +186,7 @@ unsigned char* get_message_digest(SV* text_SV, int hash_method) CHECK_NEW(md, get_digest_length(hash_method), unsigned char); #endif text = (unsigned char*) SvPV(text_SV, text_length); + switch(hash_method) { case NID_md5: @@ -711,6 +712,8 @@ _new_key_from_parameters(proto, n, e, d, p, q) rsa->d = d; #else #if OPENSSL_VERSION_NUMBER >= 0x30000000L + if(d != NULL) + THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_D, d)); params = OSSL_PARAM_BLD_to_param(params_build); THROW(params != NULL); From 3e78af7a4a8440e172004dcb514f83020f7f761b Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 5 May 2024 11:20:08 -0300 Subject: [PATCH 09/27] Fix issue in crufty old version --- RSA.xs | 1 + 1 file changed, 1 insertion(+) diff --git a/RSA.xs b/RSA.xs index 75ea567..b4b4e64 100644 --- a/RSA.xs +++ b/RSA.xs @@ -69,6 +69,7 @@ void croakSsl(char* p_file, int p_line) char _is_private(rsaData* p_rsa) { #if OLD_CRUFTY_SSL_VERSION + const BIGNUM* d; d = p_rsa->rsa->d; #else #if OPENSSL_VERSION_NUMBER >= 0x30000000L From 9d1feb08b0729ad1f17eb572a8f4ba3c3f735500 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 5 May 2024 12:21:59 -0300 Subject: [PATCH 10/27] Fix issue with openssl < 0x00908000L --- RSA.xs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/RSA.xs b/RSA.xs index b4b4e64..9407db8 100644 --- a/RSA.xs +++ b/RSA.xs @@ -540,11 +540,21 @@ generate_key(proto, bitsSV, exponent = 65537) RSA* rsa; #endif CODE: -#if OPENSSL_VERSION_NUMBER >= 0x30000000L BIGNUM *e; e = BN_new(); BN_set_word(e, exponent); - +#if OPENSSL_VERSION_NUMBER < 0x00908000L + rsa = RSA_generate_key(SvIV(bitsSV), exponent, NULL, NULL); + CHECK_OPEN_SSL(rsa != -1); +#endif +#if OPENSSL_VERSION_NUMBER >= 0x00908000L && OPENSSL_VERSION_NUMBER < 0x30000000L + int rc; + rsa = RSA_new(); + rc = RSA_generate_key_ex(rsa, SvIV(bitsSV), e, NULL); + BN_free(e); + CHECK_OPEN_SSL(rsa != -1); +#endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); CHECK_OPEN_SSL(ctx); @@ -557,9 +567,6 @@ generate_key(proto, bitsSV, exponent = 65537) e = NULL; BN_free(e); EVP_PKEY_CTX_free(ctx); -#else - rsa = RSA_generate_key(SvIV(bitsSV), exponent, NULL, NULL); - CHECK_OPEN_SSL(rsa != -1); #endif CHECK_OPEN_SSL(rsa); RETVAL = make_rsa_obj(proto, rsa); From d4773c3656f7fcd133aad829525602c5e525a06f Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 5 May 2024 16:53:20 -0300 Subject: [PATCH 11/27] Line breaks in #if ... requires ExtUtils::ParseXS@3.51 possibly 3.48 --- RSA.xs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/RSA.xs b/RSA.xs index 9407db8..762cd2a 100644 --- a/RSA.xs +++ b/RSA.xs @@ -82,10 +82,11 @@ char _is_private(rsaData* p_rsa) #endif return(d != NULL); } - #if OPENSSL_VERSION_NUMBER >= 0x30000000L + SV* make_rsa_obj(SV* p_proto, EVP_PKEY* p_rsa) #else + SV* make_rsa_obj(SV* p_proto, RSA* p_rsa) #endif { @@ -137,8 +138,8 @@ int get_digest_length(int hash_method) break; } } - #if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_MD *get_md_bynid(int hash_method) { switch(hash_method) @@ -262,13 +263,14 @@ int get_key_size(rsaData* p_rsa) { #endif return size; } - #if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY* _load_rsa_key(SV* p_keyStringSv, EVP_PKEY*(*p_loader)(BIO *, EVP_PKEY**, pem_password_cb*, void*), SV* p_passphaseSv) #else + RSA* _load_rsa_key(SV* p_keyStringSv, RSA*(*p_loader)(BIO*, RSA**, pem_password_cb*, void*), SV* p_passphaseSv) @@ -300,11 +302,12 @@ RSA* _load_rsa_key(SV* p_keyStringSv, CHECK_OPEN_SSL(rsa); return rsa; } - #if OPENSSL_VERSION_NUMBER >= 0x30000000L + SV* rsa_crypt(rsaData* p_rsa, SV* p_from, int (*p_crypt)(EVP_PKEY_CTX*, unsigned char*, size_t*, const unsigned char*, size_t), int enc) #else + SV* rsa_crypt(rsaData* p_rsa, SV* p_from, int (*p_crypt)(int, const unsigned char*, unsigned char*, RSA*, int)) #endif @@ -952,6 +955,7 @@ use_sha512_hash(p_rsa) rsaData* p_rsa; CODE: p_rsa->hashMode = NID_sha512; + #endif void From 0c35c8cc58ce51bed8d4df0a45f1372bab784ba6 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 5 May 2024 17:57:22 -0300 Subject: [PATCH 12/27] Try outputting the openssl version --- Makefile.PL | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.PL b/Makefile.PL index 3b72fdd..f924374 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -3,8 +3,10 @@ use warnings; use 5.006; use ExtUtils::MakeMaker 6.48; -use Crypt::OpenSSL::Guess qw(openssl_inc_paths openssl_lib_paths); +use Crypt::OpenSSL::Guess qw(openssl_inc_paths openssl_lib_paths openssl_version); +my ($major, $minor, $patch) = openssl_version(); +print "OpenSSL version: $major.$minor $patch", "\n"; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. From c1b3a194cadf91897f48b1961938f127f8f56966 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 5 May 2024 18:40:10 -0300 Subject: [PATCH 13/27] Fix differences in signedness --- RSA.xs | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/RSA.xs b/RSA.xs index 762cd2a..fa2f94a 100644 --- a/RSA.xs +++ b/RSA.xs @@ -315,18 +315,23 @@ SV* rsa_crypt(rsaData* p_rsa, SV* p_from, #if OPENSSL_VERSION_NUMBER >= 0x30000000L STRLEN from_length; size_t to_length; + unsigned char* to; #else STRLEN from_length; int to_length; + char* to; #endif int size; unsigned char* from; - char* to; SV* sv; from = (unsigned char*) SvPV(p_from, from_length); size = get_key_size(p_rsa); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + CHECK_NEW(to, size, unsigned char); +#else CHECK_NEW(to, size, char); +#endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *ctx; @@ -370,7 +375,7 @@ SV* rsa_crypt(rsaData* p_rsa, SV* p_from, Safefree(to); CHECK_OPEN_SSL(0); } - sv = newSVpv(to, to_length); + sv = newSVpv((char *) to, to_length); Safefree(to); return sv; } @@ -452,7 +457,11 @@ get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_u SV* cipher_name_SV; PREINIT: BIO* stringBIO; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + unsigned char* passphase = NULL; +#else char* passphase = NULL; +#endif STRLEN passphaseLength = 0; char* cipher_name; const EVP_CIPHER* enc = NULL; @@ -461,7 +470,7 @@ get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_u croak("Passphrase is required for cipher"); } if (SvPOK(passphase_SV)) { - passphase = SvPV(passphase_SV, passphaseLength); + passphase = (unsigned char *) SvPV(passphase_SV, passphaseLength); if (SvPOK(cipher_name_SV)) { cipher_name = SvPV_nolen(cipher_name_SV); } @@ -1009,11 +1018,12 @@ sign(p_rsa, text_SV) rsaData* p_rsa; SV* text_SV; PREINIT: - char* signature; unsigned char* digest; #if OPENSSL_VERSION_NUMBER >= 0x30000000L + unsigned char* signature; size_t signature_length; #else + char* signature; unsigned int signature_length; #endif CODE: @@ -1022,8 +1032,11 @@ sign(p_rsa, text_SV) { croak("Public keys cannot sign messages"); } - +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + CHECK_NEW(signature, get_key_size(p_rsa), unsigned char); +#else CHECK_NEW(signature, get_key_size(p_rsa), char); +#endif CHECK_OPEN_SSL(digest = get_message_digest(text_SV, p_rsa->hashMode)); #if OPENSSL_VERSION_NUMBER >= 0x30000000L @@ -1056,7 +1069,7 @@ sign(p_rsa, text_SV) &signature_length, p_rsa->rsa)); #endif - RETVAL = newSVpvn(signature, signature_length); + RETVAL = newSVpvn((const char *)signature, signature_length); Safefree(signature); } OUTPUT: From 0733855e5cfaeb9a8732ee19f878a393da6923de Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 5 May 2024 18:46:51 -0300 Subject: [PATCH 14/27] Check to see if issue is with ripemd160 --- t/rsa.t | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/t/rsa.t b/t/rsa.t index d3e7f0b..23f3e10 100644 --- a/t/rsa.t +++ b/t/rsa.t @@ -3,6 +3,7 @@ use Test::More; use Crypt::OpenSSL::Random; use Crypt::OpenSSL::RSA; +use Crypt::OpenSSL::Guess qw(openssl_version); BEGIN { plan tests => 43 + ( UNIVERSAL::can( "Crypt::OpenSSL::RSA", "use_sha512_hash" ) ? 4 * 5 : 0 ) } @@ -145,9 +146,16 @@ if ( UNIVERSAL::can( "Crypt::OpenSSL::RSA", "use_sha512_hash" ) ) { _Test_Sign_And_Verify( $plaintext, $rsa, $rsa_pub ); } -$rsa->use_ripemd160_hash(); -$rsa_pub->use_ripemd160_hash(); -_Test_Sign_And_Verify( $plaintext, $rsa, $rsa_pub ); +my ($major, $minor, $patch) = openssl_version(); + +SKIP: { + skip "ripemd160 in legacy provider between 3.02 and 3.07", 5 if $major eq '3.0' && + ($minor ge '2' && $minor le '6'); + + $rsa->use_ripemd160_hash(); + $rsa_pub->use_ripemd160_hash(); + _Test_Sign_And_Verify( $plaintext, $rsa, $rsa_pub ); +} if (UNIVERSAL::can("Crypt::OpenSSL::RSA", "use_whirlpool_hash")) { $rsa->use_whirlpool_hash(); From 84cf85d87119aaf34165a896f0f5d17daa91cdae Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 5 May 2024 19:16:07 -0300 Subject: [PATCH 15/27] Fix some additional warnings and stray character before BN_free --- RSA.xs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RSA.xs b/RSA.xs index fa2f94a..efa52a1 100644 --- a/RSA.xs +++ b/RSA.xs @@ -557,14 +557,14 @@ generate_key(proto, bitsSV, exponent = 65537) BN_set_word(e, exponent); #if OPENSSL_VERSION_NUMBER < 0x00908000L rsa = RSA_generate_key(SvIV(bitsSV), exponent, NULL, NULL); - CHECK_OPEN_SSL(rsa != -1); + CHECK_OPEN_SSL(rsa != NULL); #endif #if OPENSSL_VERSION_NUMBER >= 0x00908000L && OPENSSL_VERSION_NUMBER < 0x30000000L int rc; rsa = RSA_new(); rc = RSA_generate_key_ex(rsa, SvIV(bitsSV), e, NULL); - BN_free(e); - CHECK_OPEN_SSL(rsa != -1); + BN_free(e); + CHECK_OPEN_SSL(rsa != NULL); #endif #if OPENSSL_VERSION_NUMBER >= 0x30000000L ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); From 9fe4814abf94a2dc79482db8241538e4e453ca33 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 5 May 2024 19:24:36 -0300 Subject: [PATCH 16/27] Remove unused variable --- RSA.xs | 1 - 1 file changed, 1 deletion(-) diff --git a/RSA.xs b/RSA.xs index efa52a1..5e0a540 100644 --- a/RSA.xs +++ b/RSA.xs @@ -184,7 +184,6 @@ unsigned char* get_message_digest(SV* text_SV, int hash_method) unsigned char* text; #if OPENSSL_VERSION_NUMBER >= 0x30000000L unsigned char *md; - size_t *mdlen; CHECK_NEW(md, get_digest_length(hash_method), unsigned char); #endif text = (unsigned char*) SvPV(text_SV, text_length); From 42af6bcfbdad2f1578ccd9b3a2fba54e12b652cb Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 5 May 2024 19:53:19 -0300 Subject: [PATCH 17/27] Collapse duplicate code by passing init function definition --- RSA.xs | 48 ++++++++++-------------------------------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/RSA.xs b/RSA.xs index 5e0a540..04b57fa 100644 --- a/RSA.xs +++ b/RSA.xs @@ -31,13 +31,6 @@ typedef struct int hashMode; } rsaData; -enum { - DECRYPT, - ENCRYPT, - PUBLIC_DECRYPT, - PRIVATE_ENCRYPT -}; - /* Key names for the rsa hash structure */ #define KEY_KEY "_Key" @@ -304,7 +297,8 @@ RSA* _load_rsa_key(SV* p_keyStringSv, #if OPENSSL_VERSION_NUMBER >= 0x30000000L SV* rsa_crypt(rsaData* p_rsa, SV* p_from, - int (*p_crypt)(EVP_PKEY_CTX*, unsigned char*, size_t*, const unsigned char*, size_t), int enc) + int (*p_crypt)(EVP_PKEY_CTX*, unsigned char*, size_t*, const unsigned char*, size_t), + int (*init_crypt)(EVP_PKEY_CTX*)) #else SV* rsa_crypt(rsaData* p_rsa, SV* p_from, @@ -337,32 +331,10 @@ SV* rsa_crypt(rsaData* p_rsa, SV* p_from, ctx = EVP_PKEY_CTX_new((EVP_PKEY *)p_rsa->rsa, NULL); CHECK_OPEN_SSL(ctx); - switch (enc) { - case DECRYPT: - CHECK_OPEN_SSL(EVP_PKEY_decrypt_init(ctx) == 1); - CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0); - CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1); - CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1); - break; - case ENCRYPT: - CHECK_OPEN_SSL(EVP_PKEY_encrypt_init(ctx) == 1); - CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0); - CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1); - CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1); - break; - case PUBLIC_DECRYPT: - CHECK_OPEN_SSL(EVP_PKEY_verify_recover_init(ctx) == 1); - CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0); - CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1); - CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1); - break; - case PRIVATE_ENCRYPT: - CHECK_OPEN_SSL(EVP_PKEY_sign_init(ctx) == 1); - CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0); - CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1); - CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1); - break; - } + CHECK_OPEN_SSL(init_crypt(ctx) == 1); + CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0); + CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1); + CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1); EVP_PKEY_CTX_free(ctx); #else @@ -822,7 +794,7 @@ encrypt(p_rsa, p_plaintext) SV* p_plaintext; CODE: #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_encrypt, ENCRYPT); + RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_encrypt, EVP_PKEY_encrypt_init); #else RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_public_encrypt); #endif @@ -839,7 +811,7 @@ decrypt(p_rsa, p_ciphertext) croak("Public keys cannot decrypt"); } #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_decrypt, DECRYPT); + RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_decrypt, EVP_PKEY_decrypt_init); #else RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_private_decrypt); #endif @@ -856,7 +828,7 @@ private_encrypt(p_rsa, p_plaintext) croak("Public keys cannot private_encrypt"); } #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_sign, PRIVATE_ENCRYPT); + RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_sign, EVP_PKEY_sign_init); #else RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_private_encrypt); #endif @@ -869,7 +841,7 @@ public_decrypt(p_rsa, p_ciphertext) SV* p_ciphertext; CODE: #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_verify_recover, PUBLIC_DECRYPT); + RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_verify_recover, EVP_PKEY_verify_recover_init); #else RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_public_decrypt); #endif From 4d34275dccdff93340dd002490fd09bc2feac650 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Thu, 30 May 2024 21:54:31 -0300 Subject: [PATCH 18/27] Fix memory leak --- RSA.xs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/RSA.xs b/RSA.xs index 04b57fa..82159e8 100644 --- a/RSA.xs +++ b/RSA.xs @@ -176,8 +176,7 @@ unsigned char* get_message_digest(SV* text_SV, int hash_method) STRLEN text_length; unsigned char* text; #if OPENSSL_VERSION_NUMBER >= 0x30000000L - unsigned char *md; - CHECK_NEW(md, get_digest_length(hash_method), unsigned char); + static unsigned char md[EVP_MAX_MD_SIZE]; #endif text = (unsigned char*) SvPV(text_SV, text_length); From 61367c9d4b1d8a37c4145694b6833af645cb88ac Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Thu, 30 May 2024 22:26:52 -0300 Subject: [PATCH 19/27] Remove commented out debugging code --- RSA.xs | 2 -- 1 file changed, 2 deletions(-) diff --git a/RSA.xs b/RSA.xs index 82159e8..6645b26 100644 --- a/RSA.xs +++ b/RSA.xs @@ -709,8 +709,6 @@ _new_key_from_parameters(proto, n, e, d, p, q) int status = EVP_PKEY_fromdata(pctx, &rsa, EVP_PKEY_KEYPAIR, params); THROW( status > 0 && rsa != NULL ); - //EVP_PKEY_CTX* test_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, rsa, NULL); - //THROW(EVP_PKEY_check(test_ctx) == 1); #else CHECK_OPEN_SSL(RSA_set0_key(rsa, n, e, d)); #endif From 16dbfe659b21497040838802411ee224609dba0d Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Mon, 1 Jul 2024 23:58:05 -0300 Subject: [PATCH 20/27] Fix some signedness issues on early openssl --- RSA.xs | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/RSA.xs b/RSA.xs index 6645b26..a2e075b 100644 --- a/RSA.xs +++ b/RSA.xs @@ -20,6 +20,11 @@ #include #endif +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#define UNSIGNED_CHAR unsigned char +#else +#define UNSIGNED_CHAR char +#endif typedef struct { #if OPENSSL_VERSION_NUMBER >= 0x30000000L @@ -269,7 +274,7 @@ RSA* _load_rsa_key(SV* p_keyStringSv, { STRLEN keyStringLength; char* keyString; - char* passphase = NULL; + UNSIGNED_CHAR *passphase = NULL; #if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY* rsa; #else @@ -307,23 +312,18 @@ SV* rsa_crypt(rsaData* p_rsa, SV* p_from, #if OPENSSL_VERSION_NUMBER >= 0x30000000L STRLEN from_length; size_t to_length; - unsigned char* to; #else STRLEN from_length; int to_length; - char* to; #endif + UNSIGNED_CHAR *to; int size; unsigned char* from; SV* sv; from = (unsigned char*) SvPV(p_from, from_length); size = get_key_size(p_rsa); -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - CHECK_NEW(to, size, unsigned char); -#else - CHECK_NEW(to, size, char); -#endif + CHECK_NEW(to, size, UNSIGNED_CHAR); #if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *ctx; @@ -427,11 +427,7 @@ get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_u SV* cipher_name_SV; PREINIT: BIO* stringBIO; -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - unsigned char* passphase = NULL; -#else - char* passphase = NULL; -#endif + char *passphase = NULL; STRLEN passphaseLength = 0; char* cipher_name; const EVP_CIPHER* enc = NULL; @@ -440,7 +436,7 @@ get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_u croak("Passphrase is required for cipher"); } if (SvPOK(passphase_SV)) { - passphase = (unsigned char *) SvPV(passphase_SV, passphaseLength); + passphase = SvPV(passphase_SV, passphaseLength); if (SvPOK(cipher_name_SV)) { cipher_name = SvPV_nolen(cipher_name_SV); } @@ -460,7 +456,7 @@ get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_u NULL, NULL); #else PEM_write_bio_RSAPrivateKey( - stringBIO, p_rsa->rsa, enc, passphase, passphaseLength, NULL, NULL); + stringBIO, p_rsa->rsa, enc, (unsigned char *) passphase, passphaseLength, NULL, NULL); #endif RETVAL = extractBioString(stringBIO); @@ -530,9 +526,9 @@ generate_key(proto, bitsSV, exponent = 65537) CHECK_OPEN_SSL(rsa != NULL); #endif #if OPENSSL_VERSION_NUMBER >= 0x00908000L && OPENSSL_VERSION_NUMBER < 0x30000000L - int rc; rsa = RSA_new(); - rc = RSA_generate_key_ex(rsa, SvIV(bitsSV), e, NULL); + if (!RSA_generate_key_ex(rsa, SvIV(bitsSV), e, NULL)) + croak("Unable to generate a key"); BN_free(e); CHECK_OPEN_SSL(rsa != NULL); #endif From 76e6e3bd45a597794f00f2f5fa9329a3649e81d7 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Mon, 1 Jul 2024 23:15:19 -0300 Subject: [PATCH 21/27] Fixes #48 - Whirlpool is missing the header --- RSA.xs | 3 +++ t/rsa.t | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/RSA.xs b/RSA.xs index a2e075b..6e9d6f5 100644 --- a/RSA.xs +++ b/RSA.xs @@ -10,6 +10,9 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER < 0x30000000 +#include +#endif #include #include #include diff --git a/t/rsa.t b/t/rsa.t index 23f3e10..4bd1f01 100644 --- a/t/rsa.t +++ b/t/rsa.t @@ -5,7 +5,9 @@ use Crypt::OpenSSL::Random; use Crypt::OpenSSL::RSA; use Crypt::OpenSSL::Guess qw(openssl_version); -BEGIN { plan tests => 43 + ( UNIVERSAL::can( "Crypt::OpenSSL::RSA", "use_sha512_hash" ) ? 4 * 5 : 0 ) } +BEGIN { plan tests => 43 + + ( UNIVERSAL::can( "Crypt::OpenSSL::RSA", "use_sha512_hash" ) ? 4 * 5 : 0 ) + + ( UNIVERSAL::can( "Crypt::OpenSSL::RSA", "use_whirlpool_hash" ) ? 1 * 5 : 0 ) } sub _Test_Encrypt_And_Decrypt { my ( $p_plaintext_length, $p_rsa, $p_check_private_encrypt ) = @_; From bacba6dc417b61e1cb9a1e8db53d5d0d221b56be Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Wed, 3 Jul 2024 19:51:41 -0300 Subject: [PATCH 22/27] Fixes #50 - Correct openssl version may not be found --- Makefile.PL | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.PL b/Makefile.PL index f924374..1964256 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,5 +1,6 @@ use strict; use warnings; +use Config; use 5.006; use ExtUtils::MakeMaker 6.48; @@ -25,6 +26,7 @@ WriteMakefile( }, 'OBJECT' => 'RSA.o', 'LIBS' => [openssl_lib_paths() . ' -lssl -lcrypto'], + 'LDDLFLAGS' => openssl_lib_paths() . ' ' . $Config{lddlflags}, 'DEFINE' => '-DPERL5 -DOPENSSL_NO_KRB5', # perl-5.8/gcc-3.2 needs -DPERL5, and redhat9 likes -DOPENSSL_NO_KRB5 From a441b56be3fb69228543a3fd2c5c2989bc08f662 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Thu, 4 Jul 2024 17:47:52 -0300 Subject: [PATCH 23/27] Fixes #52 - Out of memory on openssl 1.1.1w hpux --- RSA.xs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/RSA.xs b/RSA.xs index 6e9d6f5..4ba4c07 100644 --- a/RSA.xs +++ b/RSA.xs @@ -242,11 +242,13 @@ SV* cor_bn2sv(const BIGNUM* p_bn) SV* extractBioString(BIO* p_stringBio) { SV* sv; - BUF_MEM* bptr; + char *datap; + long datasize = 0; CHECK_OPEN_SSL(BIO_flush(p_stringBio) == 1); - BIO_get_mem_ptr(p_stringBio, &bptr); - sv = newSVpv(bptr->data, bptr->length); + + datasize = BIO_get_mem_data(p_stringBio, &datap); + sv = newSVpv(datap, datasize); CHECK_OPEN_SSL(BIO_set_close(p_stringBio, BIO_CLOSE) == 1); BIO_free(p_stringBio); From fd7be1dba1abaff219ac30c47cf48efde1921763 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sat, 6 Jul 2024 14:01:14 -0300 Subject: [PATCH 24/27] Fix issue freeing memory on threaded perl --- RSA.xs | 92 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/RSA.xs b/RSA.xs index 4ba4c07..c74b28f 100644 --- a/RSA.xs +++ b/RSA.xs @@ -1,3 +1,4 @@ +#define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" @@ -85,10 +86,10 @@ char _is_private(rsaData* p_rsa) } #if OPENSSL_VERSION_NUMBER >= 0x30000000L -SV* make_rsa_obj(SV* p_proto, EVP_PKEY* p_rsa) +SV* make_rsa_obj(pTHX_ SV* p_proto, EVP_PKEY* p_rsa) #else -SV* make_rsa_obj(SV* p_proto, RSA* p_rsa) +SV* make_rsa_obj(pTHX_ SV* p_proto, RSA* p_rsa) #endif { rsaData* rsa; @@ -179,7 +180,7 @@ EVP_MD *get_md_bynid(int hash_method) } } #endif -unsigned char* get_message_digest(SV* text_SV, int hash_method) +unsigned char* get_message_digest(pTHX_ SV* text_SV, int hash_method) { STRLEN text_length; unsigned char* text; @@ -232,14 +233,14 @@ unsigned char* get_message_digest(SV* text_SV, int hash_method) } } -SV* cor_bn2sv(const BIGNUM* p_bn) +SV* cor_bn2sv(pTHX_ const BIGNUM* p_bn) { return p_bn != NULL ? sv_2mortal(newSViv((IV) BN_dup(p_bn))) : &PL_sv_undef; } -SV* extractBioString(BIO* p_stringBio) +SV* extractBioString(pTHX_ BIO* p_stringBio) { SV* sv; char *datap; @@ -266,13 +267,13 @@ int get_key_size(rsaData* p_rsa) { } #if OPENSSL_VERSION_NUMBER >= 0x30000000L -EVP_PKEY* _load_rsa_key(SV* p_keyStringSv, +EVP_PKEY* _load_rsa_key(pTHX_ SV* p_keyStringSv, EVP_PKEY*(*p_loader)(BIO *, EVP_PKEY**, pem_password_cb*, void*), SV* p_passphaseSv) #else -RSA* _load_rsa_key(SV* p_keyStringSv, +RSA* _load_rsa_key(pTHX_ SV* p_keyStringSv, RSA*(*p_loader)(BIO*, RSA**, pem_password_cb*, void*), SV* p_passphaseSv) #endif @@ -305,12 +306,12 @@ RSA* _load_rsa_key(SV* p_keyStringSv, } #if OPENSSL_VERSION_NUMBER >= 0x30000000L -SV* rsa_crypt(rsaData* p_rsa, SV* p_from, +SV* rsa_crypt(pTHX_ rsaData* p_rsa, SV* p_from, int (*p_crypt)(EVP_PKEY_CTX*, unsigned char*, size_t*, const unsigned char*, size_t), int (*init_crypt)(EVP_PKEY_CTX*)) #else -SV* rsa_crypt(rsaData* p_rsa, SV* p_from, +SV* rsa_crypt(pTHX_ rsaData* p_rsa, SV* p_from, int (*p_crypt)(int, const unsigned char*, unsigned char*, RSA*, int)) #endif { @@ -375,11 +376,11 @@ new_private_key(proto, key_string_SV, passphase_SV=&PL_sv_undef) SV* passphase_SV; CODE: #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = make_rsa_obj( - proto, _load_rsa_key(key_string_SV, PEM_read_bio_PrivateKey, passphase_SV)); + RETVAL = make_rsa_obj(aTHX_ + proto, _load_rsa_key(aTHX_ key_string_SV, PEM_read_bio_PrivateKey, passphase_SV)); #else - RETVAL = make_rsa_obj( - proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSAPrivateKey, passphase_SV)); + RETVAL = make_rsa_obj(aTHX_ + proto, _load_rsa_key(aTHX_ key_string_SV, PEM_read_bio_RSAPrivateKey, passphase_SV)); #endif OUTPUT: RETVAL @@ -390,11 +391,11 @@ _new_public_key_pkcs1(proto, key_string_SV) SV* key_string_SV; CODE: #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = make_rsa_obj( - proto, _load_rsa_key(key_string_SV, PEM_read_bio_PUBKEY, &PL_sv_undef)); + RETVAL = make_rsa_obj(aTHX_ + proto, _load_rsa_key(aTHX_ key_string_SV, PEM_read_bio_PUBKEY, &PL_sv_undef)); #else - RETVAL = make_rsa_obj( - proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSAPublicKey, &PL_sv_undef)); + RETVAL = make_rsa_obj(aTHX_ + proto, _load_rsa_key(aTHX_ key_string_SV, PEM_read_bio_RSAPublicKey, &PL_sv_undef)); #endif OUTPUT: RETVAL @@ -405,11 +406,11 @@ _new_public_key_x509(proto, key_string_SV) SV* key_string_SV; CODE: #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = make_rsa_obj( - proto, _load_rsa_key(key_string_SV, PEM_read_bio_PUBKEY, &PL_sv_undef)); + RETVAL = make_rsa_obj(aTHX_ + proto, _load_rsa_key(aTHX_ key_string_SV, PEM_read_bio_PUBKEY, &PL_sv_undef)); #else - RETVAL = make_rsa_obj( - proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSA_PUBKEY, &PL_sv_undef)); + RETVAL = make_rsa_obj(aTHX_ + proto, _load_rsa_key(aTHX_ key_string_SV, PEM_read_bio_RSA_PUBKEY, &PL_sv_undef)); #endif OUTPUT: RETVAL @@ -463,7 +464,7 @@ get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_u PEM_write_bio_RSAPrivateKey( stringBIO, p_rsa->rsa, enc, (unsigned char *) passphase, passphaseLength, NULL, NULL); #endif - RETVAL = extractBioString(stringBIO); + RETVAL = extractBioString(aTHX_ stringBIO); OUTPUT: RETVAL @@ -488,7 +489,7 @@ get_public_key_string(p_rsa) #else PEM_write_bio_RSAPublicKey(stringBIO, p_rsa->rsa); #endif - RETVAL = extractBioString(stringBIO); + RETVAL = extractBioString(aTHX_ stringBIO); OUTPUT: RETVAL @@ -505,7 +506,7 @@ get_public_key_x509_string(p_rsa) #else PEM_write_bio_RSA_PUBKEY(stringBIO, p_rsa->rsa); #endif - RETVAL = extractBioString(stringBIO); + RETVAL = extractBioString(aTHX_ stringBIO); OUTPUT: RETVAL @@ -552,7 +553,7 @@ generate_key(proto, bitsSV, exponent = 65537) EVP_PKEY_CTX_free(ctx); #endif CHECK_OPEN_SSL(rsa); - RETVAL = make_rsa_obj(proto, rsa); + RETVAL = make_rsa_obj(aTHX_ proto, rsa); OUTPUT: RETVAL @@ -715,7 +716,7 @@ _new_key_from_parameters(proto, n, e, d, p, q) #endif #endif } - RETVAL = make_rsa_obj(proto, rsa); + RETVAL = make_rsa_obj(aTHX_ proto, rsa); } OUTPUT: RETVAL @@ -776,14 +777,14 @@ PPCODE: RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); #endif #endif - XPUSHs(cor_bn2sv(n)); - XPUSHs(cor_bn2sv(e)); - XPUSHs(cor_bn2sv(d)); - XPUSHs(cor_bn2sv(p)); - XPUSHs(cor_bn2sv(q)); - XPUSHs(cor_bn2sv(dmp1)); - XPUSHs(cor_bn2sv(dmq1)); - XPUSHs(cor_bn2sv(iqmp)); + XPUSHs(cor_bn2sv(aTHX_ n)); + XPUSHs(cor_bn2sv(aTHX_ e)); + XPUSHs(cor_bn2sv(aTHX_ d)); + XPUSHs(cor_bn2sv(aTHX_ p)); + XPUSHs(cor_bn2sv(aTHX_ q)); + XPUSHs(cor_bn2sv(aTHX_ dmp1)); + XPUSHs(cor_bn2sv(aTHX_ dmq1)); + XPUSHs(cor_bn2sv(aTHX_ iqmp)); } SV* @@ -792,9 +793,9 @@ encrypt(p_rsa, p_plaintext) SV* p_plaintext; CODE: #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_encrypt, EVP_PKEY_encrypt_init); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_plaintext, EVP_PKEY_encrypt, EVP_PKEY_encrypt_init); #else - RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_public_encrypt); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_plaintext, RSA_public_encrypt); #endif OUTPUT: RETVAL @@ -809,9 +810,9 @@ decrypt(p_rsa, p_ciphertext) croak("Public keys cannot decrypt"); } #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_decrypt, EVP_PKEY_decrypt_init); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_ciphertext, EVP_PKEY_decrypt, EVP_PKEY_decrypt_init); #else - RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_private_decrypt); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_ciphertext, RSA_private_decrypt); #endif OUTPUT: RETVAL @@ -826,9 +827,9 @@ private_encrypt(p_rsa, p_plaintext) croak("Public keys cannot private_encrypt"); } #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_sign, EVP_PKEY_sign_init); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_plaintext, EVP_PKEY_sign, EVP_PKEY_sign_init); #else - RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_private_encrypt); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_plaintext, RSA_private_encrypt); #endif OUTPUT: RETVAL @@ -839,9 +840,9 @@ public_decrypt(p_rsa, p_ciphertext) SV* p_ciphertext; CODE: #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_verify_recover, EVP_PKEY_verify_recover_init); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_ciphertext, EVP_PKEY_verify_recover, EVP_PKEY_verify_recover_init); #else - RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_public_decrypt); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_ciphertext, RSA_public_decrypt); #endif OUTPUT: RETVAL @@ -1007,7 +1008,7 @@ sign(p_rsa, text_SV) CHECK_NEW(signature, get_key_size(p_rsa), char); #endif - CHECK_OPEN_SSL(digest = get_message_digest(text_SV, p_rsa->hashMode)); + CHECK_OPEN_SSL(digest = get_message_digest(aTHX_ text_SV, p_rsa->hashMode)); #if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *ctx; ctx = EVP_PKEY_CTX_new(p_rsa->rsa, NULL /* no engine */); @@ -1024,7 +1025,8 @@ sign(p_rsa, text_SV) CHECK_OPEN_SSL(EVP_PKEY_sign(ctx, NULL, &signature_length, digest, get_digest_length(p_rsa->hashMode)) == 1); - signature = OPENSSL_malloc(signature_length); + //signature = OPENSSL_malloc(signature_length); + Newx(signature, signature_length, char); CHECK_OPEN_SSL(signature); @@ -1063,7 +1065,7 @@ PPCODE: croak("Signature longer than key"); } - CHECK_OPEN_SSL(digest = get_message_digest(text_SV, p_rsa->hashMode)); + CHECK_OPEN_SSL(digest = get_message_digest(aTHX_ text_SV, p_rsa->hashMode)); #if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *ctx; ctx = EVP_PKEY_CTX_new(p_rsa->rsa, NULL /* no engine */); From 661c253ea5be189e310eea326c5275982c893b88 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Sun, 7 Jul 2024 11:03:10 -0300 Subject: [PATCH 25/27] Move err: after last time it is invoked and only get there if make_rsa_obj fails --- RSA.xs | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/RSA.xs b/RSA.xs index c74b28f..46f061b 100644 --- a/RSA.xs +++ b/RSA.xs @@ -681,22 +681,6 @@ _new_key_from_parameters(proto, n, e, d, p, q) #else THROW(RSA_check_key(rsa) == 1); #endif - err: - if (p_minus_1) BN_clear_free(p_minus_1); - if (q_minus_1) BN_clear_free(q_minus_1); - if (dmp1) BN_clear_free(dmp1); - if (dmq1) BN_clear_free(dmq1); - if (iqmp) BN_clear_free(iqmp); - if (ctx) BN_CTX_free(ctx); - if (error) - { -#if OPENSSL_VERSION_NUMBER >= 0x30000000L - EVP_PKEY_free(rsa); -#else - RSA_free(rsa); -#endif - CHECK_OPEN_SSL(0); - } } else { @@ -716,8 +700,33 @@ _new_key_from_parameters(proto, n, e, d, p, q) #endif #endif } + RETVAL = make_rsa_obj(aTHX_ proto, rsa); -} + if(RETVAL) + goto end; + + err: + //if (p) BN_clear_free(p); + if (p_minus_1) BN_clear_free(p_minus_1); + //if (q) BN_clear_free(q); + //if (d) BN_clear_free(d); + if (q_minus_1) BN_clear_free(q_minus_1); + if (dmp1) BN_clear_free(dmp1); + if (dmq1) BN_clear_free(dmq1); + if (iqmp) BN_clear_free(iqmp); + if (ctx) BN_CTX_free(ctx); + if (error) + { +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + EVP_PKEY_free(rsa); +#else + RSA_free(rsa); +#endif + CHECK_OPEN_SSL(0); + } + } + end: + OUTPUT: RETVAL From 5be8a4bf0a5f06de3b98adaad32cdfe9501e5b98 Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Mon, 8 Jul 2024 22:00:26 -0300 Subject: [PATCH 26/27] Fix bug private versus public - maybe --- RSA.xs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/RSA.xs b/RSA.xs index 46f061b..1b52037 100644 --- a/RSA.xs +++ b/RSA.xs @@ -308,7 +308,7 @@ RSA* _load_rsa_key(pTHX_ SV* p_keyStringSv, SV* rsa_crypt(pTHX_ rsaData* p_rsa, SV* p_from, int (*p_crypt)(EVP_PKEY_CTX*, unsigned char*, size_t*, const unsigned char*, size_t), - int (*init_crypt)(EVP_PKEY_CTX*)) + int (*init_crypt)(EVP_PKEY_CTX*), int public) #else SV* rsa_crypt(pTHX_ rsaData* p_rsa, SV* p_from, @@ -333,7 +333,14 @@ SV* rsa_crypt(pTHX_ rsaData* p_rsa, SV* p_from, #if OPENSSL_VERSION_NUMBER >= 0x30000000L EVP_PKEY_CTX *ctx; - ctx = EVP_PKEY_CTX_new((EVP_PKEY *)p_rsa->rsa, NULL); + OSSL_LIB_CTX *ossllibctx = OSSL_LIB_CTX_new(); + const char *propquery; + if (public) { + ctx = EVP_PKEY_CTX_new_from_pkey(ossllibctx, (EVP_PKEY *)p_rsa->rsa, propquery); + } else { + ctx = EVP_PKEY_CTX_new((EVP_PKEY *)p_rsa->rsa, NULL); + } + CHECK_OPEN_SSL(ctx); CHECK_OPEN_SSL(init_crypt(ctx) == 1); @@ -802,7 +809,7 @@ encrypt(p_rsa, p_plaintext) SV* p_plaintext; CODE: #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(aTHX_ p_rsa, p_plaintext, EVP_PKEY_encrypt, EVP_PKEY_encrypt_init); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_plaintext, EVP_PKEY_encrypt, EVP_PKEY_encrypt_init, 1 /* public */); #else RETVAL = rsa_crypt(aTHX_ p_rsa, p_plaintext, RSA_public_encrypt); #endif @@ -819,7 +826,7 @@ decrypt(p_rsa, p_ciphertext) croak("Public keys cannot decrypt"); } #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(aTHX_ p_rsa, p_ciphertext, EVP_PKEY_decrypt, EVP_PKEY_decrypt_init); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_ciphertext, EVP_PKEY_decrypt, EVP_PKEY_decrypt_init, 0 /* private */); #else RETVAL = rsa_crypt(aTHX_ p_rsa, p_ciphertext, RSA_private_decrypt); #endif @@ -836,7 +843,7 @@ private_encrypt(p_rsa, p_plaintext) croak("Public keys cannot private_encrypt"); } #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(aTHX_ p_rsa, p_plaintext, EVP_PKEY_sign, EVP_PKEY_sign_init); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_plaintext, EVP_PKEY_sign, EVP_PKEY_sign_init, 0 /* private */); #else RETVAL = rsa_crypt(aTHX_ p_rsa, p_plaintext, RSA_private_encrypt); #endif @@ -849,7 +856,7 @@ public_decrypt(p_rsa, p_ciphertext) SV* p_ciphertext; CODE: #if OPENSSL_VERSION_NUMBER >= 0x30000000L - RETVAL = rsa_crypt(aTHX_ p_rsa, p_ciphertext, EVP_PKEY_verify_recover, EVP_PKEY_verify_recover_init); + RETVAL = rsa_crypt(aTHX_ p_rsa, p_ciphertext, EVP_PKEY_verify_recover, EVP_PKEY_verify_recover_init, 1 /*public */); #else RETVAL = rsa_crypt(aTHX_ p_rsa, p_ciphertext, RSA_public_decrypt); #endif From ed3e25ccdde521729517fd0b73e0f779456d623c Mon Sep 17 00:00:00 2001 From: Timothy Legge Date: Fri, 19 Jul 2024 21:02:48 -0300 Subject: [PATCH 27/27] Consolidate AIX and HPUX fixes for linking properly --- Makefile.PL | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Makefile.PL b/Makefile.PL index 1964256..79b3e7d 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,6 +1,7 @@ use strict; use warnings; use Config; +use List::Util 1.45 qw(uniq); use 5.006; use ExtUtils::MakeMaker 6.48; @@ -11,6 +12,24 @@ print "OpenSSL version: $major.$minor $patch", "\n"; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. +my $libs = ' -lssl -lcrypto'; +if ( $Config{osname} eq 'aix' ) { + $libs = $libs . ' -lz'; +} + +my $ssllibpth = openssl_lib_paths(); +my $lddlflags = $Config{lddlflags}; +$lddlflags =~ s/(?=-L)/$ssllibpth /; + +my $ldflags = $Config{ldflags}; +$ldflags =~ s/(?=-L)/$ssllibpth /; + +if ($^O eq "hpux" && $Config{ld} eq "/usr/bin/ld") { + my $bpth = join ":" => uniq (+("$ssllibpth $lddlflags $ldflags") =~ m/-L(\S+)/g); + $lddlflags .= " +b $bpth"; + $ldflags .= " +Wl,+b,$bpth"; +} + WriteMakefile( 'NAME' => 'Crypt::OpenSSL::RSA', 'AUTHOR' => 'Ian Robertson ', @@ -25,8 +44,9 @@ WriteMakefile( 'Test::More' => 0, }, 'OBJECT' => 'RSA.o', - 'LIBS' => [openssl_lib_paths() . ' -lssl -lcrypto'], - 'LDDLFLAGS' => openssl_lib_paths() . ' ' . $Config{lddlflags}, + 'LIBS' => [ openssl_lib_paths() . $libs ], + 'LDDLFLAGS' => $lddlflags, + 'LDFLAGS' => $ldflags, 'DEFINE' => '-DPERL5 -DOPENSSL_NO_KRB5', # perl-5.8/gcc-3.2 needs -DPERL5, and redhat9 likes -DOPENSSL_NO_KRB5