File Coverage

X509.xs
Criterion Covered Total %
statement 258 491 52.5
branch 118 270 43.7
condition n/a
subroutine n/a
pod n/a
total 376 761 49.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             #if OPENSSL_VERSION_NUMBER >= 0x10100000
16             #include
17             #include
18             #include
19             #endif
20             #ifndef OPENSSL_NO_EC
21             # include
22             #endif
23              
24             /* from openssl/apps/apps.h */
25             #define FORMAT_UNDEF 0
26             #define FORMAT_ASN1 1
27             #define FORMAT_TEXT 2
28             #define FORMAT_PEM 3
29             #define FORMAT_PKCS12 5
30             #define FORMAT_SMIME 6
31             #define FORMAT_ENGINE 7
32             #define FORMAT_IISSGC 8
33              
34             /* fake our package name */
35             typedef X509* Crypt__OpenSSL__X509;
36             typedef X509_EXTENSION* Crypt__OpenSSL__X509__Extension;
37             typedef ASN1_OBJECT* Crypt__OpenSSL__X509__ObjectID;
38             typedef X509_NAME* Crypt__OpenSSL__X509__Name;
39             typedef X509_NAME_ENTRY* Crypt__OpenSSL__X509__Name_Entry;
40             typedef X509_CRL* Crypt__OpenSSL__X509__CRL;
41              
42             /* 1.0 backwards compat */
43             #if OPENSSL_VERSION_NUMBER < 0x10100000
44             #define const_ossl11
45              
46             #ifndef sk_OPENSSL_STRING_num
47             #define sk_OPENSSL_STRING_num sk_num
48             #endif
49              
50             #ifndef sk_OPENSSL_STRING_value
51             #define sk_OPENSSL_STRING_value sk_value
52             #endif
53              
54 3           static ASN1_INTEGER *X509_get0_serialNumber(const X509 *a)
55             {
56 3           return a->cert_info->serialNumber;
57             }
58              
59 3           static void RSA_get0_key(const RSA *r,
60             const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
61             {
62 3 100         if (n != NULL)
63 1           *n = r->n;
64 3 100         if (e != NULL)
65 2           *e = r->e;
66 3 50         if (d != NULL)
67 0           *d = r->d;
68 3           }
69              
70 3           static RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
71             {
72 3 50         if (pkey->type != EVP_PKEY_RSA)
73 0           return NULL;
74 3           return pkey->pkey.rsa;
75             }
76              
77 0           static void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
78             X509_ALGOR **palg)
79             {
80 0 0         if (psig != NULL)
81 0           *psig = crl->signature;
82 0 0         if (palg != NULL)
83 0           *palg = crl->sig_alg;
84 0           }
85              
86             #if OPENSSL_VERSION_NUMBER < 0x10002000
87             static void X509_get0_signature(const_ossl11 ASN1_BIT_STRING **psig, const_ossl11 X509_ALGOR **palg,
88             const X509 *x)
89             {
90             if (psig != NULL)
91             *psig = x->signature;
92             if (palg != NULL)
93             *palg = x->sig_alg;
94             }
95             #endif
96              
97 0           static void DSA_get0_pqg(const DSA *d,
98             const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
99             {
100 0 0         if (p != NULL)
101 0           *p = d->p;
102 0 0         if (q != NULL)
103 0           *q = d->q;
104 0 0         if (g != NULL)
105 0           *g = d->g;
106 0           }
107              
108 0           static void DSA_get0_key(const DSA *d,
109             const BIGNUM **pub_key, const BIGNUM **priv_key)
110             {
111 0 0         if (pub_key != NULL)
112 0           *pub_key = d->pub_key;
113 0 0         if (priv_key != NULL)
114 0           *priv_key = d->priv_key;
115 0           }
116              
117 0           static DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
118             {
119 0 0         if (pkey->type != EVP_PKEY_DSA)
120 0           return NULL;
121 0           return pkey->pkey.dsa;
122             }
123              
124 2           static EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
125             {
126 2 50         if (pkey->type != EVP_PKEY_EC)
127 0           return NULL;
128 2           return pkey->pkey.ec;
129             }
130              
131             #else
132             #define const_ossl11 const
133             #endif
134              
135             /* Unicode 0xfffd */
136             static U8 utf8_substitute_char[3] = { 0xef, 0xbf, 0xbd };
137              
138             /* stolen from OpenSSL.xs */
139 2444           long bio_write_cb(struct bio_st *bm, int m, const char *ptr, int l, long x, long y) {
140              
141 2444 100         if (m == BIO_CB_WRITE) {
142 1180           SV *sv = (SV *) BIO_get_callback_arg(bm);
143 1180           sv_catpvn(sv, ptr, l);
144             }
145              
146 2444 50         if (m == BIO_CB_PUTS) {
147 0           SV *sv = (SV *) BIO_get_callback_arg(bm);
148 0           l = strlen(ptr);
149 0           sv_catpvn(sv, ptr, l);
150             }
151              
152 2444           return l;
153             }
154              
155 43           static BIO* sv_bio_create(void) {
156              
157 43           SV *sv = newSVpvn("", 0);
158              
159             /* create an in-memory BIO abstraction and callbacks */
160 43           BIO *bio = BIO_new(BIO_s_mem());
161              
162 43           BIO_set_callback(bio, bio_write_cb);
163 43           BIO_set_callback_arg(bio, (void *)sv);
164              
165 43           return bio;
166             }
167              
168 43           static SV* sv_bio_final(BIO *bio) {
169              
170             SV* sv;
171              
172 43           (void)BIO_flush(bio);
173 43           sv = (SV *)BIO_get_callback_arg(bio);
174 43           BIO_set_callback_arg(bio, (void *)NULL);
175 43           BIO_set_callback(bio, (void *)NULL);
176 43           BIO_free_all(bio);
177              
178 43 50         if (!sv) sv = &PL_sv_undef;
179              
180 43           return sv;
181             }
182              
183             /* call this just before sv_bio_final if the BIO got an UTF8 encoded text and you want native perl utf-8 strings. */
184 8           static SV* sv_bio_utf8_on(BIO *bio) {
185              
186 8           SV* sv = (SV *)BIO_get_callback_arg(bio);
187              
188             /* Illegal utf-8 in the string */
189 8 50         if (!sv_utf8_decode(sv)) {
190             STRLEN len;
191 0           SV *nsv = newSVpvn("", 0);
192              
193 0 0         const U8* start = (U8 *) SvPV(sv, len);
194 0           const U8* end = start + len;
195             const U8* cur;
196              
197 0 0         while ((start < end) && !is_utf8_string_loclen(start, len, &cur, 0)) {
    0          
198 0           sv_catpvn(nsv, (const char*)start, (cur - start) + 1); /* text that was ok */
199 0           sv_catpvn(nsv, (const char*)utf8_substitute_char, 3); /* insert \x{fffd} */
200 0           start = cur + 1;
201 0           len = end - cur;
202             }
203              
204 0 0         if (start < end) {
205 0           sv_catpvn(nsv, (const char*)start, (cur - start) - 1); /* rest of the string */
206             }
207              
208 0           sv_copypv(sv, nsv);
209 0           SvREFCNT_dec(nsv);
210 0           sv_utf8_decode(sv); /* should be ok now */
211             }
212              
213 8           return sv;
214             }
215              
216             /*
217             static void sv_bio_error(BIO *bio) {
218              
219             SV* sv = (SV *)BIO_get_callback_arg(bio);
220             if (sv) sv_free(sv);
221              
222             BIO_free_all (bio);
223             }
224             */
225              
226 0           static const char *ssl_error(void) {
227             BIO *bio;
228             SV *sv;
229             STRLEN l;
230              
231 0           bio = sv_bio_create();
232 0           ERR_print_errors(bio);
233 0           sv = sv_bio_final(bio);
234 0           ERR_clear_error();
235 0 0         return SvPV(sv, l);
236             }
237              
238             /* Make a scalar ref to a class object */
239 40           static SV* sv_make_ref(const char* class, void* object) {
240             SV* rv;
241              
242 40           rv = newSV(0);
243 40           sv_setref_pv(rv, class, (void*) object);
244              
245 40 50         if (! sv_isa(rv, class) ) {
246 0           croak("Error creating reference to %s", class);
247             }
248              
249 40           return rv;
250             }
251              
252             /*
253             * hash of extensions from x509.
254             * no_name can be
255             * 0: index by long name,
256             * 1: index by oid string,
257             * 2: index by short name
258             */
259 11           static HV* hv_exts(X509* x509, int no_name) {
260             X509_EXTENSION *ext;
261             int i, c, r;
262 11           size_t len = 128;
263 11           char* key = NULL;
264             SV* rv;
265              
266 11           HV* RETVAL = newHV();
267 11           sv_2mortal((SV*)RETVAL);
268 11           c = X509_get_ext_count(x509);
269              
270 11 100         if ( !(c > 0) ) {
271 1           croak("No extensions found\n");
272             }
273              
274 43 100         for (i = 0; i < c; i++) {
275 33           r = 0;
276              
277 33           ext = X509_get_ext(x509, i);
278              
279 33 50         if (ext == NULL) croak("Extension %d unavailable\n", i);
280              
281 33           rv = sv_make_ref("Crypt::OpenSSL::X509::Extension", (void*)ext);
282              
283 33 50         if (no_name == 0 || no_name == 1) {
    100          
284              
285 30           key = malloc(sizeof(char) * (len + 1)); /*FIXME will it leak?*/
286 30           r = OBJ_obj2txt(key, len, X509_EXTENSION_get_object(ext), no_name);
287              
288 3 50         } else if (no_name == 2) {
289              
290 3           key = (char*)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
291 3           r = strlen(key);
292             }
293              
294 33 50         if (! hv_store(RETVAL, key, r, rv, 0) ) croak("Error storing extension in hash\n");
295             }
296              
297 10           return RETVAL;
298             }
299              
300             MODULE = Crypt::OpenSSL::X509 PACKAGE = Crypt::OpenSSL::X509
301              
302             PROTOTYPES: DISABLE
303              
304             BOOT:
305             {
306 4           HV *stash = gv_stashpvn("Crypt::OpenSSL::X509", 20, TRUE);
307              
308 4           struct { char *n; I32 v; } Crypt__OpenSSL__X509__const[] = {
309              
310             {"OPENSSL_VERSION_NUMBER", OPENSSL_VERSION_NUMBER},
311             {"FORMAT_UNDEF", FORMAT_UNDEF},
312             {"FORMAT_ASN1", FORMAT_ASN1},
313             {"FORMAT_TEXT", FORMAT_TEXT},
314             {"FORMAT_PEM", FORMAT_PEM},
315             {"FORMAT_PKCS12", FORMAT_PKCS12},
316             {"FORMAT_SMIME", FORMAT_SMIME},
317             {"FORMAT_ENGINE", FORMAT_ENGINE},
318             {"FORMAT_IISSGC", FORMAT_IISSGC},
319             {"V_ASN1_PRINTABLESTRING", V_ASN1_PRINTABLESTRING},
320             {"V_ASN1_UTF8STRING", V_ASN1_UTF8STRING},
321             {"V_ASN1_IA5STRING", V_ASN1_IA5STRING},
322             {Nullch,0}};
323              
324             char *name;
325             int i;
326              
327 52 100         for (i = 0; (name = Crypt__OpenSSL__X509__const[i].n); i++) {
328 48           newCONSTSUB(stash, name, newSViv(Crypt__OpenSSL__X509__const[i].v));
329             }
330             #if OPENSSL_VERSION_NUMBER < 0x10100000
331 4           ERR_load_crypto_strings();
332             # ifdef OPENSSL_LOAD_CONF
333             OPENSSL_add_all_algorithms_conf;
334             # endif
335             #endif
336             }
337              
338             Crypt::OpenSSL::X509
339             new(class)
340             SV *class
341              
342             CODE:
343              
344 0 0         if ((RETVAL = X509_new()) == NULL) {
345 0           croak("X509_new");
346             }
347              
348 0 0         if (!X509_set_version(RETVAL, 2)) {
349 0           X509_free(RETVAL);
350 0 0         croak ("%s - can't X509_set_version()", SvPV_nolen(class));
351             }
352              
353 0           ASN1_INTEGER_set(X509_get_serialNumber(RETVAL), 0L);
354              
355             OUTPUT:
356             RETVAL
357              
358             Crypt::OpenSSL::X509
359             new_from_string(class, string, format = FORMAT_PEM)
360             SV *class
361             SV *string
362             int format
363              
364             ALIAS:
365             new_from_file = 1
366              
367             PREINIT:
368             BIO *bio;
369             STRLEN len;
370             char *cert;
371              
372             CODE:
373              
374 17 50         cert = SvPV(string, len);
375              
376 17 100         if (ix == 1) {
377 16           bio = BIO_new_file(cert, "r");
378             } else {
379 1           bio = BIO_new_mem_buf(cert, len);
380             }
381              
382 17 50         if (!bio) croak("%s: Failed to create BIO", SvPV_nolen(class));
    0          
383              
384             /* this can come in any number of ways */
385 17 100         if (format == FORMAT_ASN1) {
386              
387 1           RETVAL = (X509*)d2i_X509_bio(bio, NULL);
388              
389             } else {
390              
391 16           RETVAL = (X509*)PEM_read_bio_X509(bio, NULL, NULL, NULL);
392             }
393              
394 17           BIO_free_all(bio);
395              
396 17 50         if (!RETVAL) croak("%s: failed to read X509 certificate.", SvPV_nolen(class));
    0          
397              
398             OUTPUT:
399             RETVAL
400              
401             void
402             DESTROY(x509)
403             Crypt::OpenSSL::X509 x509;
404              
405             PPCODE:
406              
407 17 50         if (x509) X509_free(x509); x509 = 0;
408              
409             # This is called via an END block in the Perl module to clean up initialization that happened in BOOT.
410             void
411             __X509_cleanup(void)
412             PPCODE:
413             #if OPENSSL_VERSION_NUMBER < 0x10100000
414 4           CRYPTO_cleanup_all_ex_data();
415 4           ERR_free_strings();
416 4           ERR_remove_state(0);
417 4           EVP_cleanup();
418             #endif
419              
420             SV*
421             accessor(x509)
422             Crypt::OpenSSL::X509 x509;
423              
424             ALIAS:
425             subject = 1
426             issuer = 2
427             serial = 3
428             hash = 4
429             subject_hash = 4
430             notBefore = 5
431             notAfter = 6
432             email = 7
433             version = 8
434             sig_alg_name = 9
435             key_alg_name = 10
436             issuer_hash = 11
437              
438             PREINIT:
439             BIO *bio;
440             X509_NAME *name;
441              
442             CODE:
443              
444 19           bio = sv_bio_create();
445              
446             /* this includes both subject and issuer since they are so much alike */
447 19 100         if (ix == 1 || ix == 2) {
    100          
448              
449 6 100         if (ix == 1) {
450 4           name = X509_get_subject_name(x509);
451             } else {
452 2           name = X509_get_issuer_name(x509);
453             }
454              
455             /* this is prefered over X509_NAME_oneline() */
456 6           X509_NAME_print_ex(bio, name, 0, (XN_FLAG_SEP_CPLUS_SPC | ASN1_STRFLGS_UTF8_CONVERT) & ~ASN1_STRFLGS_ESC_MSB);
457              
458             /* this need not be pure ascii, try to get a native perl character string with * utf8 */
459 6           sv_bio_utf8_on(bio);
460              
461 13 100         } else if (ix == 3) {
462              
463 3           i2a_ASN1_INTEGER(bio, X509_get0_serialNumber(x509));
464              
465 10 100         } else if (ix == 4) {
466              
467 2           BIO_printf(bio, "%08lx", X509_subject_name_hash(x509));
468              
469 8 50         } else if (ix == 5) {
470             #if OPENSSL_VERSION_NUMBER < 0x10100000
471 0           ASN1_TIME_print(bio, X509_get_notBefore(x509));
472             #else
473             ASN1_TIME_print(bio, X509_get0_notBefore(x509));
474             #endif
475              
476 8 50         } else if (ix == 6) {
477             #if OPENSSL_VERSION_NUMBER < 0x10100000
478 0           ASN1_TIME_print(bio, X509_get_notAfter(x509));
479             #else
480             ASN1_TIME_print(bio, X509_get0_notBefore(x509));
481             #endif
482 8 100         } else if (ix == 7) {
483              
484             int j;
485 2           STACK_OF(OPENSSL_STRING) *emlst = X509_get1_email(x509);
486              
487 6 100         for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) {
488 4 100         BIO_printf(bio, "%s%s", (j ? " " : ""), sk_OPENSSL_STRING_value(emlst, j));
489             }
490              
491 2           X509_email_free(emlst);
492              
493 6 100         } else if (ix == 8) {
494              
495 1           BIO_printf(bio, "%02ld", X509_get_version(x509));
496              
497 5 100         } else if (ix == 9) {
498             const_ossl11 X509_ALGOR *palg;
499             const_ossl11 ASN1_OBJECT *paobj;
500              
501 2           X509_get0_signature(NULL, &palg, x509);
502 2           X509_ALGOR_get0(&paobj, NULL, NULL, palg);
503              
504 2           i2a_ASN1_OBJECT(bio, paobj);
505 3 100         } else if ( ix == 10 ) {
506             X509_PUBKEY *pkey;
507             ASN1_OBJECT *ppkalg;
508              
509 2           pkey = X509_get_X509_PUBKEY(x509);
510 2           X509_PUBKEY_get0_param(&ppkalg, NULL, NULL, NULL, pkey);
511              
512 2           i2a_ASN1_OBJECT(bio, ppkalg);
513 1 50         } else if ( ix == 11 ) {
514 1           BIO_printf(bio, "%08lx", X509_issuer_name_hash(x509));
515             }
516              
517 19           RETVAL = sv_bio_final(bio);
518              
519             OUTPUT:
520             RETVAL
521              
522             Crypt::OpenSSL::X509::Name
523             subject_name(x509)
524             Crypt::OpenSSL::X509 x509;
525              
526             ALIAS:
527             subject_name = 1
528             issuer_name = 2
529              
530             CODE:
531 14 100         if (ix == 1) {
532 12           RETVAL = X509_get_subject_name(x509);
533             } else {
534 2           RETVAL = X509_get_issuer_name(x509);
535             }
536              
537             OUTPUT:
538             RETVAL
539              
540             SV*
541             sig_print(x509)
542             Crypt::OpenSSL::X509 x509;
543              
544             PREINIT:
545             BIO *bio;
546             unsigned char *s;
547             const_ossl11 ASN1_BIT_STRING *psig;
548             int n,i;
549              
550             CODE:
551              
552 0           X509_get0_signature(&psig, NULL, x509);
553 0           n = psig->length;
554 0           s = psig->data;
555 0           bio = sv_bio_create();
556              
557 0 0         for (i=0; i
558 0           BIO_printf(bio, "%02x", s[i]);
559             }
560              
561 0           RETVAL = sv_bio_final(bio);
562             OUTPUT:
563             RETVAL
564              
565             SV*
566             as_string(x509, format = FORMAT_PEM)
567             Crypt::OpenSSL::X509 x509;
568             int format;
569              
570             PREINIT:
571             BIO *bio;
572              
573             CODE:
574              
575 1           bio = sv_bio_create();
576              
577             /* get the certificate back out in a specified format. */
578              
579 1 50         if (format == FORMAT_PEM) {
580              
581 0           PEM_write_bio_X509(bio, x509);
582              
583 1 50         } else if (format == FORMAT_ASN1) {
584              
585 1           i2d_X509_bio(bio, x509);
586              
587             }
588              
589 1           RETVAL = sv_bio_final(bio);
590              
591             OUTPUT:
592             RETVAL
593              
594             SV*
595             bit_length(x509)
596             Crypt::OpenSSL::X509 x509;
597              
598             PREINIT:
599             EVP_PKEY *pkey;
600             const DSA *dsa_pkey;
601             const RSA *rsa_pkey;
602             const EC_KEY *ec_pkey;
603             const BIGNUM *p;
604             const BIGNUM *n;
605             int length;
606              
607             CODE:
608 2           pkey = X509_extract_key(x509);
609 2 50         if (pkey == NULL) {
610 0           EVP_PKEY_free(pkey);
611 0           croak("Public key is unavailable\n");
612             }
613              
614 2           switch(EVP_PKEY_base_id(pkey)) {
615             case EVP_PKEY_RSA:
616 1           rsa_pkey = EVP_PKEY_get0_RSA(pkey);
617 1           RSA_get0_key(rsa_pkey, &n, NULL, NULL);
618 1           length = BN_num_bits(n);
619 1           break;
620             case EVP_PKEY_DSA:
621 0           dsa_pkey = EVP_PKEY_get0_DSA(pkey);
622 0           DSA_get0_pqg(dsa_pkey, &p, NULL, NULL);
623 0           length = BN_num_bits(p);
624 0           break;
625             #ifndef OPENSSL_NO_EC
626             case EVP_PKEY_EC:
627             {
628             const EC_GROUP *group;
629             BIGNUM* ec_order;
630 1           ec_order = BN_new();
631 1 50         if ( !ec_order ) {
632 0           EVP_PKEY_free(pkey);
633 0           croak("Could not malloc bignum");
634             }
635 1           ec_pkey = EVP_PKEY_get0_EC_KEY(pkey);
636 1 50         if ( (group = EC_KEY_get0_group(ec_pkey)) == NULL) {
637 0           EVP_PKEY_free(pkey);
638 0           croak("No EC group");
639             }
640             /* */
641 1 50         if (!EC_GROUP_get_order(group, ec_order, NULL)) {
642 0           EVP_PKEY_free(pkey);
643 0           croak("Could not get ec-group order");
644             }
645 1           length = BN_num_bits(ec_order);
646             /* */
647 1           BN_free(ec_order);
648 1           break;
649             }
650             #endif
651             default:
652 0           EVP_PKEY_free(pkey);
653 0           croak("Unknown public key type");
654             }
655              
656 2           RETVAL = newSVuv(length);
657              
658             OUTPUT:
659             RETVAL
660              
661             const char*
662             curve(x509)
663             Crypt::OpenSSL::X509 x509;
664              
665             PREINIT:
666             #ifndef OPENSSL_NO_EC
667             EVP_PKEY *pkey;
668             #endif
669              
670             CODE:
671             #ifdef OPENSSL_NO_EC
672             if ( x509 ) {} /* fix unused variable warning. */
673             croak("OpenSSL without EC-support");
674             #else
675 1           pkey = X509_extract_key(x509);
676 1 50         if (pkey == NULL) {
677 0           EVP_PKEY_free(pkey);
678 0           croak("Public key is unavailable\n");
679             }
680 1 50         if ( EVP_PKEY_base_id(pkey) == EVP_PKEY_EC ) {
681             const EC_GROUP *group;
682             const EC_KEY *ec_pkey;
683             int nid;
684 1           ec_pkey = EVP_PKEY_get0_EC_KEY(pkey);
685 1 50         if ( (group = EC_KEY_get0_group(ec_pkey)) == NULL) {
686 0           EVP_PKEY_free(pkey);
687 0           croak("No EC group");
688             }
689 1           nid = EC_GROUP_get_curve_name(group);
690 1 50         if ( nid == 0 ) {
691 0           EVP_PKEY_free(pkey);
692 0           croak("invalid nid");
693             }
694 1           RETVAL = OBJ_nid2sn(nid);
695             } else {
696 0           EVP_PKEY_free(pkey);
697 0           croak("Wrong Algorithm type\n");
698             }
699 1           EVP_PKEY_free(pkey);
700             #endif
701              
702             OUTPUT:
703             RETVAL
704              
705              
706             SV*
707             modulus(x509)
708             Crypt::OpenSSL::X509 x509;
709              
710             PREINIT:
711             EVP_PKEY *pkey;
712             BIO *bio;
713             int pkey_id;
714              
715             CODE:
716              
717 0           pkey = X509_extract_key(x509);
718 0           bio = sv_bio_create();
719              
720 0 0         if (pkey == NULL) {
721              
722 0           BIO_free_all(bio);
723 0           EVP_PKEY_free(pkey);
724 0           croak("Modulus is unavailable\n");
725             }
726              
727 0           pkey_id = EVP_PKEY_base_id(pkey);
728 0 0         if (pkey_id == EVP_PKEY_RSA) {
729             const RSA *rsa_pkey;
730             const BIGNUM *n;
731              
732 0           rsa_pkey = EVP_PKEY_get0_RSA(pkey);
733 0           RSA_get0_key(rsa_pkey, &n, NULL, NULL);
734              
735 0           BN_print(bio, n);
736              
737 0 0         } else if (pkey_id == EVP_PKEY_DSA) {
738             const DSA *dsa_pkey;
739             const BIGNUM *pub_key;
740              
741 0           dsa_pkey = EVP_PKEY_get0_DSA(pkey);
742 0           DSA_get0_key(dsa_pkey, &pub_key, NULL);
743 0           BN_print(bio, pub_key);
744             #ifndef OPENSSL_NO_EC
745 0 0         } else if ( pkey_id == EVP_PKEY_EC ) {
746             const EC_POINT *public_key;
747             const EC_GROUP *group;
748             const EC_KEY *ec_pkey;
749 0           BIGNUM *pub_key=NULL;
750              
751 0           ec_pkey = EVP_PKEY_get0_EC_KEY(pkey);
752 0 0         if ( (group = EC_KEY_get0_group(ec_pkey)) == NULL) {
753 0           BIO_free_all(bio);
754 0           EVP_PKEY_free(pkey);
755 0           croak("No EC group");
756             }
757 0           public_key = EC_KEY_get0_public_key(ec_pkey);
758 0 0         if ((pub_key = EC_POINT_point2bn(group, public_key, EC_KEY_get_conv_form(ec_pkey), NULL, NULL)) == NULL) {
759 0           BIO_free_all(bio);
760 0           EVP_PKEY_free(pkey);
761 0           croak("EC library error");
762             }
763 0           BN_print(bio, pub_key);
764             #endif
765             } else {
766              
767 0           BIO_free_all(bio);
768 0           EVP_PKEY_free(pkey);
769 0           croak("Wrong Algorithm type\n");
770             }
771              
772 0           RETVAL = sv_bio_final(bio);
773              
774 0           EVP_PKEY_free(pkey);
775              
776             OUTPUT:
777             RETVAL
778              
779             SV*
780             exponent(x509)
781             Crypt::OpenSSL::X509 x509;
782              
783             PREINIT:
784             EVP_PKEY *pkey;
785             BIO *bio;
786              
787             ALIAS:
788             pub_exponent = 1
789              
790             CODE:
791 2           pkey = X509_get_pubkey(x509);
792 2           bio = sv_bio_create();
793              
794             /* Silence warning */
795 2 100         if (ix)
796              
797 1 50         if (pkey == NULL) {
798 0           BIO_free_all(bio);
799 0           EVP_PKEY_free(pkey);
800 0           croak("Exponent is unavailable\n");
801             }
802              
803 2 50         if (EVP_PKEY_base_id(pkey) == EVP_PKEY_RSA) {
804             const RSA *rsa_pkey;
805             const BIGNUM *e;
806              
807 2           rsa_pkey = EVP_PKEY_get0_RSA(pkey);
808 2           RSA_get0_key(rsa_pkey, NULL, &e, NULL);
809              
810 2           BN_print(bio, e);
811             } else {
812 0           BIO_free_all(bio);
813 0           EVP_PKEY_free(pkey);
814 0           croak("Wrong Algorithm type -- exponent only available with RSA\n");
815             }
816              
817 2           RETVAL = sv_bio_final(bio);
818              
819 2           EVP_PKEY_free(pkey);
820              
821             OUTPUT:
822             RETVAL
823              
824             SV*
825             fingerprint_md5(x509)
826             Crypt::OpenSSL::X509 x509;
827              
828             ALIAS:
829             fingerprint_sha1 = 1
830             fingerprint_sha224 = 2
831             fingerprint_sha256 = 3
832             fingerprint_sha384 = 4
833             fingerprint_sha512 = 5
834              
835             PREINIT:
836              
837 7           const EVP_MD *mds[] = { EVP_md5(), EVP_sha1(), EVP_sha224(), EVP_sha256(), EVP_sha384(), EVP_sha512() };
838             unsigned char md[EVP_MAX_MD_SIZE];
839             int i;
840             unsigned int n;
841             BIO *bio;
842              
843             CODE:
844              
845 7           bio = sv_bio_create();
846              
847 7 50         if (!X509_digest(x509, mds[ix], md, &n)) {
848              
849 0           BIO_free_all(bio);
850 0           croak("Digest error: %s", ssl_error());
851             }
852              
853 7           BIO_printf(bio, "%02X", md[0]);
854 224 100         for (i = 1; i < n; i++) {
855 217           BIO_printf(bio, ":%02X", md[i]);
856             }
857              
858 7           RETVAL = sv_bio_final(bio);
859              
860             OUTPUT:
861             RETVAL
862              
863             SV*
864             checkend(x509, checkoffset)
865             Crypt::OpenSSL::X509 x509;
866             IV checkoffset;
867              
868             PREINIT:
869             time_t now;
870              
871             CODE:
872              
873 0           now = time(NULL);
874              
875             /* given an offset in seconds, will the certificate be expired? */
876             #if OPENSSL_VERSION_NUMBER < 0x10100000
877 0 0         if (ASN1_UTCTIME_cmp_time_t(X509_get_notAfter(x509), now + (int)checkoffset) == -1) {
878             #else
879             if (ASN1_UTCTIME_cmp_time_t(X509_get0_notAfter(x509), now + (int)checkoffset) == -1) {
880             #endif
881 0           RETVAL = &PL_sv_yes;
882             } else {
883 0           RETVAL = &PL_sv_no;
884             }
885              
886             OUTPUT:
887             RETVAL
888              
889             SV*
890             pubkey(x509)
891             Crypt::OpenSSL::X509 x509;
892              
893             PREINIT:
894             EVP_PKEY *pkey;
895             BIO *bio;
896             int pkey_id;
897              
898             CODE:
899              
900 0           pkey = X509_get_pubkey(x509);
901 0           bio = sv_bio_create();
902              
903 0 0         if (pkey == NULL) {
904              
905 0           BIO_free_all(bio);
906 0           EVP_PKEY_free(pkey);
907 0           croak("Public Key is unavailable\n");
908             }
909              
910 0           pkey_id = EVP_PKEY_base_id(pkey);
911 0 0         if (pkey_id == EVP_PKEY_RSA) {
912             const RSA *rsa_pkey;
913              
914 0           rsa_pkey = EVP_PKEY_get0_RSA(pkey);
915 0           PEM_write_bio_RSAPublicKey(bio, rsa_pkey);
916              
917 0 0         } else if (pkey_id == EVP_PKEY_DSA) {
918             const DSA *dsa_pkey;
919              
920 0           dsa_pkey = EVP_PKEY_get0_DSA(pkey);
921             /* In openssl v3, EVP_PKEY_get0_DSA came to return "const DSA*" type.
922             * However PEM_write_bio_DSA_PUBKEY still needs non-const DSA*.
923             * So we should force to cast dsa_pkey to "DSA*" here.
924             */
925 0           PEM_write_bio_DSA_PUBKEY(bio, (DSA*)dsa_pkey);
926             #ifndef OPENSSL_NO_EC
927 0 0         } else if (pkey_id == EVP_PKEY_EC ) {
928             const EC_KEY *ec_pkey;
929              
930 0           ec_pkey = EVP_PKEY_get0_EC_KEY(pkey);
931             /* In openssl v3, EVP_PKEY_get0_EC_KEY came to return "const EC_KEY*" type.
932             * However PEM_write_bio_EC_PUBKEY still needs non-const EC_KEY*.
933             * So we should force to cast ec_pkey to "EC_KEY*" here.
934             */
935 0           PEM_write_bio_EC_PUBKEY(bio, (EC_KEY*)ec_pkey);
936             #endif
937             } else {
938              
939 0           BIO_free_all(bio);
940 0           EVP_PKEY_free(pkey);
941 0           croak("Wrong Algorithm type\n");
942             }
943              
944 0           EVP_PKEY_free(pkey);
945              
946 0           RETVAL = sv_bio_final(bio);
947              
948             OUTPUT:
949             RETVAL
950              
951             char*
952             pubkey_type(x509)
953             Crypt::OpenSSL::X509 x509;
954             PREINIT:
955             EVP_PKEY *pkey;
956             int pkey_id;
957             CODE:
958 1           RETVAL=NULL;
959 1           pkey = X509_get_pubkey(x509);
960              
961 1 50         if(!pkey)
962 0           XSRETURN_UNDEF;
963              
964 1           pkey_id = EVP_PKEY_base_id(pkey);
965 1 50         if (pkey_id == EVP_PKEY_DSA) {
966 0           RETVAL="dsa";
967              
968 1 50         } else if (pkey_id == EVP_PKEY_RSA) {
969 0           RETVAL="rsa";
970             #ifndef OPENSSL_NO_EC
971 1 50         } else if (pkey_id == EVP_PKEY_EC ) {
972 1           RETVAL="ec";
973             #endif
974             }
975              
976             OUTPUT:
977             RETVAL
978              
979             int
980             num_extensions(x509)
981             Crypt::OpenSSL::X509 x509;
982              
983             CODE:
984 1           RETVAL = X509_get_ext_count(x509);
985              
986             OUTPUT:
987             RETVAL
988              
989             Crypt::OpenSSL::X509::Extension
990             extension(x509, i)
991             Crypt::OpenSSL::X509 x509;
992             int i;
993              
994             PREINIT:
995             X509_EXTENSION *ext;
996             int c;
997              
998             CODE:
999 0           ext = NULL;
1000              
1001 0           c = X509_get_ext_count(x509);
1002              
1003 0 0         if (!(c > 0)) {
1004 0           croak("No extensions found\n");
1005 0 0         } else if (i >= c || i < 0) {
    0          
1006 0           croak("Requested extension index out of range\n");
1007             } else {
1008 0           ext = X509_get_ext(x509, i);
1009             }
1010              
1011 0 0         if (ext == NULL) {
1012             /* X509_EXTENSION_free(ext); // not needed? */
1013 0           croak("Extension unavailable\n");
1014             }
1015              
1016 0           RETVAL = ext;
1017              
1018             OUTPUT:
1019             RETVAL
1020              
1021             HV*
1022             extensions(x509)
1023             Crypt::OpenSSL::X509 x509
1024              
1025             ALIAS:
1026             extensions_by_long_name = 0
1027             extensions_by_oid = 1
1028             extensions_by_name = 2
1029              
1030             CODE:
1031 11           RETVAL = hv_exts(x509, ix);
1032              
1033             OUTPUT:
1034             RETVAL
1035              
1036             MODULE = Crypt::OpenSSL::X509 PACKAGE = Crypt::OpenSSL::X509::Extension
1037              
1038             int
1039             critical(ext)
1040             Crypt::OpenSSL::X509::Extension ext;
1041              
1042             CODE:
1043              
1044 3 50         if (ext == NULL) {
1045 0           croak("No extension supplied\n");
1046             }
1047              
1048 3           RETVAL = X509_EXTENSION_get_critical(ext);
1049              
1050             OUTPUT:
1051             RETVAL
1052              
1053             Crypt::OpenSSL::X509::ObjectID
1054             object(ext)
1055             Crypt::OpenSSL::X509::Extension ext;
1056              
1057             CODE:
1058              
1059 1 50         if (ext == NULL) {
1060 0           croak("No extension supplied\n");
1061             }
1062              
1063 1           RETVAL = X509_EXTENSION_get_object(ext);
1064              
1065             OUTPUT:
1066             RETVAL
1067              
1068             SV*
1069             value(ext)
1070             Crypt::OpenSSL::X509::Extension ext;
1071              
1072             PREINIT:
1073             BIO* bio;
1074              
1075             CODE:
1076 3           bio = sv_bio_create();
1077              
1078 3 50         if (ext == NULL) {
1079 0           BIO_free_all(bio);
1080 0           croak("No extension supplied\n");
1081             }
1082              
1083 3           ASN1_STRING_print_ex(bio, X509_EXTENSION_get_data(ext), ASN1_STRFLGS_DUMP_ALL);
1084              
1085 3           RETVAL = sv_bio_final(bio);
1086              
1087             OUTPUT:
1088             RETVAL
1089              
1090             SV*
1091             to_string(ext)
1092             Crypt::OpenSSL::X509::Extension ext;
1093             ALIAS:
1094             as_string = 1
1095              
1096             PREINIT:
1097             BIO* bio;
1098            
1099             CODE:
1100             (void)ix;
1101 2           bio = sv_bio_create();
1102              
1103 2 50         if (ext == NULL) {
1104 0           BIO_free_all(bio);
1105 0           croak("No extension supplied\n");
1106             }
1107              
1108 2           X509V3_EXT_print(bio, ext, 0, 0);
1109              
1110 2           RETVAL = sv_bio_final(bio);
1111              
1112             OUTPUT:
1113             RETVAL
1114              
1115             int
1116             basicC(ext, value)
1117             Crypt::OpenSSL::X509::Extension ext;
1118             char *value;
1119              
1120             PREINIT:
1121             BASIC_CONSTRAINTS *bs;
1122 1           int ret = 0;
1123              
1124             CODE:
1125              
1126             /* retrieve the value of CA or pathlen in basicConstraints */
1127 1           bs = X509V3_EXT_d2i(ext);
1128              
1129 1 50         if (strcmp(value, "ca") == 0) {
1130 1           ret = bs->ca ? 1 : 0;
1131              
1132 0 0         } else if (strcmp(value, "pathlen") == 0) {
1133 0           ret = bs->pathlen ? 1 : 0;
1134             }
1135              
1136 1           BASIC_CONSTRAINTS_free(bs);
1137              
1138 1           RETVAL = ret;
1139              
1140             OUTPUT:
1141             RETVAL
1142              
1143             SV*
1144             ia5string(ext)
1145             Crypt::OpenSSL::X509::Extension ext;
1146              
1147             PREINIT:
1148             ASN1_IA5STRING *str;
1149             BIO *bio;
1150              
1151             CODE:
1152              
1153             /* retrieving the value of an ia5string object */
1154 0           bio = sv_bio_create();
1155 0           str = X509V3_EXT_d2i(ext);
1156 0           BIO_printf(bio,"%s", str->data);
1157 0           ASN1_IA5STRING_free(str);
1158              
1159 0           RETVAL = sv_bio_final(bio);
1160              
1161             OUTPUT:
1162             RETVAL
1163              
1164             SV*
1165             bit_string(ext)
1166             Crypt::OpenSSL::X509::Extension ext;
1167              
1168             PREINIT:
1169             int i, nid;
1170             ASN1_OBJECT *object;
1171             ASN1_BIT_STRING *bit_str;
1172             int string[10];
1173             BIO *bio;
1174              
1175             CODE:
1176 1           bio = sv_bio_create();
1177              
1178 1           object = X509_EXTENSION_get_object(ext);
1179 1           nid = OBJ_obj2nid(object);
1180 1           bit_str = X509V3_EXT_d2i(ext);
1181              
1182 1 50         if (nid == NID_key_usage) {
1183              
1184 10 100         for (i = 0; i < 9; i++) {
1185 9           string[i] = (int)ASN1_BIT_STRING_get_bit(bit_str, i);
1186 9           BIO_printf(bio, "%d", string[i]);
1187             }
1188              
1189 0 0         } else if (nid == NID_netscape_cert_type) {
1190              
1191 0 0         for (i = 0; i < 8; i++) {
1192 0           string[i] = (int)ASN1_BIT_STRING_get_bit(bit_str, i);
1193 0           BIO_printf(bio, "%d", string[i]);
1194             }
1195             }
1196              
1197 1           RETVAL = sv_bio_final(bio);
1198              
1199             OUTPUT:
1200             RETVAL
1201              
1202             SV*
1203             extendedKeyUsage(ext)
1204             Crypt::OpenSSL::X509::Extension ext;
1205              
1206             PREINIT:
1207             BIO *bio;
1208             STACK_OF(ASN1_OBJECT) *extku;
1209             int nid;
1210             const char *value;
1211              
1212             CODE:
1213              
1214 0           bio = sv_bio_create();
1215 0           extku = (STACK_OF(ASN1_OBJECT)*) X509V3_EXT_d2i(ext);
1216              
1217 0 0         while(sk_ASN1_OBJECT_num(extku) > 0) {
1218 0           nid = OBJ_obj2nid(sk_ASN1_OBJECT_pop(extku));
1219 0           value = OBJ_nid2sn(nid);
1220 0           BIO_printf(bio, "%s", value);
1221 0           BIO_printf(bio, " ");
1222             }
1223              
1224 0           RETVAL = sv_bio_final(bio);
1225              
1226             OUTPUT:
1227             RETVAL
1228              
1229             int
1230             auth_att(ext)
1231             Crypt::OpenSSL::X509::Extension ext;
1232              
1233             PREINIT:
1234             AUTHORITY_KEYID *akid;
1235              
1236             CODE:
1237              
1238 0           akid = X509V3_EXT_d2i(ext);
1239 0           RETVAL = akid->keyid ? 1 : 0;
1240              
1241             OUTPUT:
1242             RETVAL
1243              
1244             SV*
1245             keyid_data(ext)
1246             Crypt::OpenSSL::X509::Extension ext;
1247              
1248             PREINIT:
1249             AUTHORITY_KEYID *akid;
1250             ASN1_OCTET_STRING *skid;
1251             int nid;
1252             ASN1_OBJECT *object;
1253             BIO *bio;
1254              
1255             CODE:
1256              
1257 1           bio = sv_bio_create();
1258 1           object = X509_EXTENSION_get_object(ext);
1259 1           nid = OBJ_obj2nid(object);
1260              
1261 1 50         if (nid == NID_authority_key_identifier) {
1262              
1263 0           akid = X509V3_EXT_d2i(ext);
1264 0           BIO_printf(bio, "%s", akid->keyid->data);
1265              
1266 1 50         } else if (nid == NID_subject_key_identifier) {
1267              
1268 1           skid = X509V3_EXT_d2i(ext);
1269 1           BIO_printf(bio, "%s", skid->data);
1270             }
1271              
1272 1           RETVAL = sv_bio_final(bio);
1273              
1274             OUTPUT:
1275             RETVAL
1276              
1277             MODULE = Crypt::OpenSSL::X509 PACKAGE = Crypt::OpenSSL::X509::ObjectID
1278             char*
1279             name(obj)
1280             Crypt::OpenSSL::X509::ObjectID obj;
1281              
1282             PREINIT:
1283             char buf[128];
1284              
1285             CODE:
1286              
1287 1 50         if (obj == NULL) {
1288 0           croak("No ObjectID supplied\n");
1289             }
1290              
1291 1           (void)OBJ_obj2txt(buf, 128, obj, 0);
1292              
1293 1           RETVAL = buf;
1294              
1295             OUTPUT:
1296             RETVAL
1297              
1298             char*
1299             oid(obj)
1300             Crypt::OpenSSL::X509::ObjectID obj;
1301              
1302             PREINIT:
1303             char buf[128];
1304              
1305             CODE:
1306              
1307 0 0         if (obj == NULL) {
1308 0           croak("No ObjectID supplied\n");
1309             }
1310              
1311 0           (void)OBJ_obj2txt(buf, 128, obj, 1);
1312              
1313 0           RETVAL = buf;
1314              
1315             OUTPUT:
1316             RETVAL
1317              
1318             MODULE = Crypt::OpenSSL::X509 PACKAGE = Crypt::OpenSSL::X509::Name
1319              
1320             SV*
1321             as_string(name)
1322             Crypt::OpenSSL::X509::Name name;
1323              
1324             PREINIT:
1325             BIO *bio;
1326              
1327             CODE:
1328              
1329 2           bio = sv_bio_create();
1330             /* this is prefered over X509_NAME_oneline() */
1331 2           X509_NAME_print_ex(bio, name, 0, XN_FLAG_SEP_CPLUS_SPC);
1332              
1333 2           RETVAL = sv_bio_final(bio);
1334              
1335             OUTPUT:
1336             RETVAL
1337              
1338             AV*
1339             entries(name)
1340             Crypt::OpenSSL::X509::Name name;
1341              
1342             PREINIT:
1343             int i, c;
1344             SV* rv;
1345              
1346             CODE:
1347              
1348 1           RETVAL = newAV();
1349 1           sv_2mortal((SV*)RETVAL);
1350              
1351 1           c = X509_NAME_entry_count(name);
1352              
1353 8 100         for (i = 0; i < c; i++) {
1354 7           rv = sv_make_ref("Crypt::OpenSSL::X509::Name_Entry", (void*)X509_NAME_get_entry(name, i));
1355 7           av_push(RETVAL, rv);
1356             }
1357              
1358             OUTPUT:
1359             RETVAL
1360              
1361             int
1362             get_index_by_type(name, type, lastpos = -1)
1363             Crypt::OpenSSL::X509::Name name;
1364             const char* type;
1365             int lastpos;
1366              
1367             ALIAS:
1368             get_index_by_long_type = 1
1369             has_entry = 2
1370             has_long_entry = 3
1371             has_oid_entry = 4
1372             get_index_by_oid_type = 5
1373              
1374             PREINIT:
1375             int nid, i;
1376              
1377             CODE:
1378              
1379 6 100         if (ix == 1 || ix == 3) {
    100          
1380 2           nid = OBJ_ln2nid(type);
1381 4 100         } else if (ix == 4 || ix == 5) {
    50          
1382 2           nid = OBJ_obj2nid(OBJ_txt2obj(type, /*oid*/ 1));
1383             } else {
1384 2           nid = OBJ_sn2nid(type);
1385             }
1386              
1387 6 50         if (!nid) {
1388 0           croak("Unknown type");
1389             }
1390              
1391 6           i = X509_NAME_get_index_by_NID(name, nid, lastpos);
1392              
1393 6 100         if (ix == 2 || ix == 3 || ix == 4) { /* has_entry */
    100          
    100          
1394 4           RETVAL = (i > lastpos)?1:0;
1395             } else { /* get_index */
1396 2           RETVAL = i;
1397             }
1398              
1399             OUTPUT:
1400             RETVAL
1401              
1402             Crypt::OpenSSL::X509::Name_Entry
1403             get_entry_by_type(name, type, lastpos = -1)
1404             Crypt::OpenSSL::X509::Name name;
1405             const char* type;
1406             int lastpos;
1407              
1408             ALIAS:
1409             get_entry_by_long_type = 1
1410              
1411             PREINIT:
1412             int nid, i;
1413              
1414             CODE:
1415              
1416 3 50         if (ix == 1) {
1417 0           nid = OBJ_ln2nid(type);
1418             } else {
1419 3           nid = OBJ_sn2nid(type);
1420             }
1421              
1422 3 50         if (!nid) {
1423 0           croak("Unknown type");
1424             }
1425              
1426 3           i = X509_NAME_get_index_by_NID(name, nid, lastpos);
1427 3           RETVAL = X509_NAME_get_entry(name, i);
1428              
1429             OUTPUT:
1430             RETVAL
1431              
1432              
1433             MODULE = Crypt::OpenSSL::X509 PACKAGE = Crypt::OpenSSL::X509::Name_Entry
1434              
1435             SV*
1436             as_string(name_entry, ln = 0)
1437             Crypt::OpenSSL::X509::Name_Entry name_entry;
1438             int ln;
1439              
1440             ALIAS:
1441             as_long_string = 1
1442              
1443             PREINIT:
1444             BIO *bio;
1445             const char *n;
1446             int nid;
1447              
1448             CODE:
1449 2           bio = sv_bio_create();
1450 2           nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(name_entry));
1451              
1452 2 100         if (ix == 1 || ln) {
    50          
1453 1           n = OBJ_nid2ln(nid);
1454             } else {
1455 1           n = OBJ_nid2sn(nid);
1456             }
1457              
1458 2           BIO_printf(bio, "%s=", n);
1459              
1460 2           ASN1_STRING_print_ex(bio, X509_NAME_ENTRY_get_data(name_entry), ASN1_STRFLGS_UTF8_CONVERT & ~ASN1_STRFLGS_ESC_MSB);
1461              
1462 2           sv_bio_utf8_on(bio);
1463              
1464 2           RETVAL = sv_bio_final(bio);
1465              
1466             OUTPUT:
1467             RETVAL
1468              
1469             SV*
1470             type(name_entry, ln = 0)
1471             Crypt::OpenSSL::X509::Name_Entry name_entry;
1472             int ln;
1473              
1474             ALIAS:
1475             long_type = 1
1476              
1477             PREINIT:
1478             BIO *bio;
1479             const char *n;
1480             int nid;
1481              
1482             CODE:
1483 2           bio = sv_bio_create();
1484 2           nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(name_entry));
1485              
1486 2 100         if (ix == 1 || ln) {
    50          
1487 1           n = OBJ_nid2ln(nid);
1488             } else {
1489 1           n = OBJ_nid2sn(nid);
1490             }
1491              
1492 2           BIO_printf(bio, "%s", n);
1493 2           RETVAL = sv_bio_final(bio);
1494              
1495             OUTPUT:
1496             RETVAL
1497              
1498             SV*
1499             value(name_entry)
1500             Crypt::OpenSSL::X509::Name_Entry name_entry;
1501              
1502             PREINIT:
1503             BIO *bio;
1504              
1505             CODE:
1506 1           bio = sv_bio_create();
1507 1           ASN1_STRING_print(bio, X509_NAME_ENTRY_get_data(name_entry));
1508 1           RETVAL = sv_bio_final(bio);
1509              
1510             OUTPUT:
1511             RETVAL
1512              
1513             int
1514             is_printableString(name_entry, asn1_type = V_ASN1_PRINTABLESTRING)
1515             Crypt::OpenSSL::X509::Name_Entry name_entry;
1516             int asn1_type;
1517              
1518             ALIAS:
1519             is_asn1_type = 1
1520             is_printableString = V_ASN1_PRINTABLESTRING
1521             is_ia5string = V_ASN1_IA5STRING
1522             is_utf8string = V_ASN1_UTF8STRING
1523              
1524             CODE:
1525 2 100         RETVAL = (X509_NAME_ENTRY_get_data(name_entry)->type == (ix == 1 ? asn1_type : ix));
1526              
1527             OUTPUT:
1528             RETVAL
1529              
1530             char*
1531             encoding(name_entry)
1532             Crypt::OpenSSL::X509::Name_Entry name_entry;
1533              
1534             CODE:
1535 0           RETVAL = NULL;
1536              
1537 0 0         if (X509_NAME_ENTRY_get_data(name_entry)->type == V_ASN1_PRINTABLESTRING) {
1538 0           RETVAL = "printableString";
1539              
1540 0 0         } else if(X509_NAME_ENTRY_get_data(name_entry)->type == V_ASN1_IA5STRING) {
1541 0           RETVAL = "ia5String";
1542              
1543 0 0         } else if(X509_NAME_ENTRY_get_data(name_entry)->type == V_ASN1_UTF8STRING) {
1544 0           RETVAL = "utf8String";
1545             }
1546              
1547             OUTPUT:
1548             RETVAL
1549              
1550             MODULE = Crypt::OpenSSL::X509 PACKAGE = Crypt::OpenSSL::X509_CRL
1551              
1552             Crypt::OpenSSL::X509::CRL
1553             new_from_crl_string(class, string, format = FORMAT_PEM)
1554             SV *class;
1555             SV *string;
1556             int format;
1557              
1558             ALIAS:
1559             new_from_crl_file = 1
1560              
1561             PREINIT:
1562             BIO *bio;
1563             STRLEN len;
1564             char *crl;
1565              
1566             CODE:
1567              
1568 0 0         crl = SvPV(string, len);
1569              
1570 0 0         if (ix == 1) {
1571 0           bio = BIO_new_file(crl, "r");
1572             } else {
1573 0           bio = BIO_new_mem_buf(crl, len);
1574             }
1575              
1576 0 0         if (!bio) {
1577 0 0         croak("%s: Failed to create BIO", SvPV_nolen(class));
1578             }
1579              
1580 0 0         if (format == FORMAT_ASN1) {
1581 0           RETVAL = (X509_CRL*)d2i_X509_CRL_bio(bio, NULL);
1582             } else {
1583 0           RETVAL = (X509_CRL*)PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
1584             }
1585              
1586 0 0         if (!RETVAL) {
1587 0 0         croak("%s: failed to read X509 certificate.", SvPV_nolen(class));
1588             }
1589              
1590 0           BIO_free(bio);
1591              
1592             OUTPUT:
1593             RETVAL
1594              
1595             SV*
1596             CRL_accessor(crl)
1597             Crypt::OpenSSL::X509::CRL crl;
1598              
1599             ALIAS:
1600             CRL_issuer = 1
1601             CRL_sig_alg_name = 2
1602              
1603             PREINIT:
1604             BIO *bio;
1605             X509_NAME *name;
1606              
1607             CODE:
1608 0           bio = sv_bio_create();
1609              
1610 0 0         if (ix == 1) {
1611 0           name = X509_CRL_get_issuer(crl);
1612 0           sv_bio_utf8_on(bio);
1613 0           X509_NAME_print_ex(bio, name, 0, (XN_FLAG_SEP_CPLUS_SPC | ASN1_STRFLGS_UTF8_CONVERT) & ~ASN1_STRFLGS_ESC_MSB);
1614              
1615 0 0         } else if (ix == 2) {
1616             const_ossl11 X509_ALGOR *palg;
1617             const_ossl11 ASN1_OBJECT *paobj;
1618              
1619 0           X509_CRL_get0_signature(crl, NULL, &palg);
1620 0           X509_ALGOR_get0(&paobj, NULL, NULL, palg);
1621              
1622 0           i2a_ASN1_OBJECT(bio, paobj);
1623             }
1624              
1625 0           RETVAL = sv_bio_final(bio);
1626              
1627             OUTPUT:
1628             RETVAL