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