File Coverage

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