File Coverage

RSA.xs
Criterion Covered Total %
statement 192 203 94.5
branch 83 144 57.6
condition n/a
subroutine n/a
pod n/a
total 275 347 79.2


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