File Coverage

RSA.xs
Criterion Covered Total %
statement 315 334 94.3
branch 147 258 56.9
condition n/a
subroutine n/a
pod n/a
total 462 592 78.0


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4              
5             #include
6             #include
7             #include
8             #include
9             #include
10             #include
11             #include
12             #include
13             #if OPENSSL_VERSION_NUMBER >= 0x10000000 && OPENSSL_VERSION_NUMBER < 0x30000000
14             #ifndef LIBRESSL_VERSION_NUMBER
15             #include
16             #endif
17             #endif
18             #include
19             #include
20             #include
21             #include
22             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
23             #include
24             #include
25             #include
26             #endif
27              
28             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
29             #define UNSIGNED_CHAR unsigned char
30             #define SIZE_T_INT size_t
31             #define SIZE_T_UNSIGNED_INT size_t
32             #define EVP_PKEY EVP_PKEY
33             #define EVP_PKEY_free(p) EVP_PKEY_free(p)
34             #define EVP_PKEY_get_size(p) EVP_PKEY_get_size(p)
35             #define PEM_read_bio_PrivateKey PEM_read_bio_PrivateKey
36             #define PEM_read_bio_RSAPublicKey PEM_read_bio_PUBKEY
37             #define PEM_read_bio_RSA_PUBKEY PEM_read_bio_PUBKEY
38             #define PEM_write_bio_PUBKEY(o,p) PEM_write_bio_PUBKEY(o,p);
39             #define PEM_write_bio_PrivateKey_traditional(m, n, o, p, q, r, s) PEM_write_bio_PrivateKey_traditional(m, n, o, p, q, r, s)
40             #else
41             #define UNSIGNED_CHAR char
42             #define SIZE_T_INT int
43             #define SIZE_T_UNSIGNED_INT unsigned int
44             #define EVP_PKEY RSA
45             #define EVP_PKEY_free(p) RSA_free(p)
46             #define EVP_PKEY_get_size(p) RSA_size(p)
47             #define PEM_read_bio_PrivateKey PEM_read_bio_RSAPrivateKey
48             #define PEM_read_bio_RSAPublicKey PEM_read_bio_RSAPublicKey
49             #define PEM_read_bio_RSA_PUBKEY PEM_read_bio_RSA_PUBKEY
50             #define PEM_write_bio_PUBKEY(o,p) PEM_write_bio_RSA_PUBKEY(o,p)
51             #define PEM_write_bio_PrivateKey_traditional(m, n, o, p, q, r, s) PEM_write_bio_RSAPrivateKey(m, n , o, p, q, r, s)
52             #endif
53              
54             typedef struct
55             {
56             EVP_PKEY* rsa;
57             int padding;
58             int hashMode;
59             } rsaData;
60              
61             /* Key names for the rsa hash structure */
62              
63             #define KEY_KEY "_Key"
64             #define PADDING_KEY "_Padding"
65             #define HASH_KEY "_Hash_Mode"
66              
67             #define PACKAGE_NAME "Crypt::OpenSSL::RSA"
68              
69             #define OLD_CRUFTY_SSL_VERSION (OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x03050000fL))
70              
71 8           void croakSsl(char* p_file, int p_line)
72             {
73             const char* errorReason;
74             /* Just return the top error on the stack */
75 8           errorReason = ERR_reason_error_string(ERR_get_error());
76 8           ERR_clear_error();
77 8           croak("%s:%d: OpenSSL error: %s", p_file, p_line, errorReason);
78             }
79              
80             #define CHECK_OPEN_SSL(p_result) if (!(p_result)) croakSsl(__FILE__, __LINE__);
81              
82             #define PACKAGE_CROAK(p_message) croak("%s", (p_message))
83             #define CHECK_NEW(p_var, p_size, p_type) \
84             if (New(0, p_var, p_size, p_type) == NULL) \
85             { PACKAGE_CROAK("unable to alloc buffer"); }
86              
87             #define THROW(p_result) if (!(p_result)) { error = 1; goto err; }
88              
89 34           char _is_private(rsaData* p_rsa)
90             {
91 34           char ret = 0;
92             #if OLD_CRUFTY_SSL_VERSION
93             const BIGNUM* d;
94             d = p_rsa->rsa->d;
95             ret = (d != NULL);
96             #else
97             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
98 34           BIGNUM* d = NULL;
99 34           EVP_PKEY_get_bn_param(p_rsa->rsa, OSSL_PKEY_PARAM_RSA_D, &d);
100 34           ret = (d != NULL);
101 34           BN_clear_free(d);
102             #else
103             const BIGNUM* d = NULL;
104             RSA_get0_key(p_rsa->rsa, NULL, NULL, &d);
105             ret = (d != NULL);
106             #endif
107             #endif
108 34           return ret;
109             }
110              
111 20           SV* make_rsa_obj(SV* p_proto, EVP_PKEY* p_rsa)
112             {
113             rsaData* rsa;
114              
115 20 50         CHECK_NEW(rsa, 1, rsaData);
116 20           rsa->rsa = p_rsa;
117 20           rsa->hashMode = NID_sha1;
118 20           rsa->padding = RSA_PKCS1_OAEP_PADDING;
119 20 50         return sv_bless(
120             newRV_noinc(newSViv((IV) rsa)),
121             (SvROK(p_proto) ? SvSTASH(SvRV(p_proto)) : gv_stashsv(p_proto, 1)));
122             }
123              
124 63           int get_digest_length(int hash_method)
125             {
126 63           switch(hash_method)
127             {
128 9           case NID_md5:
129 9           return MD5_DIGEST_LENGTH;
130             break;
131 9           case NID_sha1:
132 9           return SHA_DIGEST_LENGTH;
133             break;
134             #ifdef SHA512_DIGEST_LENGTH
135 9           case NID_sha224:
136 9           return SHA224_DIGEST_LENGTH;
137             break;
138 9           case NID_sha256:
139 9           return SHA256_DIGEST_LENGTH;
140             break;
141 9           case NID_sha384:
142 9           return SHA384_DIGEST_LENGTH;
143             break;
144 9           case NID_sha512:
145 9           return SHA512_DIGEST_LENGTH;
146             break;
147             #endif
148 9           case NID_ripemd160:
149 9           return RIPEMD160_DIGEST_LENGTH;
150             break;
151             #ifdef WHIRLPOOL_DIGEST_LENGTH
152             case NID_whirlpool:
153             return WHIRLPOOL_DIGEST_LENGTH;
154             break;
155             #endif
156 0           default:
157 0           croak("Unknown digest hash mode %u", hash_method);
158             break;
159             }
160             }
161             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
162              
163 49           EVP_MD *get_md_bynid(int hash_method)
164             {
165 49           switch(hash_method)
166             {
167 7           case NID_md5:
168 7           return EVP_MD_fetch(NULL, "md5", NULL);
169             break;
170 7           case NID_sha1:
171 7           return EVP_MD_fetch(NULL, "sha1", NULL);
172             break;
173             #ifdef SHA512_DIGEST_LENGTH
174 7           case NID_sha224:
175 7           return EVP_MD_fetch(NULL, "sha224", NULL);
176             break;
177 7           case NID_sha256:
178 7           return EVP_MD_fetch(NULL, "sha256", NULL);
179             break;
180 7           case NID_sha384:
181 7           return EVP_MD_fetch(NULL, "sha384", NULL);
182             break;
183 7           case NID_sha512:
184 7           return EVP_MD_fetch(NULL, "sha512", NULL);
185             break;
186             #endif
187 7           case NID_ripemd160:
188 7           return EVP_MD_fetch(NULL, "ripemd160", NULL);
189             break;
190             #ifdef WHIRLPOOL_DIGEST_LENGTH
191             case NID_whirlpool:
192             return EVP_MD_fetch(NULL, "whirlpool", NULL);
193             break;
194             #endif
195 0           default:
196 0           croak("Unknown digest hash mode %u", hash_method);
197             break;
198             }
199             }
200             #endif
201 55           unsigned char* get_message_digest(SV* text_SV, int hash_method)
202             {
203             STRLEN text_length;
204             unsigned char* text;
205             unsigned char *md;
206             static unsigned char m[EVP_MAX_MD_SIZE];
207 55           text = (unsigned char*) SvPV(text_SV, text_length);
208 55           md = m;
209              
210 55           switch(hash_method)
211             {
212 8           case NID_md5:
213             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
214 8 50         return EVP_Q_digest(NULL, "MD5", NULL, text, text_length, md, NULL) ? md : NULL;
215             #else
216             return MD5(text, text_length, md);
217             #endif
218             break;
219 8           case NID_sha1:
220 8           return SHA1(text, text_length, md);
221             break;
222             #ifdef SHA512_DIGEST_LENGTH
223 8           case NID_sha224:
224 8           return SHA224(text, text_length, md);
225             break;
226 8           case NID_sha256:
227 8           return SHA256(text, text_length, md);
228             break;
229 8           case NID_sha384:
230 8           return SHA384(text, text_length, md);
231             break;
232 8           case NID_sha512:
233 8           return SHA512(text, text_length, md);
234             break;
235             #endif
236 7           case NID_ripemd160:
237             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
238 7 50         return EVP_Q_digest(NULL, "RIPEMD160", NULL, text, text_length, md, NULL) ? md : NULL;
239             #else
240             return RIPEMD160(text, text_length, md);
241             #endif
242             break;
243             #ifdef WHIRLPOOL_DIGEST_LENGTH
244             case NID_whirlpool:
245             return WHIRLPOOL(text, text_length, md);
246             break;
247             #endif
248 0           default:
249 0           croak("Unknown digest hash mode %u", hash_method);
250             break;
251             }
252             }
253              
254 64           SV* cor_bn2sv(const BIGNUM* p_bn)
255             {
256             return p_bn != NULL
257 41           ? sv_2mortal(newSViv((IV) BN_dup(p_bn)))
258 105 100         : &PL_sv_undef;
259             }
260              
261 17           SV* extractBioString(BIO* p_stringBio)
262             {
263             SV* sv;
264             char* datap;
265 17           long datasize = 0;
266              
267 17 50         CHECK_OPEN_SSL(BIO_flush(p_stringBio) == 1);
268              
269 17           datasize = BIO_get_mem_data(p_stringBio, &datap);
270 17           sv = newSVpv(datap, datasize);
271              
272 17 50         CHECK_OPEN_SSL(BIO_set_close(p_stringBio, BIO_CLOSE) == 1);
273 17           BIO_free(p_stringBio);
274 17           return sv;
275             }
276              
277 11           EVP_PKEY* _load_rsa_key(SV* p_keyStringSv,
278             EVP_PKEY*(*p_loader)(BIO *, EVP_PKEY**, pem_password_cb*, void*),
279             SV* p_passphaseSv)
280             {
281             STRLEN keyStringLength;
282             char* keyString;
283 11           UNSIGNED_CHAR *passphase = NULL;
284              
285             EVP_PKEY* rsa;
286             BIO* stringBIO;
287              
288 11           keyString = SvPV(p_keyStringSv, keyStringLength);
289              
290 11 100         if (SvPOK(p_passphaseSv)) {
291 4           passphase = SvPV_nolen(p_passphaseSv);
292             }
293              
294 11 50         CHECK_OPEN_SSL(stringBIO = BIO_new_mem_buf(keyString, keyStringLength));
295              
296 11           rsa = p_loader(stringBIO, NULL, NULL, passphase);
297              
298 11 50         CHECK_OPEN_SSL(BIO_set_close(stringBIO, BIO_CLOSE) == 1);
299 11           BIO_free(stringBIO);
300              
301 11 50         CHECK_OPEN_SSL(rsa);
302 11           return rsa;
303             }
304             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
305              
306 15           SV* rsa_crypt(rsaData* p_rsa, SV* p_from,
307             int (*p_crypt)(EVP_PKEY_CTX*, unsigned char*, size_t*, const unsigned char*, size_t),
308             int (*init_crypt)(EVP_PKEY_CTX*), int public)
309             #else
310              
311             SV* rsa_crypt(rsaData* p_rsa, SV* p_from,
312             int (*p_crypt)(int, const unsigned char*, unsigned char*, RSA*, int))
313             #endif
314             {
315             STRLEN from_length;
316             SIZE_T_INT to_length;
317             int size;
318             unsigned char* from;
319             UNSIGNED_CHAR *to;
320             SV* sv;
321              
322 15           from = (unsigned char*) SvPV(p_from, from_length);
323 15           size = EVP_PKEY_get_size(p_rsa->rsa);
324 15 50         CHECK_NEW(to, size, UNSIGNED_CHAR);
325             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
326              
327 15 50         if(p_rsa->padding == RSA_PKCS1_PSS_PADDING)
328 0           croak("PKCS#1 v2.1 RSA-PSS cannot be used for encryption operations call \"use_pkcs1_oaep_padding\" instead.");
329              
330             EVP_PKEY_CTX *ctx;
331              
332 15           OSSL_LIB_CTX *ossllibctx = OSSL_LIB_CTX_new();
333 15 100         if (public) {
334 8           ctx = EVP_PKEY_CTX_new_from_pkey(ossllibctx, (EVP_PKEY* )p_rsa->rsa, NULL);
335             } else {
336 7           ctx = EVP_PKEY_CTX_new((EVP_PKEY* )p_rsa->rsa, NULL);
337             }
338              
339 15 50         CHECK_OPEN_SSL(ctx);
340              
341 15 50         CHECK_OPEN_SSL(init_crypt(ctx) == 1);
342 15 50         CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0);
343 15 50         CHECK_OPEN_SSL(p_crypt(ctx, NULL, &to_length, from, from_length) == 1);
344 15 50         CHECK_OPEN_SSL(p_crypt(ctx, to, &to_length, from, from_length) == 1);
345              
346 15           EVP_PKEY_CTX_free(ctx);
347             #else
348             to_length = p_crypt(
349             from_length, from, (unsigned char*) to, p_rsa->rsa, p_rsa->padding);
350             #endif
351             if (to_length < 0)
352             {
353             Safefree(to);
354             CHECK_OPEN_SSL(0);
355             }
356 15           sv = newSVpv((char* ) to, to_length);
357 15           Safefree(to);
358 15           return sv;
359             }
360              
361             MODULE = Crypt::OpenSSL::RSA PACKAGE = Crypt::OpenSSL::RSA
362             PROTOTYPES: DISABLE
363              
364             BOOT:
365             #if OPENSSL_VERSION_NUMBER < 0x10100000L
366             # might introduce memory leak without calling EVP_cleanup() on exit
367             # see https://wiki.openssl.org/index.php/Library_Initialization
368             ERR_load_crypto_strings();
369             OpenSSL_add_all_algorithms();
370             #else
371             # NOOP
372             #endif
373              
374             SV*
375             new_private_key(proto, key_string_SV, passphase_SV=&PL_sv_undef)
376             SV* proto;
377             SV* key_string_SV;
378             SV* passphase_SV;
379             CODE:
380 7           RETVAL = make_rsa_obj(
381             proto, _load_rsa_key(key_string_SV, PEM_read_bio_PrivateKey, passphase_SV));
382             OUTPUT:
383             RETVAL
384              
385             SV*
386             _new_public_key_pkcs1(proto, key_string_SV)
387             SV* proto;
388             SV* key_string_SV;
389             CODE:
390 3           RETVAL = make_rsa_obj(
391             proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSAPublicKey, &PL_sv_undef));
392             OUTPUT:
393             RETVAL
394              
395             SV*
396             _new_public_key_x509(proto, key_string_SV)
397             SV* proto;
398             SV* key_string_SV;
399             CODE:
400 1           RETVAL = make_rsa_obj(
401             proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSA_PUBKEY, &PL_sv_undef));
402             OUTPUT:
403             RETVAL
404              
405             void
406             DESTROY(p_rsa)
407             rsaData* p_rsa;
408             CODE:
409 20           EVP_PKEY_free(p_rsa->rsa);
410 20           Safefree(p_rsa);
411              
412             SV*
413             get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_undef)
414             rsaData* p_rsa;
415             SV* passphase_SV;
416             SV* cipher_name_SV;
417             PREINIT:
418             BIO* stringBIO;
419 9           char* passphase = NULL;
420 9           STRLEN passphaseLength = 0;
421             char* cipher_name;
422 9 50         const EVP_CIPHER* enc = NULL;
423             CODE:
424 9 100         if (SvPOK(cipher_name_SV) && !SvPOK(passphase_SV)) {
    50          
425 0           croak("Passphrase is required for cipher");
426             }
427 9 100         if (SvPOK(passphase_SV)) {
428 3           passphase = SvPV(passphase_SV, passphaseLength);
429 3 100         if (SvPOK(cipher_name_SV)) {
430 2           cipher_name = SvPV_nolen(cipher_name_SV);
431             }
432             else {
433 1           cipher_name = "des3";
434             }
435 3           enc = EVP_get_cipherbyname(cipher_name);
436 3 50         if (enc == NULL) {
437 0           croak("Unsupported cipher: %s", cipher_name);
438             }
439             }
440              
441 9 50         CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem()));
442 9           PEM_write_bio_PrivateKey_traditional(
443             stringBIO, p_rsa->rsa, enc, (unsigned char* ) passphase, passphaseLength, NULL, NULL);
444 9           RETVAL = extractBioString(stringBIO);
445              
446             OUTPUT:
447             RETVAL
448              
449             SV*
450             get_public_key_string(p_rsa)
451             rsaData* p_rsa;
452             PREINIT:
453             BIO* stringBIO;
454             CODE:
455 5 50         CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem()));
456             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
457 5           OSSL_ENCODER_CTX *ctx = NULL;
458              
459 5           ctx = OSSL_ENCODER_CTX_new_for_pkey(p_rsa->rsa, OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
460             "PEM", "PKCS1", NULL);
461 5 50         CHECK_OPEN_SSL(ctx != NULL && OSSL_ENCODER_CTX_get_num_encoders(ctx));
    50          
462              
463 5 50         CHECK_OPEN_SSL(OSSL_ENCODER_to_bio(ctx, stringBIO) == 1);
464              
465 5           OSSL_ENCODER_CTX_free(ctx);
466             #else
467             PEM_write_bio_RSAPublicKey(stringBIO, p_rsa->rsa);
468             #endif
469 5           RETVAL = extractBioString(stringBIO);
470              
471             OUTPUT:
472             RETVAL
473              
474             SV*
475             get_public_key_x509_string(p_rsa)
476             rsaData* p_rsa;
477             PREINIT:
478             BIO* stringBIO;
479             CODE:
480 3 50         CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem()));
481 3           PEM_write_bio_PUBKEY(stringBIO, p_rsa->rsa);
482 3           RETVAL = extractBioString(stringBIO);
483              
484             OUTPUT:
485             RETVAL
486              
487             SV*
488             generate_key(proto, bitsSV, exponent = 65537)
489             SV* proto;
490             SV* bitsSV;
491             unsigned long exponent;
492             PREINIT:
493 3 50         EVP_PKEY* rsa = NULL;
494             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
495             EVP_PKEY_CTX *ctx;
496             #endif
497             CODE:
498             BIGNUM *e;
499 3           e = BN_new();
500 3           BN_set_word(e, exponent);
501             #if OPENSSL_VERSION_NUMBER < 0x00908000L
502             rsa = RSA_generate_key(SvIV(bitsSV), exponent, NULL, NULL);
503             CHECK_OPEN_SSL(rsa != NULL);
504             #endif
505             #if OPENSSL_VERSION_NUMBER >= 0x00908000L && OPENSSL_VERSION_NUMBER < 0x30000000L
506             rsa = RSA_new();
507             if (!RSA_generate_key_ex(rsa, SvIV(bitsSV), e, NULL))
508             croak("Unable to generate a key");
509             BN_free(e);
510             CHECK_OPEN_SSL(rsa != NULL);
511             #endif
512             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
513 3           ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
514              
515 3 50         CHECK_OPEN_SSL(ctx);
516 3 50         CHECK_OPEN_SSL(EVP_PKEY_keygen_init(ctx) == 1);
517 3 50         CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, SvIV(bitsSV)) > 0);
518 3 50         CHECK_OPEN_SSL(EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, e) >0);
519 3 50         CHECK_OPEN_SSL(EVP_PKEY_generate(ctx, &rsa) == 1);
520 3 50         CHECK_OPEN_SSL(rsa != NULL);
521              
522 3           e = NULL;
523 3           BN_free(e);
524 3           EVP_PKEY_CTX_free(ctx);
525             #endif
526 3 50         CHECK_OPEN_SSL(rsa);
527 3           RETVAL = make_rsa_obj(proto, rsa);
528             OUTPUT:
529             RETVAL
530              
531              
532             SV*
533             _new_key_from_parameters(proto, n, e, d, p, q)
534             SV* proto;
535             BIGNUM* n;
536             BIGNUM* e;
537             BIGNUM* d;
538             BIGNUM* p;
539             BIGNUM* q;
540             PREINIT:
541 8           EVP_PKEY* rsa = NULL;
542 8           BN_CTX* ctx = NULL;
543 8           BIGNUM* p_minus_1 = NULL;
544 8           BIGNUM* q_minus_1 = NULL;
545 8           BIGNUM* dmp1 = NULL;
546 8           BIGNUM* dmq1 = NULL;
547 8           BIGNUM* iqmp = NULL;
548             int error;
549             CODE:
550             {
551 8 50         if (!(n && e))
    50          
552             {
553 0           croak("At least a modulus and public key must be provided");
554             }
555             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
556 8           OSSL_PARAM *params = NULL;
557 8           EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
558 8 50         CHECK_OPEN_SSL(pctx != NULL);
559 8 50         CHECK_OPEN_SSL(EVP_PKEY_fromdata_init(pctx) > 0);
560 8           OSSL_PARAM_BLD *params_build = OSSL_PARAM_BLD_new();
561 8 50         CHECK_OPEN_SSL(params_build)
562             #else
563             CHECK_OPEN_SSL(rsa = RSA_new());
564             #endif
565             #if OLD_CRUFTY_SSL_VERSION
566             rsa->n = n;
567             rsa->e = e;
568             #endif
569             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
570 8 50         CHECK_OPEN_SSL(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_N, n));
571 8 50         CHECK_OPEN_SSL(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_E, e));
572             #endif
573 8 100         if (p || q)
    100          
574 4           {
575 6           error = 0;
576 6 50         THROW(ctx = BN_CTX_new());
577 6 100         if (!p)
578             {
579 3 50         THROW(p = BN_new());
580 3 50         THROW(BN_div(p, NULL, n, q, ctx));
581             }
582 3 100         else if (!q)
583             {
584 2           q = BN_new();
585 2 50         THROW(BN_div(q, NULL, n, p, ctx));
586             }
587             #if OLD_CRUFTY_SSL_VERSION
588             rsa->p = p;
589             rsa->q = q;
590             #else
591             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
592             #else
593             THROW(RSA_set0_factors(rsa, p, q));
594             #endif
595             #endif
596 6 50         THROW(p_minus_1 = BN_new());
597 6 50         THROW(BN_sub(p_minus_1, p, BN_value_one()));
598 6 50         THROW(q_minus_1 = BN_new());
599 6 50         THROW(BN_sub(q_minus_1, q, BN_value_one()));
600 6 100         if (!d)
601             {
602 1 50         THROW(d = BN_new());
603 1 50         THROW(BN_mul(d, p_minus_1, q_minus_1, ctx));
604 1 50         THROW(BN_mod_inverse(d, e, d, ctx));
605             }
606             #if OLD_CRUFTY_SSL_VERSION
607             rsa->d = d;
608             #else
609             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
610 6 50         THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_D, d));
611 6 50         THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_FACTOR1, p));
612 6 50         THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_FACTOR2, q));
613             #else
614             THROW(RSA_set0_key(rsa, n, e, d));
615             #endif
616             #endif
617 6 50         THROW(dmp1 = BN_new());
618 6 50         THROW(BN_mod(dmp1, d, p_minus_1, ctx));
619 6 50         THROW(dmq1 = BN_new());
620 6 50         THROW(BN_mod(dmq1, d, q_minus_1, ctx));
621 6 50         THROW(iqmp = BN_new());
622 6 50         THROW(BN_mod_inverse(iqmp, q, p, ctx));
623             #if OLD_CRUFTY_SSL_VERSION
624             rsa->dmp1 = dmp1;
625             rsa->dmq1 = dmq1;
626             rsa->iqmp = iqmp;
627             #else
628             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
629 6 50         THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1));
630 6 50         THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1));
631 6 50         THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp));
632              
633 6           params = OSSL_PARAM_BLD_to_param(params_build);
634 6 50         THROW(params != NULL);
635              
636 6           int status = EVP_PKEY_fromdata(pctx, &rsa, EVP_PKEY_KEYPAIR, params);
637 6 50         THROW( status > 0 && rsa != NULL );
    50          
638 6           EVP_PKEY_CTX* test_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, rsa, NULL);
639 6 100         THROW(EVP_PKEY_check(test_ctx) == 1);
640             #else
641             THROW(RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp));
642             #endif
643             #endif
644 4           dmp1 = dmq1 = iqmp = NULL;
645             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
646 4           OSSL_PARAM_BLD_free(params_build);
647 4           OSSL_PARAM_free(params);
648             #else
649             THROW(RSA_check_key(rsa) == 1);
650             #endif
651             }
652             else
653             {
654             #if OLD_CRUFTY_SSL_VERSION
655             rsa->d = d;
656             #else
657             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
658 2 100         if(d != NULL)
659 1 50         THROW(OSSL_PARAM_BLD_push_BN(params_build, OSSL_PKEY_PARAM_RSA_D, d));
660 2           params = OSSL_PARAM_BLD_to_param(params_build);
661 2 50         THROW(params != NULL);
662              
663 2           int status = EVP_PKEY_fromdata(pctx, &rsa, EVP_PKEY_KEYPAIR, params);
664 2 50         THROW( status > 0 && rsa != NULL );
    50          
665             #else
666             CHECK_OPEN_SSL(RSA_set0_key(rsa, n, e, d));
667             #endif
668             #endif
669             }
670              
671 6           RETVAL = make_rsa_obj(proto, rsa);
672 6 50         if(RETVAL)
673 6           goto end;
674              
675 0           err:
676             //if (p) BN_clear_free(p);
677 2 50         if (p_minus_1) BN_clear_free(p_minus_1);
678             //if (q) BN_clear_free(q);
679             //if (d) BN_clear_free(d);
680 2 50         if (q_minus_1) BN_clear_free(q_minus_1);
681 2 50         if (dmp1) BN_clear_free(dmp1);
682 2 50         if (dmq1) BN_clear_free(dmq1);
683 2 50         if (iqmp) BN_clear_free(iqmp);
684 2 50         if (ctx) BN_CTX_free(ctx);
685 2 50         if (error)
686             {
687 2           EVP_PKEY_free(rsa);
688 2           CHECK_OPEN_SSL(0);
689             }
690             }
691 6           end:
692              
693             OUTPUT:
694             RETVAL
695              
696             void
697             _get_key_parameters(p_rsa)
698             rsaData* p_rsa;
699             PREINIT:
700             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
701 8           BIGNUM* n = NULL;
702 8           BIGNUM* e = NULL;
703 8           BIGNUM* d = NULL;
704 8           BIGNUM* p = NULL;
705 8           BIGNUM* q = NULL;
706 8           BIGNUM* dmp1 = NULL;
707 8           BIGNUM* dmq1 = NULL;
708 8 50         BIGNUM* iqmp = NULL;
709             #else
710             const BIGNUM* n;
711             const BIGNUM* e;
712             const BIGNUM* d;
713             const BIGNUM* p;
714             const BIGNUM* q;
715             const BIGNUM* dmp1;
716             const BIGNUM* dmq1;
717             const BIGNUM* iqmp;
718             #endif
719             PPCODE:
720             {
721             EVP_PKEY* rsa;
722 8           rsa = p_rsa->rsa;
723             #if OLD_CRUFTY_SSL_VERSION
724             n = rsa->n;
725             e = rsa->e;
726             d = rsa->d;
727             p = rsa->p;
728             q = rsa->q;
729             dmp1 = rsa->dmp1;
730             dmq1 = rsa->dmq1;
731             iqmp = rsa->iqmp;
732             #else
733             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
734 8           EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_N, &n);
735 8           EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_E, &e);
736 8           EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_D, &d);
737 8           EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_FACTOR1, &p);
738 8           EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_FACTOR2, &q);
739 8           EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT1, &dmp1);
740 8           EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_EXPONENT2, &dmq1);
741 8           EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &iqmp);
742             #else
743             RSA_get0_key(rsa, &n, &e, &d);
744             RSA_get0_factors(rsa, &p, &q);
745             RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
746             #endif
747             #endif
748 8 50         XPUSHs(cor_bn2sv(n));
749 8 50         XPUSHs(cor_bn2sv(e));
750 8 50         XPUSHs(cor_bn2sv(d));
751 8 50         XPUSHs(cor_bn2sv(p));
752 8 50         XPUSHs(cor_bn2sv(q));
753 8 50         XPUSHs(cor_bn2sv(dmp1));
754 8 50         XPUSHs(cor_bn2sv(dmq1));
755 8 50         XPUSHs(cor_bn2sv(iqmp));
756             }
757              
758             SV*
759             encrypt(p_rsa, p_plaintext)
760             rsaData* p_rsa;
761             SV* p_plaintext;
762             CODE:
763             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
764 6           RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_encrypt, EVP_PKEY_encrypt_init, 1 /* public */);
765             #else
766             RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_public_encrypt);
767             #endif
768             OUTPUT:
769             RETVAL
770              
771             SV*
772             decrypt(p_rsa, p_ciphertext)
773             rsaData* p_rsa;
774             SV* p_ciphertext;
775             CODE:
776 6 100         if (!_is_private(p_rsa))
777             {
778 1           croak("Public keys cannot decrypt");
779             }
780             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
781 5           RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_decrypt, EVP_PKEY_decrypt_init, 0 /* private */);
782             #else
783             RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_private_decrypt);
784             #endif
785             OUTPUT:
786             RETVAL
787              
788             SV*
789             private_encrypt(p_rsa, p_plaintext)
790             rsaData* p_rsa;
791             SV* p_plaintext;
792             CODE:
793 3 100         if (!_is_private(p_rsa))
794             {
795 1           croak("Public keys cannot private_encrypt");
796             }
797             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
798 2           RETVAL = rsa_crypt(p_rsa, p_plaintext, EVP_PKEY_sign, EVP_PKEY_sign_init, 0 /* private */);
799             #else
800             RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_private_encrypt);
801             #endif
802             OUTPUT:
803             RETVAL
804              
805             SV*
806             public_decrypt(p_rsa, p_ciphertext)
807             rsaData* p_rsa;
808             SV* p_ciphertext;
809             CODE:
810             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
811 2           RETVAL = rsa_crypt(p_rsa, p_ciphertext, EVP_PKEY_verify_recover, EVP_PKEY_verify_recover_init, 1 /*public */);
812             #else
813             RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_public_decrypt);
814             #endif
815             OUTPUT:
816             RETVAL
817              
818             int
819             size(p_rsa)
820             rsaData* p_rsa;
821             CODE:
822 4           RETVAL = EVP_PKEY_get_size(p_rsa->rsa);
823             OUTPUT:
824             RETVAL
825              
826             int
827             check_key(p_rsa)
828             rsaData* p_rsa;
829             CODE:
830 2 100         if (!_is_private(p_rsa))
831             {
832 1           croak("Public keys cannot be checked");
833             }
834             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
835 1           EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_pkey(NULL, p_rsa->rsa, NULL);
836 1           RETVAL = EVP_PKEY_private_check(pctx);
837             #else
838             RETVAL = RSA_check_key(p_rsa->rsa);
839             #endif
840             OUTPUT:
841             RETVAL
842              
843             # Seed the PRNG with user-provided bytes; returns true if the
844             # seeding was sufficient.
845              
846             int
847             _random_seed(random_bytes_SV)
848             SV* random_bytes_SV;
849             PREINIT:
850             STRLEN random_bytes_length;
851             char* random_bytes;
852             CODE:
853 0           random_bytes = SvPV(random_bytes_SV, random_bytes_length);
854 0           RAND_seed(random_bytes, random_bytes_length);
855 0           RETVAL = RAND_status();
856             OUTPUT:
857             RETVAL
858              
859             # Returns true if the PRNG has enough seed data
860              
861             int
862             _random_status()
863             CODE:
864 1           RETVAL = RAND_status();
865             OUTPUT:
866             RETVAL
867              
868             void
869             use_md5_hash(p_rsa)
870             rsaData* p_rsa;
871             CODE:
872 4           p_rsa->hashMode = NID_md5;
873              
874             void
875             use_sha1_hash(p_rsa)
876             rsaData* p_rsa;
877             CODE:
878 4           p_rsa->hashMode = NID_sha1;
879              
880             #ifdef SHA512_DIGEST_LENGTH
881              
882             void
883             use_sha224_hash(p_rsa)
884             rsaData* p_rsa;
885             CODE:
886 4           p_rsa->hashMode = NID_sha224;
887              
888             void
889             use_sha256_hash(p_rsa)
890             rsaData* p_rsa;
891             CODE:
892 4           p_rsa->hashMode = NID_sha256;
893              
894             void
895             use_sha384_hash(p_rsa)
896             rsaData* p_rsa;
897             CODE:
898 4           p_rsa->hashMode = NID_sha384;
899              
900             void
901             use_sha512_hash(p_rsa)
902             rsaData* p_rsa;
903             CODE:
904 4           p_rsa->hashMode = NID_sha512;
905              
906             #endif
907              
908             void
909             use_ripemd160_hash(p_rsa)
910             rsaData* p_rsa;
911             CODE:
912 2           p_rsa->hashMode = NID_ripemd160;
913              
914             #ifdef WHIRLPOOL_DIGEST_LENGTH
915              
916             void
917             use_whirlpool_hash(p_rsa)
918             rsaData* p_rsa;
919             CODE:
920             p_rsa->hashMode = NID_whirlpool;
921              
922             #endif
923              
924             void
925             use_no_padding(p_rsa)
926             rsaData* p_rsa;
927             CODE:
928 3           p_rsa->padding = RSA_NO_PADDING;
929              
930             void
931             use_pkcs1_padding(p_rsa)
932             rsaData* p_rsa;
933             CODE:
934 0           croak("PKCS#1 1.5 is disabled as it is known to be vulnerable to marvin attacks.");
935              
936             void
937             use_pkcs1_oaep_padding(p_rsa)
938             rsaData* p_rsa;
939             CODE:
940 4           p_rsa->padding = RSA_PKCS1_OAEP_PADDING;
941              
942             void
943             use_pkcs1_pss_padding(p_rsa)
944             rsaData* p_rsa;
945             CODE:
946 2           p_rsa->padding = RSA_PKCS1_PSS_PADDING;
947              
948             #if OPENSSL_VERSION_NUMBER < 0x30000000L
949              
950             void
951             use_sslv23_padding(p_rsa)
952             rsaData* p_rsa;
953             CODE:
954             p_rsa->padding = RSA_SSLV23_PADDING;
955              
956             #endif
957              
958             # Sign text. Returns the signature.
959              
960             SV*
961             sign(p_rsa, text_SV)
962             rsaData* p_rsa;
963             SV* text_SV;
964             PREINIT:
965             UNSIGNED_CHAR *signature;
966             unsigned char* digest;
967             SIZE_T_UNSIGNED_INT signature_length;
968             CODE:
969             {
970 21 100         if (!_is_private(p_rsa))
971             {
972 1           croak("Public keys cannot sign messages");
973             }
974 20 50         CHECK_NEW(signature, EVP_PKEY_get_size(p_rsa->rsa), UNSIGNED_CHAR);
975              
976 20 50         CHECK_OPEN_SSL(digest = get_message_digest(text_SV, p_rsa->hashMode));
977             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
978             EVP_PKEY_CTX *ctx;
979 20           ctx = EVP_PKEY_CTX_new(p_rsa->rsa, NULL /* no engine */);
980 20 50         CHECK_OPEN_SSL(ctx);
981 20 50         CHECK_OPEN_SSL(EVP_PKEY_sign_init(ctx));
982             /* FIXME: Issue setting padding in some cases */
983 20 100         CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0);
984              
985 14           EVP_MD* md = get_md_bynid(p_rsa->hashMode);
986 14 50         CHECK_OPEN_SSL(md != NULL);
987              
988             int md_status;
989 14 50         CHECK_OPEN_SSL((md_status = EVP_PKEY_CTX_set_signature_md(ctx, md)) > 0);
990 14 50         if (p_rsa->padding == RSA_PKCS1_PSS_PADDING) {
991 14 50         CHECK_OPEN_SSL((md_status = EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md)) > 0);
992 14 50         CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_DIGEST) > 0);
993             }
994 14 50         CHECK_OPEN_SSL(EVP_PKEY_sign(ctx, NULL, &signature_length, digest, get_digest_length(p_rsa->hashMode)) == 1);
995              
996             //signature = OPENSSL_malloc(signature_length);
997 14           Newx(signature, signature_length, char);
998              
999 14 50         CHECK_OPEN_SSL(signature);
1000              
1001 14 50         CHECK_OPEN_SSL(EVP_PKEY_sign(ctx, signature, &signature_length, digest, get_digest_length(p_rsa->hashMode)) == 1);
1002 14 50         CHECK_OPEN_SSL(signature);
1003             #else
1004             CHECK_OPEN_SSL(RSA_sign(p_rsa->hashMode,
1005             digest,
1006             get_digest_length(p_rsa->hashMode),
1007             (unsigned char*) signature,
1008             &signature_length,
1009             p_rsa->rsa));
1010             #endif
1011 14           RETVAL = newSVpvn((const char* )signature, signature_length);
1012 14           Safefree(signature);
1013             }
1014             OUTPUT:
1015             RETVAL
1016              
1017             # Verify signature. Returns true if correct, false otherwise.
1018              
1019             void
1020             verify(p_rsa, text_SV, sig_SV)
1021             rsaData* p_rsa;
1022             SV* text_SV;
1023             SV* sig_SV;
1024             PPCODE:
1025             {
1026             unsigned char* sig;
1027             unsigned char* digest;
1028             STRLEN sig_length;
1029              
1030 35           sig = (unsigned char*) SvPV(sig_SV, sig_length);
1031 35 50         if (EVP_PKEY_get_size(p_rsa->rsa) < sig_length)
1032             {
1033 0           croak("Signature longer than key");
1034             }
1035              
1036 35 50         CHECK_OPEN_SSL(digest = get_message_digest(text_SV, p_rsa->hashMode));
1037             #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1038             EVP_PKEY_CTX *ctx;
1039 35           ctx = EVP_PKEY_CTX_new(p_rsa->rsa, NULL /* no engine */);
1040 35 50         CHECK_OPEN_SSL(ctx);
1041 35 50         CHECK_OPEN_SSL(EVP_PKEY_verify_init(ctx) == 1);
1042             /* FIXME: Issue setting padding in some cases */
1043 35 50         CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_padding(ctx, p_rsa->padding) > 0);
1044              
1045 35           EVP_MD* md = get_md_bynid(p_rsa->hashMode);
1046 35 50         CHECK_OPEN_SSL(md != NULL);
1047              
1048             int md_status;
1049 35 50         CHECK_OPEN_SSL((md_status = EVP_PKEY_CTX_set_signature_md(ctx, md)) > 0);
1050 35 50         if (p_rsa->padding == RSA_PKCS1_PSS_PADDING) {
1051 35 50         CHECK_OPEN_SSL((md_status = EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md)) > 0);
1052 35 50         CHECK_OPEN_SSL(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_DIGEST) > 0);
1053             }
1054              
1055 35           switch (EVP_PKEY_verify(ctx, sig, sig_length, digest, get_digest_length(p_rsa->hashMode)))
1056             #else
1057             switch(RSA_verify(p_rsa->hashMode,
1058             digest,
1059             get_digest_length(p_rsa->hashMode),
1060             sig,
1061             sig_length,
1062             p_rsa->rsa))
1063             #endif
1064             {
1065 28           case 0:
1066 28           ERR_clear_error();
1067 35           XSRETURN_NO;
1068             break;
1069 7           case 1:
1070 7           XSRETURN_YES;
1071             break;
1072 0           default:
1073 0           CHECK_OPEN_SSL(0);
1074 0           break;
1075             }
1076             }
1077              
1078             int
1079             is_private(p_rsa)
1080             rsaData* p_rsa;
1081             CODE:
1082 2 50         RETVAL = _is_private(p_rsa);
1083             OUTPUT:
1084             RETVAL