File Coverage

X509.xs
Criterion Covered Total %
statement 246 457 53.8
branch 114 236 48.3
condition n/a
subroutine n/a
pod n/a
total 360 693 51.9


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