@@ -401,56 +401,56 @@ EVP_PKEY* _load_rsa_key(SV* p_keyStringSv,
401401#endif
402402 return rsa ;
403403}
404+
405+ static void check_max_message_length (rsaData * p_rsa , STRLEN from_length ) {
406+ int size ;
407+ int max_len = -1 ;
408+ const char * pad_name = NULL ;
409+
410+ size = EVP_PKEY_get_size (p_rsa -> rsa );
411+
412+ if (p_rsa -> padding == RSA_PKCS1_OAEP_PADDING ) {
413+ max_len = size - 42 ; /* 2 * SHA1_DIGEST_LENGTH + 2 */
414+ pad_name = "OAEP" ;
415+ } else if (p_rsa -> padding == RSA_PKCS1_PADDING ) {
416+ max_len = size - 11 ; /* PKCS#1 v1.5 overhead */
417+ pad_name = "PKCS#1 v1.5" ;
418+ } else if (p_rsa -> padding == RSA_NO_PADDING ) {
419+ max_len = size ;
420+ pad_name = "no" ;
421+ }
422+ if (max_len >= 0 && from_length > (STRLEN ) max_len ) {
423+ croak ("plaintext too long for key size with %s padding"
424+ " (%d bytes max, got %d)" , pad_name , max_len , (int )from_length );
425+ }
426+ }
404427#if OPENSSL_VERSION_NUMBER >= 0x30000000L
405428
406429SV * rsa_crypt (rsaData * p_rsa , SV * p_from ,
407430 int (* p_crypt )(EVP_PKEY_CTX * , unsigned char * , size_t * , const unsigned char * , size_t ),
408- int (* init_crypt )(EVP_PKEY_CTX * ), int public , int is_encrypt )
431+ int (* init_crypt )(EVP_PKEY_CTX * ), int is_encrypt )
409432#else
410433
411434SV * rsa_crypt (rsaData * p_rsa , SV * p_from ,
412- int (* p_crypt )(int , const unsigned char * , unsigned char * , RSA * , int ), int public , int is_encrypt )
435+ int (* p_crypt )(int , const unsigned char * , unsigned char * , RSA * , int ), int is_encrypt )
413436#endif
414437{
415438 STRLEN from_length ;
416439 SIZE_T_INT to_length ;
417- int size ;
418440 unsigned char * from ;
419441 UNSIGNED_CHAR * to = NULL ;
420442 SV * sv ;
443+ #if OPENSSL_VERSION_NUMBER < 0x30000000L
444+ int size ;
445+ #endif
421446
422447 from = (unsigned char * ) SvPV (p_from , from_length );
423- size = EVP_PKEY_get_size (p_rsa -> rsa );
424448
425449 if (is_encrypt && p_rsa -> padding == RSA_PKCS1_PADDING ) {
426450 croak ("PKCS#1 v1.5 padding for encryption is vulnerable to the Marvin attack. "
427451 "Use use_pkcs1_oaep_padding() for encryption, or use_pkcs1_padding() with sign()/verify()." );
428452 }
429453
430- /* Pre-validate plaintext length before calling OpenSSL.
431- Only applies to encryption direction (encrypt, private_encrypt),
432- not to decryption (decrypt, public_decrypt) where input is ciphertext. */
433- if (public == is_encrypt ) {
434- int max_len = -1 ;
435- const char * pad_name = NULL ;
436-
437- if (p_rsa -> padding == RSA_PKCS1_OAEP_PADDING ) {
438- max_len = size - 42 ; /* 2 * SHA1_DIGEST_LENGTH + 2 */
439- pad_name = "OAEP" ;
440- } else if (p_rsa -> padding == RSA_PKCS1_PADDING ) {
441- max_len = size - 11 ; /* PKCS#1 v1.5 overhead */
442- pad_name = "PKCS#1 v1.5" ;
443- } else if (p_rsa -> padding == RSA_NO_PADDING ) {
444- max_len = size ;
445- pad_name = "no" ;
446- }
447-
448- if (max_len >= 0 && (int )from_length > max_len ) {
449- croak ("plaintext too long for key size with %s padding"
450- " (%d bytes max, got %d)" , pad_name , max_len , (int )from_length );
451- }
452- }
453-
454454#if OPENSSL_VERSION_NUMBER >= 0x30000000L
455455
456456 if (p_rsa -> padding == RSA_PKCS1_PSS_PADDING ) {
@@ -488,6 +488,7 @@ SV* rsa_crypt(rsaData* p_rsa, SV* p_from,
488488 CHECK_OPEN_SSL (0 );
489489 crypt_done :
490490#else
491+ size = EVP_PKEY_get_size (p_rsa -> rsa );
491492 CHECK_NEW (to , size , UNSIGNED_CHAR );
492493 to_length = p_crypt (
493494 from_length , from , (unsigned char * ) to , p_rsa -> rsa , p_rsa -> padding );
@@ -1146,10 +1147,11 @@ encrypt(p_rsa, p_plaintext)
11461147 rsaData * p_rsa ;
11471148 SV * p_plaintext ;
11481149 CODE :
1150+ check_max_message_length (p_rsa , sv_len (p_plaintext ));
11491151#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1150- RETVAL = rsa_crypt (p_rsa , p_plaintext , EVP_PKEY_encrypt , EVP_PKEY_encrypt_init , 1 /* public */ , 1 /* is_encrypt */ );
1152+ RETVAL = rsa_crypt (p_rsa , p_plaintext , EVP_PKEY_encrypt , EVP_PKEY_encrypt_init , 1 /* is_encrypt */ );
11511153#else
1152- RETVAL = rsa_crypt (p_rsa , p_plaintext , RSA_public_encrypt , 1 /* public */ , 1 /* is_encrypt */ );
1154+ RETVAL = rsa_crypt (p_rsa , p_plaintext , RSA_public_encrypt , 1 /* is_encrypt */ );
11531155#endif
11541156 OUTPUT :
11551157 RETVAL
@@ -1164,9 +1166,9 @@ decrypt(p_rsa, p_ciphertext)
11641166 croak ("Public keys cannot decrypt" );
11651167 }
11661168#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1167- RETVAL = rsa_crypt (p_rsa , p_ciphertext , EVP_PKEY_decrypt , EVP_PKEY_decrypt_init , 0 /* private */ , 1 /* is_encrypt */ );
1169+ RETVAL = rsa_crypt (p_rsa , p_ciphertext , EVP_PKEY_decrypt , EVP_PKEY_decrypt_init , 1 /* is_encrypt */ );
11681170#else
1169- RETVAL = rsa_crypt (p_rsa , p_ciphertext , RSA_private_decrypt , 0 /* private */ , 1 /* is_encrypt */ );
1171+ RETVAL = rsa_crypt (p_rsa , p_ciphertext , RSA_private_decrypt , 1 /* is_encrypt */ );
11701172#endif
11711173 OUTPUT :
11721174 RETVAL
@@ -1180,10 +1182,11 @@ private_encrypt(p_rsa, p_plaintext)
11801182 {
11811183 croak ("Public keys cannot private_encrypt" );
11821184 }
1185+ check_max_message_length (p_rsa , sv_len (p_plaintext ));
11831186#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1184- RETVAL = rsa_crypt (p_rsa , p_plaintext , EVP_PKEY_sign , EVP_PKEY_sign_init , 0 /* private */ , 0 /* is_encrypt */ );
1187+ RETVAL = rsa_crypt (p_rsa , p_plaintext , EVP_PKEY_sign , EVP_PKEY_sign_init , 0 /* is_encrypt */ );
11851188#else
1186- RETVAL = rsa_crypt (p_rsa , p_plaintext , RSA_private_encrypt , 0 /* private */ , 0 /* is_encrypt */ );
1189+ RETVAL = rsa_crypt (p_rsa , p_plaintext , RSA_private_encrypt , 0 /* is_encrypt */ );
11871190#endif
11881191 OUTPUT :
11891192 RETVAL
@@ -1194,9 +1197,9 @@ public_decrypt(p_rsa, p_ciphertext)
11941197 SV * p_ciphertext ;
11951198 CODE :
11961199#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1197- RETVAL = rsa_crypt (p_rsa , p_ciphertext , EVP_PKEY_verify_recover , EVP_PKEY_verify_recover_init , 1 /*public */ , 0 /* is_encrypt */ );
1200+ RETVAL = rsa_crypt (p_rsa , p_ciphertext , EVP_PKEY_verify_recover , EVP_PKEY_verify_recover_init , 0 /* is_encrypt */ );
11981201#else
1199- RETVAL = rsa_crypt (p_rsa , p_ciphertext , RSA_public_decrypt , 1 /* public */ , 0 /* is_encrypt */ );
1202+ RETVAL = rsa_crypt (p_rsa , p_ciphertext , RSA_public_decrypt , 0 /* is_encrypt */ );
12001203#endif
12011204 OUTPUT :
12021205 RETVAL
0 commit comments