Skip to content

Commit 569a79c

Browse files
authored
Merge pull request #165 from timlegge/remove-public
rsa_crypt no longer needs public/private arguement
2 parents 8ae30c7 + dcd1593 commit 569a79c

1 file changed

Lines changed: 39 additions & 36 deletions

File tree

RSA.xs

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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

406429
SV* 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

411434
SV* 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

Comments
 (0)