File Coverage

RSA.xs
Criterion Covered Total %
statement 207 220 94.0
branch 95 160 59.3
condition n/a
subroutine n/a
pod n/a
total 302 380 79.4


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             #include
14             #include
15             #include
16             #include
17              
18             typedef struct
19             {
20             RSA* rsa;
21             int padding;
22             int hashMode;
23             } rsaData;
24              
25             /* Key names for the rsa hash structure */
26              
27             #define KEY_KEY "_Key"
28             #define PADDING_KEY "_Padding"
29             #define HASH_KEY "_Hash_Mode"
30              
31             #define PACKAGE_NAME "Crypt::OpenSSL::RSA"
32              
33             #define OLD_CRUFTY_SSL_VERSION (OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x03050000fL))
34              
35 2           void croakSsl(char* p_file, int p_line)
36             {
37             const char* errorReason;
38             /* Just return the top error on the stack */
39 2           errorReason = ERR_reason_error_string(ERR_get_error());
40 2           ERR_clear_error();
41 2           croak("%s:%d: OpenSSL error: %s", p_file, p_line, errorReason);
42             }
43              
44             #define CHECK_OPEN_SSL(p_result) if (!(p_result)) croakSsl(__FILE__, __LINE__);
45              
46             #define PACKAGE_CROAK(p_message) croak("%s", (p_message))
47             #define CHECK_NEW(p_var, p_size, p_type) \
48             if (New(0, p_var, p_size, p_type) == NULL) \
49             { PACKAGE_CROAK("unable to alloc buffer"); }
50              
51             #define THROW(p_result) if (!(p_result)) { error = 1; goto err; }
52              
53 30           char _is_private(rsaData* p_rsa)
54             {
55             const BIGNUM *d;
56             #if OLD_CRUFTY_SSL_VERSION
57 30           d = p_rsa->rsa->d;
58             #else
59             RSA_get0_key(p_rsa->rsa, NULL, NULL, &d);
60             #endif
61 30           return(d != NULL);
62             }
63              
64 20           SV* make_rsa_obj(SV* p_proto, RSA* p_rsa)
65             {
66             rsaData* rsa;
67              
68 20 50         CHECK_NEW(rsa, 1, rsaData);
69 20           rsa->rsa = p_rsa;
70 20           rsa->hashMode = NID_sha1;
71 20           rsa->padding = RSA_PKCS1_OAEP_PADDING;
72 20 50         return sv_bless(
73             newRV_noinc(newSViv((IV) rsa)),
74             (SvROK(p_proto) ? SvSTASH(SvRV(p_proto)) : gv_stashsv(p_proto, 1)));
75             }
76              
77 49           int get_digest_length(int hash_method)
78             {
79 49           switch(hash_method)
80             {
81             case NID_md5:
82 7           return MD5_DIGEST_LENGTH;
83             break;
84             case NID_sha1:
85 7           return SHA_DIGEST_LENGTH;
86             break;
87             #ifdef SHA512_DIGEST_LENGTH
88             case NID_sha224:
89 7           return SHA224_DIGEST_LENGTH;
90             break;
91             case NID_sha256:
92 7           return SHA256_DIGEST_LENGTH;
93             break;
94             case NID_sha384:
95 7           return SHA384_DIGEST_LENGTH;
96             break;
97             case NID_sha512:
98 7           return SHA512_DIGEST_LENGTH;
99             break;
100             #endif
101             case NID_ripemd160:
102 7           return RIPEMD160_DIGEST_LENGTH;
103             break;
104             #ifdef WHIRLPOOL_DIGEST_LENGTH
105             case NID_whirlpool:
106             return WHIRLPOOL_DIGEST_LENGTH;
107             break;
108             #endif
109             default:
110 0           croak("Unknown digest hash mode %u", hash_method);
111             break;
112             }
113             }
114              
115 49           unsigned char* get_message_digest(SV* text_SV, int hash_method)
116             {
117             STRLEN text_length;
118             unsigned char* text;
119              
120 49 50         text = (unsigned char*) SvPV(text_SV, text_length);
121              
122 49           switch(hash_method)
123             {
124             case NID_md5:
125 7           return MD5(text, text_length, NULL);
126             break;
127             case NID_sha1:
128 7           return SHA1(text, text_length, NULL);
129             break;
130             #ifdef SHA512_DIGEST_LENGTH
131             case NID_sha224:
132 7           return SHA224(text, text_length, NULL);
133             break;
134             case NID_sha256:
135 7           return SHA256(text, text_length, NULL);
136             break;
137             case NID_sha384:
138 7           return SHA384(text, text_length, NULL);
139             break;
140             case NID_sha512:
141 7           return SHA512(text, text_length, NULL);
142             break;
143             #endif
144             case NID_ripemd160:
145 7           return RIPEMD160(text, text_length, NULL);
146             break;
147             #ifdef WHIRLPOOL_DIGEST_LENGTH
148             case NID_whirlpool:
149             return WHIRLPOOL(text, text_length, NULL);
150             break;
151             #endif
152             default:
153 49           croak("Unknown digest hash mode %u", hash_method);
154             break;
155             }
156             }
157              
158 64           SV* cor_bn2sv(const BIGNUM* p_bn)
159             {
160 64           return p_bn != NULL
161 41           ? sv_2mortal(newSViv((IV) BN_dup(p_bn)))
162 105 100         : &PL_sv_undef;
163             }
164              
165 17           SV* extractBioString(BIO* p_stringBio)
166             {
167             SV* sv;
168             BUF_MEM* bptr;
169              
170 17 50         CHECK_OPEN_SSL(BIO_flush(p_stringBio) == 1);
171 17           BIO_get_mem_ptr(p_stringBio, &bptr);
172 17           sv = newSVpv(bptr->data, bptr->length);
173              
174 17 50         CHECK_OPEN_SSL(BIO_set_close(p_stringBio, BIO_CLOSE) == 1);
175 17           BIO_free(p_stringBio);
176 17           return sv;
177             }
178              
179 11           RSA* _load_rsa_key(SV* p_keyStringSv,
180             RSA*(*p_loader)(BIO*, RSA**, pem_password_cb*, void*),
181             SV* p_passphaseSv)
182             {
183             STRLEN keyStringLength;
184             char* keyString;
185 11           char* passphase = NULL;
186              
187             RSA* rsa;
188             BIO* stringBIO;
189              
190 11 50         keyString = SvPV(p_keyStringSv, keyStringLength);
191              
192 11 100         if (SvPOK(p_passphaseSv)) {
193 4 50         passphase = SvPV_nolen(p_passphaseSv);
194             }
195              
196 11 50         CHECK_OPEN_SSL(stringBIO = BIO_new_mem_buf(keyString, keyStringLength));
197              
198 11           rsa = p_loader(stringBIO, NULL, NULL, passphase);
199              
200 11 50         CHECK_OPEN_SSL(BIO_set_close(stringBIO, BIO_CLOSE) == 1);
201 11           BIO_free(stringBIO);
202              
203 11 50         CHECK_OPEN_SSL(rsa);
204 11           return rsa;
205             }
206              
207 19           SV* rsa_crypt(rsaData* p_rsa, SV* p_from,
208             int (*p_crypt)(int, const unsigned char*, unsigned char*, RSA*, int))
209             {
210             STRLEN from_length;
211             int to_length;
212             int size;
213             unsigned char* from;
214             char* to;
215             SV* sv;
216              
217 19 50         from = (unsigned char*) SvPV(p_from, from_length);
218 19           size = RSA_size(p_rsa->rsa);
219 19 50         CHECK_NEW(to, size, char);
220              
221 19           to_length = p_crypt(
222             from_length, from, (unsigned char*) to, p_rsa->rsa, p_rsa->padding);
223              
224 19 50         if (to_length < 0)
225             {
226 0           Safefree(to);
227 0           CHECK_OPEN_SSL(0);
228             }
229 19           sv = newSVpv(to, to_length);
230 19           Safefree(to);
231 19           return sv;
232             }
233              
234              
235             MODULE = Crypt::OpenSSL::RSA PACKAGE = Crypt::OpenSSL::RSA
236             PROTOTYPES: DISABLE
237              
238             BOOT:
239             #if OPENSSL_VERSION_NUMBER < 0x10100000L
240 4           # might introduce memory leak without calling EVP_cleanup() on exit
241 4           # see https://wiki.openssl.org/index.php/Library_Initialization
242             ERR_load_crypto_strings();
243             OpenSSL_add_all_algorithms();
244             #else
245             # NOOP
246             #endif
247              
248             SV*
249             new_private_key(proto, key_string_SV, passphase_SV=&PL_sv_undef)
250             SV* proto;
251             SV* key_string_SV;
252             SV* passphase_SV;
253             CODE:
254 7           RETVAL = make_rsa_obj(
255             proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSAPrivateKey, passphase_SV));
256             OUTPUT:
257             RETVAL
258              
259             SV*
260             _new_public_key_pkcs1(proto, key_string_SV)
261             SV* proto;
262             SV* key_string_SV;
263             CODE:
264 3           RETVAL = make_rsa_obj(
265             proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSAPublicKey, &PL_sv_undef));
266             OUTPUT:
267             RETVAL
268              
269             SV*
270             _new_public_key_x509(proto, key_string_SV)
271             SV* proto;
272             SV* key_string_SV;
273             CODE:
274 1           RETVAL = make_rsa_obj(
275             proto, _load_rsa_key(key_string_SV, PEM_read_bio_RSA_PUBKEY, &PL_sv_undef));
276             OUTPUT:
277             RETVAL
278              
279             void
280             DESTROY(p_rsa)
281             rsaData* p_rsa;
282             CODE:
283 20           RSA_free(p_rsa->rsa);
284 20           Safefree(p_rsa);
285              
286             SV*
287             get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_undef)
288             rsaData* p_rsa;
289             SV* passphase_SV;
290             SV* cipher_name_SV;
291             PREINIT:
292             BIO* stringBIO;
293 9           char* passphase = NULL;
294 9           STRLEN passphaseLength = 0;
295             char* cipher_name;
296 9           const EVP_CIPHER* enc = NULL;
297             CODE:
298 9 100         if (SvPOK(cipher_name_SV) && !SvPOK(passphase_SV)) {
    50          
299 0           croak("Passphrase is required for cipher");
300             }
301 9 100         if (SvPOK(passphase_SV)) {
302 3 50         passphase = SvPV(passphase_SV, passphaseLength);
303 3 100         if (SvPOK(cipher_name_SV)) {
304 2 50         cipher_name = SvPV_nolen(cipher_name_SV);
305             }
306             else {
307 1           cipher_name = "des3";
308             }
309 3           enc = EVP_get_cipherbyname(cipher_name);
310 3 50         if (enc == NULL) {
311 0           croak("Unsupported cipher: %s", cipher_name);
312             }
313             }
314              
315 9 50         CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem()));
316 9           PEM_write_bio_RSAPrivateKey(
317             stringBIO, p_rsa->rsa, enc, passphase, passphaseLength, NULL, NULL);
318 9           RETVAL = extractBioString(stringBIO);
319              
320             OUTPUT:
321             RETVAL
322              
323             SV*
324             get_public_key_string(p_rsa)
325             rsaData* p_rsa;
326             PREINIT:
327             BIO* stringBIO;
328             CODE:
329 5 50         CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem()));
330 5           PEM_write_bio_RSAPublicKey(stringBIO, p_rsa->rsa);
331 5           RETVAL = extractBioString(stringBIO);
332              
333             OUTPUT:
334             RETVAL
335              
336             SV*
337             get_public_key_x509_string(p_rsa)
338             rsaData* p_rsa;
339             PREINIT:
340             BIO* stringBIO;
341             CODE:
342 3 50         CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem()));
343 3           PEM_write_bio_RSA_PUBKEY(stringBIO, p_rsa->rsa);
344 3           RETVAL = extractBioString(stringBIO);
345              
346             OUTPUT:
347             RETVAL
348              
349             SV*
350             generate_key(proto, bitsSV, exponent = 65537)
351             SV* proto;
352             SV* bitsSV;
353             unsigned long exponent;
354             PREINIT:
355             RSA* rsa;
356             CODE:
357             #if OPENSSL_VERSION_NUMBER >= 0x00908000L
358             BIGNUM *e;
359             int rc;
360 3           e = BN_new();
361 3           BN_set_word(e, exponent);
362 3           rsa = RSA_new();
363 3 50         rc = RSA_generate_key_ex(rsa, SvIV(bitsSV), e, NULL);
364 3           BN_free(e);
365 3           e = NULL;
366 3 50         CHECK_OPEN_SSL(rc != -1);
367             #else
368             rsa = RSA_generate_key(SvIV(bitsSV), exponent, NULL, NULL);
369             #endif
370 3 50         CHECK_OPEN_SSL(rsa);
371 3           RETVAL = make_rsa_obj(proto, rsa);
372             OUTPUT:
373             RETVAL
374              
375              
376             SV*
377             _new_key_from_parameters(proto, n, e, d, p, q)
378             SV* proto;
379             BIGNUM* n;
380             BIGNUM* e;
381             BIGNUM* d;
382             BIGNUM* p;
383             BIGNUM* q;
384             PREINIT:
385             RSA* rsa;
386             BN_CTX* ctx;
387 8           BIGNUM* p_minus_1 = NULL;
388 8           BIGNUM* q_minus_1 = NULL;
389 8           BIGNUM* dmp1 = NULL;
390 8           BIGNUM* dmq1 = NULL;
391 8           BIGNUM* iqmp = NULL;
392             int error;
393             CODE:
394             {
395 8 50         if (!(n && e))
    50          
396             {
397 0           croak("At least a modulus and public key must be provided");
398             }
399 8 50         CHECK_OPEN_SSL(rsa = RSA_new());
400             #if OLD_CRUFTY_SSL_VERSION
401 8           rsa->n = n;
402 8           rsa->e = e;
403             #endif
404 8 100         if (p || q)
    100          
405             {
406 6           error = 0;
407 6 50         THROW(ctx = BN_CTX_new());
408 6 100         if (!p)
409             {
410 3 50         THROW(p = BN_new());
411 3 50         THROW(BN_div(p, NULL, n, q, ctx));
412             }
413 3 100         else if (!q)
414             {
415 2           q = BN_new();
416 2 50         THROW(BN_div(q, NULL, n, p, ctx));
417             }
418             #if OLD_CRUFTY_SSL_VERSION
419 6           rsa->p = p;
420 6           rsa->q = q;
421             #else
422             THROW(RSA_set0_factors(rsa, p, q));
423             #endif
424 6 50         THROW(p_minus_1 = BN_new());
425 6 50         THROW(BN_sub(p_minus_1, p, BN_value_one()));
426 6 50         THROW(q_minus_1 = BN_new());
427 6 50         THROW(BN_sub(q_minus_1, q, BN_value_one()));
428 6 100         if (!d)
429             {
430 1 50         THROW(d = BN_new());
431 1 50         THROW(BN_mul(d, p_minus_1, q_minus_1, ctx));
432 1 50         THROW(BN_mod_inverse(d, e, d, ctx));
433             }
434             #if OLD_CRUFTY_SSL_VERSION
435 6           rsa->d = d;
436             #else
437             THROW(RSA_set0_key(rsa, n, e, d));
438             #endif
439 6 50         THROW(dmp1 = BN_new());
440 6 50         THROW(BN_mod(dmp1, d, p_minus_1, ctx));
441 6 50         THROW(dmq1 = BN_new());
442 6 50         THROW(BN_mod(dmq1, d, q_minus_1, ctx));
443 6 50         THROW(iqmp = BN_new());
444 6 50         THROW(BN_mod_inverse(iqmp, q, p, ctx));
445             #if OLD_CRUFTY_SSL_VERSION
446 6           rsa->dmp1 = dmp1;
447 6           rsa->dmq1 = dmq1;
448 6           rsa->iqmp = iqmp;
449             #else
450             THROW(RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp));
451             #endif
452 6           dmp1 = dmq1 = iqmp = NULL;
453 6 100         THROW(RSA_check_key(rsa) == 1);
454             err:
455 6 50         if (p_minus_1) BN_clear_free(p_minus_1);
456 6 50         if (q_minus_1) BN_clear_free(q_minus_1);
457 6 50         if (dmp1) BN_clear_free(dmp1);
458 6 50         if (dmq1) BN_clear_free(dmq1);
459 6 50         if (iqmp) BN_clear_free(iqmp);
460 6 50         if (ctx) BN_CTX_free(ctx);
461 6 100         if (error)
462             {
463 2           RSA_free(rsa);
464 2           CHECK_OPEN_SSL(0);
465             }
466             }
467             else
468             {
469             #if OLD_CRUFTY_SSL_VERSION
470 2           rsa->d = d;
471             #else
472             CHECK_OPEN_SSL(RSA_set0_key(rsa, n, e, d));
473             #endif
474             }
475 6           RETVAL = make_rsa_obj(proto, rsa);
476             }
477             OUTPUT:
478             RETVAL
479              
480             void
481             _get_key_parameters(p_rsa)
482             rsaData* p_rsa;
483             PREINIT:
484             const BIGNUM* n;
485             const BIGNUM* e;
486             const BIGNUM* d;
487             const BIGNUM* p;
488             const BIGNUM* q;
489             const BIGNUM* dmp1;
490             const BIGNUM* dmq1;
491             const BIGNUM* iqmp;
492             PPCODE:
493             {
494             RSA* rsa;
495 8           rsa = p_rsa->rsa;
496             #if OLD_CRUFTY_SSL_VERSION
497 8           n = rsa->n;
498 8           e = rsa->e;
499 8           d = rsa->d;
500 8           p = rsa->p;
501 8           q = rsa->q;
502 8           dmp1 = rsa->dmp1;
503 8           dmq1 = rsa->dmq1;
504 8           iqmp = rsa->iqmp;
505             #else
506             RSA_get0_key(rsa, &n, &e, &d);
507             RSA_get0_factors(rsa, &p, &q);
508             RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
509             #endif
510 8 50         XPUSHs(cor_bn2sv(n));
511 8 50         XPUSHs(cor_bn2sv(e));
512 8 50         XPUSHs(cor_bn2sv(d));
513 8 50         XPUSHs(cor_bn2sv(p));
514 8 50         XPUSHs(cor_bn2sv(q));
515 8 50         XPUSHs(cor_bn2sv(dmp1));
516 8 50         XPUSHs(cor_bn2sv(dmq1));
517 8 50         XPUSHs(cor_bn2sv(iqmp));
518             }
519              
520             SV*
521             encrypt(p_rsa, p_plaintext)
522             rsaData* p_rsa;
523             SV* p_plaintext;
524             CODE:
525 7           RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_public_encrypt);
526             OUTPUT:
527             RETVAL
528              
529             SV*
530             decrypt(p_rsa, p_ciphertext)
531             rsaData* p_rsa;
532             SV* p_ciphertext;
533             CODE:
534 7 100         if (!_is_private(p_rsa))
535             {
536 1           croak("Public keys cannot decrypt");
537             }
538 6           RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_private_decrypt);
539             OUTPUT:
540             RETVAL
541              
542             SV*
543             private_encrypt(p_rsa, p_plaintext)
544             rsaData* p_rsa;
545             SV* p_plaintext;
546             CODE:
547 4 100         if (!_is_private(p_rsa))
548             {
549 1           croak("Public keys cannot private_encrypt");
550             }
551 3           RETVAL = rsa_crypt(p_rsa, p_plaintext, RSA_private_encrypt);
552             OUTPUT:
553             RETVAL
554              
555             SV*
556             public_decrypt(p_rsa, p_ciphertext)
557             rsaData* p_rsa;
558             SV* p_ciphertext;
559             CODE:
560 3           RETVAL = rsa_crypt(p_rsa, p_ciphertext, RSA_public_decrypt);
561             OUTPUT:
562             RETVAL
563              
564             int
565             size(p_rsa)
566             rsaData* p_rsa;
567             CODE:
568 5           RETVAL = RSA_size(p_rsa->rsa);
569             OUTPUT:
570             RETVAL
571              
572             int
573             check_key(p_rsa)
574             rsaData* p_rsa;
575             CODE:
576 2 100         if (!_is_private(p_rsa))
577             {
578 1           croak("Public keys cannot be checked");
579             }
580 1           RETVAL = RSA_check_key(p_rsa->rsa);
581             OUTPUT:
582             RETVAL
583              
584             # Seed the PRNG with user-provided bytes; returns true if the
585             # seeding was sufficient.
586              
587             int
588             _random_seed(random_bytes_SV)
589             SV* random_bytes_SV;
590             PREINIT:
591             STRLEN random_bytes_length;
592             char* random_bytes;
593             CODE:
594 0 0         random_bytes = SvPV(random_bytes_SV, random_bytes_length);
595 0           RAND_seed(random_bytes, random_bytes_length);
596 0           RETVAL = RAND_status();
597             OUTPUT:
598             RETVAL
599              
600             # Returns true if the PRNG has enough seed data
601              
602             int
603             _random_status()
604             CODE:
605 1           RETVAL = RAND_status();
606             OUTPUT:
607             RETVAL
608              
609             void
610             use_md5_hash(p_rsa)
611             rsaData* p_rsa;
612             CODE:
613 2           p_rsa->hashMode = NID_md5;
614              
615             void
616             use_sha1_hash(p_rsa)
617             rsaData* p_rsa;
618             CODE:
619 2           p_rsa->hashMode = NID_sha1;
620              
621             #ifdef SHA512_DIGEST_LENGTH
622              
623             void
624             use_sha224_hash(p_rsa)
625             rsaData* p_rsa;
626             CODE:
627 2           p_rsa->hashMode = NID_sha224;
628              
629             void
630             use_sha256_hash(p_rsa)
631             rsaData* p_rsa;
632             CODE:
633 2           p_rsa->hashMode = NID_sha256;
634              
635             void
636             use_sha384_hash(p_rsa)
637             rsaData* p_rsa;
638             CODE:
639 2           p_rsa->hashMode = NID_sha384;
640              
641             void
642             use_sha512_hash(p_rsa)
643             rsaData* p_rsa;
644             CODE:
645 2           p_rsa->hashMode = NID_sha512;
646              
647             #endif
648              
649             void
650             use_ripemd160_hash(p_rsa)
651             rsaData* p_rsa;
652             CODE:
653 2           p_rsa->hashMode = NID_ripemd160;
654              
655             #ifdef WHIRLPOOL_DIGEST_LENGTH
656              
657             void
658             use_whirlpool_hash(p_rsa)
659             rsaData* p_rsa;
660             CODE:
661             p_rsa->hashMode = NID_whirlpool;
662              
663             #endif
664              
665             void
666             use_no_padding(p_rsa)
667             rsaData* p_rsa;
668             CODE:
669 3           p_rsa->padding = RSA_NO_PADDING;
670              
671             void
672             use_pkcs1_padding(p_rsa)
673             rsaData* p_rsa;
674             CODE:
675 1           p_rsa->padding = RSA_PKCS1_PADDING;
676              
677             void
678             use_pkcs1_oaep_padding(p_rsa)
679             rsaData* p_rsa;
680             CODE:
681 2           p_rsa->padding = RSA_PKCS1_OAEP_PADDING;
682              
683             #if OPENSSL_VERSION_NUMBER < 0x30000000L
684              
685             void
686             use_sslv23_padding(p_rsa)
687             rsaData* p_rsa;
688             CODE:
689 0           p_rsa->padding = RSA_SSLV23_PADDING;
690              
691             #endif
692              
693             # Sign text. Returns the signature.
694              
695             SV*
696             sign(p_rsa, text_SV)
697             rsaData* p_rsa;
698             SV* text_SV;
699             PREINIT:
700             char* signature;
701             unsigned char* digest;
702             unsigned int signature_length;
703             CODE:
704             {
705 15 100         if (!_is_private(p_rsa))
706             {
707 1           croak("Public keys cannot sign messages");
708             }
709              
710 14 50         CHECK_NEW(signature, RSA_size(p_rsa->rsa), char);
711              
712 14 50         CHECK_OPEN_SSL(digest = get_message_digest(text_SV, p_rsa->hashMode));
713 14 50         CHECK_OPEN_SSL(RSA_sign(p_rsa->hashMode,
714             digest,
715             get_digest_length(p_rsa->hashMode),
716             (unsigned char*) signature,
717             &signature_length,
718             p_rsa->rsa));
719 14           RETVAL = newSVpvn(signature, signature_length);
720 14           Safefree(signature);
721             }
722             OUTPUT:
723             RETVAL
724              
725             # Verify signature. Returns true if correct, false otherwise.
726              
727             void
728             verify(p_rsa, text_SV, sig_SV)
729             rsaData* p_rsa;
730             SV* text_SV;
731             SV* sig_SV;
732             PPCODE:
733             {
734             unsigned char* sig;
735             unsigned char* digest;
736             STRLEN sig_length;
737              
738 35 50         sig = (unsigned char*) SvPV(sig_SV, sig_length);
739 35 50         if (RSA_size(p_rsa->rsa) < sig_length)
740             {
741 0           croak("Signature longer than key");
742             }
743              
744 35 50         CHECK_OPEN_SSL(digest = get_message_digest(text_SV, p_rsa->hashMode));
745 35           switch(RSA_verify(p_rsa->hashMode,
746             digest,
747 35           get_digest_length(p_rsa->hashMode),
748             sig,
749             sig_length,
750             p_rsa->rsa))
751             {
752             case 0:
753 28           ERR_clear_error();
754 35           XSRETURN_NO;
755             break;
756             case 1:
757 7           XSRETURN_YES;
758             break;
759             default:
760 0           CHECK_OPEN_SSL(0);
761 0           break;
762             }
763             }
764              
765             int
766             is_private(p_rsa)
767             rsaData* p_rsa;
768             CODE:
769 2           RETVAL = _is_private(p_rsa);
770             OUTPUT:
771             RETVAL