1 #ifdef __cplusplus
2 extern "C" {
3 #endif
4
5 #include "EXTERN.h"
6 #include "perl.h"
7 #include "XSUB.h"
8
9 #ifdef __cplusplus
10 }
11 #endif
12
13 #include <botan/asn1_obj.h>
14 #include <botan/asn1_oid.h>
15 #include <botan/filters.h>
16 #include <botan/init.h>
17 #include <botan/oids.h>
18 #include <botan/x509cert.h>
19 #include <botan/x509_ext.h>
20
21
22 /* xsubpp converts ':' to '_' in typemap. We create our types without ':' */
23
24 typedef Botan::ASN1_String Botan__ASN1_String;
25 typedef Botan::AlgorithmIdentifier Botan__AlgorithmIdentifier;
26 typedef Botan::AlternativeName Botan__AlternativeName;
27 typedef Botan::Attribute Botan__Attribute;
28 typedef Botan::Base64_Decoder Botan__Base64_Decoder;
29 typedef Botan::Base64_Encoder Botan__Base64_Encoder;
30 typedef Botan::Chain Botan__Chain;
31 typedef Botan::Certificate_Extension Botan__Extension;
32 typedef Botan::Filter Botan__Filter;
33 typedef Botan::Fork Botan__Fork;
34 typedef Botan::Hex_Decoder Botan__Hex_Decoder;
35 typedef Botan::Hex_Encoder Botan__Hex_Encoder;
36 typedef Botan::OID Botan__OID;
37 typedef Botan::Pipe Botan__Pipe;
38 typedef Botan::X509_Certificate Botan__X509_Certificate;
39 typedef Botan::X509_DN Botan__X509_DN;
40 typedef Botan::X509_Time Botan__X509_Time;
41 typedef Botan::u32bit Botan__u32bit;
42
43
44 /* Types to keep track of destruction C++ objects passed
45 * into other objects...
46 * An Botan object is deleted by his parent object into which is passed,
47 * e.g. some Filter is deleted when his Pipe is destructed. We must
48 * track this and not to delete object again in Perls destructor.
49 */
50
51 class ObjectInfo
52 {
53 private:
54 I32 d_signature;
55 bool d_del;
56 public:
57 static I32 const SIGNVAL = 0x696a626f;
ObjectInfo()58 ObjectInfo() : d_signature(SIGNVAL),
59 d_del(true) {};
~ObjectInfo()60 ~ObjectInfo() {};
61 void set_delete(bool del = true) { d_del = del; };
set_delete_no()62 void set_delete_no() { set_delete(false); };
set_delete_yes()63 void set_delete_yes() { set_delete(true); };
should_delete()64 bool should_delete() const { return d_del; };
65 };
66
67 /* Constant object in initial state - template */
68
69 ObjectInfo const oi_init;
70
71
72 /* Botan library initializer ... */
73
74 Botan::LibraryInitializer botan_init;
75
76
77
78 /*============================================================================*/
79
80 MODULE = Botan PACKAGE = Botan
81
82 PROTOTYPES: ENABLE
83
84 void
85 constant(char *name)
86 CODE:
87 using namespace Botan;
88 errno = 0;
89 switch (name[0])
90 {
91 case 'F':
92 if ( strEQ(name, "FULL_CHECK") )
93 XSRETURN_IV( FULL_CHECK ); // Decoder_Checking enum
94 break;
95 case 'I':
96 if ( strEQ(name, "IGNORE_WS") )
97 XSRETURN_IV( IGNORE_WS ); // Decoder_Checking enum
98 break;
99 case 'N':
100 if ( strEQ(name, "NONE") )
101 XSRETURN_IV( NONE ); // Decoder_Checking enum
102 break;
103 }
104 errno = EINVAL;
105 XSRETURN_UNDEF;
106
107
108 # =========================== Botan::Chain ==========================
109
110 MODULE = Botan PACKAGE = Botan::Chain
111
112 Botan__Chain *
113 Botan__Chain::new(f1 = 0, f2 = 0, f3 = 0, f4 = 0)
114 Botan__Filter *f1;
115 Botan__Filter *f2;
116 Botan__Filter *f3;
117 Botan__Filter *f4;
118 PREINIT:
119 ObjectInfo *f1_oi;
120 ObjectInfo *f2_oi;
121 ObjectInfo *f3_oi;
122 ObjectInfo *f4_oi;
123 CODE:
124 try {
125 RETVAL = new Botan__Chain(f1, f2, f3, f4);
126 if ( f1 ) f1_oi->set_delete_no();
127 if ( f2 ) f2_oi->set_delete_no();
128 if ( f3 ) f3_oi->set_delete_no();
129 if ( f4 ) f4_oi->set_delete_no();
130 }
catch(const std::exception & e)131 catch (const std::exception &e) {
132 croak(e.what());
133 }
134 OUTPUT:
135 RETVAL
136
137 void
138 Botan__Chain::DESTROY()
139 PREINIT:
140 ObjectInfo *THIS_oi;
141 CODE:
142 if ( THIS_oi->should_delete() )
143 try {
144 delete THIS;
145 }
catch(const std::exception & e)146 catch (const std::exception &e) {
147 croak(e.what());
148 }
149
150
151 # =========================== Botan::Fork ==========================
152
153 MODULE = Botan PACKAGE = Botan::Fork
154
155 Botan__Fork *
156 Botan__Fork::new(f1 = 0, f2 = 0, f3 = 0, f4 = 0)
157 Botan__Filter *f1;
158 Botan__Filter *f2;
159 Botan__Filter *f3;
160 Botan__Filter *f4;
161 PREINIT:
162 ObjectInfo *f1_oi;
163 ObjectInfo *f2_oi;
164 ObjectInfo *f3_oi;
165 ObjectInfo *f4_oi;
166 CODE:
167 try {
168 RETVAL = new Botan__Fork(f1, f2, f3, f4);
169 if ( f1 ) f1_oi->set_delete_no();
170 if ( f2 ) f2_oi->set_delete_no();
171 if ( f3 ) f3_oi->set_delete_no();
172 if ( f4 ) f4_oi->set_delete_no();
173 }
catch(const std::exception & e)174 catch (const std::exception &e) {
175 croak(e.what());
176 }
177 OUTPUT:
178 RETVAL
179
180 void
181 Botan__Fork::DESTROY()
182 PREINIT:
183 ObjectInfo *THIS_oi;
184 CODE:
185 if ( THIS_oi->should_delete() )
186 try {
187 delete THIS;
188 }
catch(const std::exception & e)189 catch (const std::exception &e) {
190 croak(e.what());
191 }
192
193
194 # ============================ Botan::Base64_Decoder ============================
195
196 MODULE = Botan PACKAGE = Botan::Base64_Decoder
197
198 Botan__Base64_Decoder *
199 Botan__Base64_Decoder::new(checking = Botan::NONE)
200 int checking;
201 CODE:
202 try {
203 using namespace Botan;
204 RETVAL = new Base64_Decoder((Decoder_Checking)checking);
205 }
catch(const std::exception & e)206 catch (const std::exception &e) {
207 croak(e.what());
208 }
209 OUTPUT:
210 RETVAL
211
212 void
213 Botan__Base64_Decoder::DESTROY()
214 PREINIT:
215 ObjectInfo *THIS_oi;
216 CODE:
217 if ( THIS_oi->should_delete() )
218 try {
219 delete THIS;
220 }
catch(const std::exception & e)221 catch (const std::exception &e) {
222 croak(e.what());
223 }
224
225
226 # =========================== Botan::Base64_Encoder ==========================
227
228 MODULE = Botan PACKAGE = Botan::Base64_Encoder
229
230 Botan__Base64_Encoder *
231 Botan__Base64_Encoder::new(breaks = false, length = 72)
232 bool breaks;
233 Botan__u32bit length;
234 CODE:
235 try {
236 RETVAL = new Botan__Base64_Encoder(breaks, length);
237 }
catch(const std::exception & e)238 catch (const std::exception &e) {
239 croak(e.what());
240 }
241 OUTPUT:
242 RETVAL
243
244 void
245 Botan__Base64_Encoder::DESTROY()
246 PREINIT:
247 ObjectInfo *THIS_oi;
248 CODE:
249 if ( THIS_oi->should_delete() )
250 try {
251 delete THIS;
252 }
catch(const std::exception & e)253 catch (const std::exception &e) {
254 croak(e.what());
255 }
256
257
258 # ============================ Botan::Hex_Decoder ============================
259
260 MODULE = Botan PACKAGE = Botan::Hex_Decoder
261
262 Botan__Hex_Decoder *
263 Botan__Hex_Decoder::new(checking = Botan::NONE)
264 int checking;
265 CODE:
266 try {
267 using namespace Botan;
268 RETVAL = new Hex_Decoder((Decoder_Checking)checking);
269 }
catch(const std::exception & e)270 catch (const std::exception &e) {
271 croak(e.what());
272 }
273 OUTPUT:
274 RETVAL
275
276 void
277 Botan__Hex_Decoder::DESTROY()
278 PREINIT:
279 ObjectInfo *THIS_oi;
280 CODE:
281 if ( THIS_oi->should_delete() )
282 try {
283 delete THIS;
284 }
catch(const std::exception & e)285 catch (const std::exception &e) {
286 croak(e.what());
287 }
288
289
290 # ============================ Botan::Hex_Encoder ============================
291
292 MODULE = Botan PACKAGE = Botan::Hex_Encoder
293
294 Botan__Hex_Encoder *
295 Botan__Hex_Encoder::new(breaks = false, length = 72, lcase = false)
296 bool breaks;
297 Botan__u32bit length;
298 bool lcase;
299 CODE:
300 try {
301 using Botan::Hex_Encoder;
302 RETVAL = new Hex_Encoder(breaks, length,
303 lcase ? Hex_Encoder::Lowercase : Hex_Encoder::Uppercase);
304 }
catch(const std::exception & e)305 catch (const std::exception &e) {
306 croak(e.what());
307 }
308 OUTPUT:
309 RETVAL
310
311 void
312 Botan__Hex_Encoder::DESTROY()
313 PREINIT:
314 ObjectInfo *THIS_oi;
315 CODE:
316 if ( THIS_oi->should_delete() )
317 try {
318 delete THIS;
319 }
catch(const std::exception & e)320 catch (const std::exception &e) {
321 croak(e.what());
322 }
323
324
325 # ================================ Botan::OID ================================
326
327 MODULE = Botan PACKAGE = Botan::OID
328
329 Botan__OID *
new(s)330 Botan__OID::new(s)
331 char *s;
332 CODE:
333 try {
334 RETVAL = new Botan__OID(s);
335 }
catch(const std::exception & e)336 catch (const std::exception &e) {
337 croak(e.what());
338 }
339 OUTPUT:
340 RETVAL
341
342 void
DESTROY()343 Botan__OID::DESTROY()
344 CODE:
345 try {
346 delete THIS;
347 }
catch(const std::exception & e)348 catch (const std::exception &e) {
349 croak(e.what());
350 }
351
352 char *
as_string()353 Botan__OID::as_string()
354 CODE:
355 try {
356 RETVAL = const_cast<char *>(THIS->as_string().c_str());
357 }
catch(const std::exception & e)358 catch (const std::exception &e) {
359 croak(e.what());
360 }
361 OUTPUT:
362 RETVAL
363
364
365 # ================================ Botan::OIDS ================================
366
367 MODULE = Botan PACKAGE = Botan::OIDS
368
369 void
add_oid(oid,name)370 add_oid(oid, name)
371 Botan__OID *oid;
372 char *name;
373 CODE:
374 try {
375 Botan::OIDS::add_oid(*oid, name);
376 }
catch(const std::exception & e)377 catch (const std::exception &e) {
378 croak(e.what());
379 }
380
381 char *
lookup_by_oid(oid)382 lookup_by_oid(oid)
383 Botan__OID *oid;
384 CODE:
385 try {
386 RETVAL = const_cast<char *>(Botan::OIDS::lookup(*oid).c_str());
387 }
catch(const std::exception & e)388 catch (const std::exception &e) {
389 croak(e.what());
390 }
391 OUTPUT:
392 RETVAL
393
394 Botan__OID *
lookup_by_name(name)395 lookup_by_name(name)
396 char *name;
397 CODE:
398 try {
399 RETVAL = new Botan__OID(Botan::OIDS::lookup(name));
400 }
catch(const std::exception & e)401 catch (const std::exception &e) {
402 croak(e.what());
403 }
404 char const * CLASS = "Botan::OID";
405 OUTPUT:
406 RETVAL
407
408 int
have_oid(name)409 have_oid(name)
410 char *name;
411 CODE:
412 try {
413 RETVAL = Botan::OIDS::have_oid(name);
414 }
catch(const std::exception & e)415 catch (const std::exception &e) {
416 croak(e.what());
417 }
418 OUTPUT:
419 RETVAL
420
421
422 # ================================ Botan::Pipe ================================
423
424 MODULE = Botan PACKAGE = Botan::Pipe
425
426 Botan__Pipe *
427 Botan__Pipe::new(...)
428 CODE:
429 for (I32 i = 1; i < items; i++)
430 {
431 if ( !sv_isobject(ST(i)) || (SvTYPE(SvRV(ST(i))) != SVt_PVMG) )
432 croak("Botan::Pipe::new() -- arg %u is not "
433 "a blessed SV reference", i +1);
434 if ( !sv_derived_from(ST(i), "Botan::Filter") )
435 croak("Botan::Pipe::new() -- arg %u is not "
436 "an object derived from Botan::Filter", i +1);
437 MAGIC *mg = mg_find(SvRV(ST(i)), '~');
438 if ( mg == 0
439 || mg->mg_len != sizeof(ObjectInfo)
440 || *(I32 *)(mg->mg_ptr) != ObjectInfo::SIGNVAL )
441 croak("Botan::Pipe::new() -- arg %u has no "
442 "valid private magic data (ObjectInfo)", i +1);
443 }
444 try {
445 RETVAL = new Botan__Pipe();
446 for (I32 i = 1; i < items; i++)
447 {
448 SV *osv = (SV *)SvRV(ST(i));
449 ObjectInfo *oi = (ObjectInfo *)(mg_find(osv, '~')->mg_ptr);
450 RETVAL->append((Botan__Filter *)(SvIV(osv)));
451 oi->set_delete_no();
452 }
453 }
catch(const std::exception & e)454 catch (const std::exception &e) {
455 croak(e.what());
456 }
457 OUTPUT:
458 RETVAL
459
460 void
461 Botan__Pipe::DESTROY()
462 PREINIT:
463 ObjectInfo *THIS_oi;
464 CODE:
465 try {
466 delete THIS;
467 }
catch(const std::exception & e)468 catch (const std::exception &e) {
469 croak(e.what());
470 }
471
472 void
473 Botan__Pipe::write(s)
474 SV *s;
475 PREINIT:
476 ObjectInfo *THIS_oi;
477 CODE:
478 STRLEN len;
479 char *ptr = SvPV(s, len);
480 try {
481 THIS->write((unsigned char *)ptr, len);
482 }
catch(const std::exception & e)483 catch (const std::exception &e) {
484 croak(e.what());
485 }
486
487 void
488 Botan__Pipe::process_msg(s)
489 SV *s;
490 PREINIT:
491 ObjectInfo *THIS_oi;
492 CODE:
493 STRLEN len;
494 char *ptr = SvPV(s, len);
495 try {
496 THIS->process_msg((unsigned char *)ptr, len);
497 }
catch(const std::exception & e)498 catch (const std::exception &e) {
499 croak(e.what());
500 }
501
502 Botan__u32bit
503 Botan__Pipe::remaining(msgno = Botan::Pipe::DEFAULT_MESSAGE)
504 Botan__u32bit msgno;
505 PREINIT:
506 ObjectInfo *THIS_oi;
507 CODE:
508 try {
509 RETVAL = THIS->remaining(msgno);
510 }
catch(const std::exception & e)511 catch (const std::exception &e) {
512 croak(e.what());
513 }
514 OUTPUT:
515 RETVAL
516
517 SV *
518 Botan__Pipe::read(len = 0xFFFFFFFF, msgno = Botan::Pipe::DEFAULT_MESSAGE)
519 Botan__u32bit len;
520 Botan__u32bit msgno;
521 PREINIT:
522 ObjectInfo *THIS_oi;
523 CODE:
524 try {
525 if ( len > THIS->remaining(msgno) )
526 len = THIS->remaining(msgno);
527 RETVAL = NEWSV(0, len);
528 SvPOK_on(RETVAL);
529 if ( len > 0 )
530 SvCUR_set(RETVAL, THIS->read((unsigned char *)SvPVX(RETVAL),
531 len, msgno));
532 }
catch(const std::exception & e)533 catch (const std::exception &e) {
534 croak(e.what());
535 }
536 OUTPUT:
537 RETVAL
538
539 SV *
540 Botan__Pipe::peek(len = 0xFFFFFFFF, offset = 0, \
541 msgno = Botan::Pipe::DEFAULT_MESSAGE)
542 Botan__u32bit len;
543 Botan__u32bit offset;
544 Botan__u32bit msgno;
545 PREINIT:
546 ObjectInfo *THIS_oi;
547 CODE:
548 try {
549 if ( len > THIS->remaining(msgno) )
550 len = THIS->remaining(msgno);
551 RETVAL = NEWSV(0, len);
552 SvPOK_on(RETVAL);
553 if ( len > 0 )
554 SvCUR_set(RETVAL, THIS->peek((unsigned char *)SvPVX(RETVAL),
555 len, offset, msgno));
556 }
catch(const std::exception & e)557 catch (const std::exception &e) {
558 croak(e.what());
559 }
560 OUTPUT:
561 RETVAL
562
563 Botan__u32bit
564 Botan__Pipe::default_msg()
565 PREINIT:
566 ObjectInfo *THIS_oi;
567 CODE:
568 try {
569 RETVAL = THIS->default_msg();
570 }
catch(const std::exception & e)571 catch (const std::exception &e) {
572 croak(e.what());
573 }
574 OUTPUT:
575 RETVAL
576
577 void
578 Botan__Pipe::set_default_msg(msgno)
579 Botan__u32bit msgno;
580 PREINIT:
581 ObjectInfo *THIS_oi;
582 CODE:
583 try {
584 THIS->set_default_msg(msgno);
585 }
catch(const std::exception & e)586 catch (const std::exception &e) {
587 croak(e.what());
588 }
589
590 Botan__u32bit
591 Botan__Pipe::message_count()
592 PREINIT:
593 ObjectInfo *THIS_oi;
594 CODE:
595 try {
596 RETVAL = THIS->message_count();
597 }
catch(const std::exception & e)598 catch (const std::exception &e) {
599 croak(e.what());
600 }
601 OUTPUT:
602 RETVAL
603
604 bool
605 Botan__Pipe::end_of_data()
606 PREINIT:
607 ObjectInfo *THIS_oi;
608 CODE:
609 try {
610 RETVAL = THIS->end_of_data();
611 }
catch(const std::exception & e)612 catch (const std::exception &e) {
613 croak(e.what());
614 }
615 OUTPUT:
616 RETVAL
617
618 void
619 Botan__Pipe::start_msg()
620 PREINIT:
621 ObjectInfo *THIS_oi;
622 CODE:
623 try {
624 THIS->start_msg();
625 }
catch(const std::exception & e)626 catch (const std::exception &e) {
627 croak(e.what());
628 }
629
630 void
631 Botan__Pipe::end_msg()
632 PREINIT:
633 ObjectInfo *THIS_oi;
634 CODE:
635 try {
636 THIS->end_msg();
637 }
catch(const std::exception & e)638 catch (const std::exception &e) {
639 croak(e.what());
640 }
641
642 void
643 Botan__Pipe::reset()
644 PREINIT:
645 ObjectInfo *THIS_oi;
646 CODE:
647 try {
648 THIS->reset();
649 }
catch(const std::exception & e)650 catch (const std::exception &e) {
651 croak(e.what());
652 }
653
654
655 # ========================== Botan::X509_Certificate ==========================
656
657 MODULE = Botan PACKAGE = Botan::X509_Certificate
658
659 Botan__X509_Certificate *
new(char * fn)660 Botan__X509_Certificate::new(char *fn)
661 CODE:
662 try {
663 RETVAL = new Botan__X509_Certificate(fn);
664 }
catch(const std::exception & e)665 catch (const std::exception &e) {
666 croak(e.what());
667 }
668 OUTPUT:
669 RETVAL
670
671 void
DESTROY()672 Botan__X509_Certificate::DESTROY()
673 CODE:
674 try {
675 delete THIS;
676 }
catch(const std::exception & e)677 catch (const std::exception &e) {
678 croak(e.what());
679 }
680
681 unsigned int
x509_version()682 Botan__X509_Certificate::x509_version()
683 CODE:
684 try {
685 RETVAL = THIS->x509_version();
686 }
catch(const std::exception & e)687 catch (const std::exception &e) {
688 croak(e.what());
689 }
690 OUTPUT:
691 RETVAL
692
693 char *
start_time()694 Botan__X509_Certificate::start_time()
695 CODE:
696 try {
697 RETVAL = const_cast<char *>(THIS->start_time().c_str());
698 }
catch(const std::exception & e)699 catch (const std::exception &e) {
700 croak(e.what());
701 }
702 OUTPUT:
703 RETVAL
704
705 char *
end_time()706 Botan__X509_Certificate::end_time()
707 CODE:
708 try {
709 RETVAL = const_cast<char *>(THIS->end_time().c_str());
710 }
catch(const std::exception & e)711 catch (const std::exception &e) {
712 croak(e.what());
713 }
714 OUTPUT:
715 RETVAL
716
717 char *
subject_info(char * info)718 Botan__X509_Certificate::subject_info(char *info)
719 CODE:
720 try {
721 std::vector<std::string> s = THIS->subject_info(info);
722
723 if(s.size() > 0)
724 RETVAL = const_cast<char *>(s[0].c_str());
725 else
726 RETVAL = "err";
727 }
catch(const std::exception & e)728 catch (const std::exception &e) {
729 croak(e.what());
730 }
731 OUTPUT:
732 RETVAL
733
734 char *
issuer_info(char * info)735 Botan__X509_Certificate::issuer_info(char *info)
736 CODE:
737 try {
738 std::vector<std::string> s = THIS->subject_info(info);
739
740 if(s.size() > 0)
741 RETVAL = const_cast<char *>(s[0].c_str());
742 else
743 RETVAL = "err";
744 }
catch(const std::exception & e)745 catch (const std::exception &e) {
746 croak(e.what());
747 }
748 OUTPUT:
749 RETVAL
750
751 Botan__X509_DN *
subject_dn()752 Botan__X509_Certificate::subject_dn()
753 CODE:
754 try {
755 RETVAL = new Botan__X509_DN(THIS->subject_dn());
756 }
catch(const std::exception & e)757 catch (const std::exception &e) {
758 croak(e.what());
759 }
760 char const * CLASS = "Botan::X509_DN";
761 OUTPUT:
762 RETVAL
763
764 Botan__X509_DN *
issuer_dn()765 Botan__X509_Certificate::issuer_dn()
766 CODE:
767 try {
768 RETVAL = new Botan__X509_DN(THIS->issuer_dn());
769 }
catch(const std::exception & e)770 catch (const std::exception &e) {
771 croak(e.what());
772 }
773 char const * CLASS = "Botan::X509_DN";
774 OUTPUT:
775 RETVAL
776
777
778 # ============================== Botan::X509_DN ==============================
779
780 MODULE = Botan PACKAGE = Botan::X509_DN
781
782 Botan__X509_DN *
new()783 Botan__X509_DN::new()
784 CODE:
785 try {
786 RETVAL = new Botan__X509_DN();
787 }
catch(const std::exception & e)788 catch (const std::exception &e) {
789 croak(e.what());
790 }
791 OUTPUT:
792 RETVAL
793
794 void
DESTROY()795 Botan__X509_DN::DESTROY()
796 CODE:
797 try {
798 delete THIS;
799 }
catch(const std::exception & e)800 catch (const std::exception &e) {
801 croak(e.what());
802 }
803
804 AV *
get_attributes()805 Botan__X509_DN::get_attributes()
806 CODE:
807 try {
808 using namespace std;
809 using namespace Botan;
810
811 typedef multimap<OID, string>::const_iterator rdn_iter;
812
813 multimap<OID, string> const &atrmmap = THIS->get_attributes();
814 RETVAL = newAV();
815 for(rdn_iter i = atrmmap.begin(); i != atrmmap.end(); i++)
816 {
817 string const &atr = i->first.as_string();
818 string const &val = i->second;
819 av_push(RETVAL, newSVpvn(atr.c_str(), atr.length()));
820 av_push(RETVAL, newSVpvn(val.c_str(), val.length()));
821 }
822 }
catch(const std::exception & e)823 catch (const std::exception &e) {
824 croak(e.what());
825 }
826 OUTPUT:
827 RETVAL
828