#ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef __cplusplus } #endif #include #include #include #include #include #include #include #include /* xsubpp converts ':' to '_' in typemap. We create our types without ':' */ typedef Botan::ASN1_String Botan__ASN1_String; typedef Botan::AlgorithmIdentifier Botan__AlgorithmIdentifier; typedef Botan::AlternativeName Botan__AlternativeName; typedef Botan::Attribute Botan__Attribute; typedef Botan::Base64_Decoder Botan__Base64_Decoder; typedef Botan::Base64_Encoder Botan__Base64_Encoder; typedef Botan::Chain Botan__Chain; typedef Botan::Certificate_Extension Botan__Extension; typedef Botan::Filter Botan__Filter; typedef Botan::Fork Botan__Fork; typedef Botan::Hex_Decoder Botan__Hex_Decoder; typedef Botan::Hex_Encoder Botan__Hex_Encoder; typedef Botan::OID Botan__OID; typedef Botan::Pipe Botan__Pipe; typedef Botan::X509_Certificate Botan__X509_Certificate; typedef Botan::X509_DN Botan__X509_DN; typedef Botan::X509_Time Botan__X509_Time; typedef Botan::u32bit Botan__u32bit; /* Types to keep track of destruction C++ objects passed * into other objects... * An Botan object is deleted by his parent object into which is passed, * e.g. some Filter is deleted when his Pipe is destructed. We must * track this and not to delete object again in Perls destructor. */ class ObjectInfo { private: I32 d_signature; bool d_del; public: static I32 const SIGNVAL = 0x696a626f; ObjectInfo() : d_signature(SIGNVAL), d_del(true) {}; ~ObjectInfo() {}; void set_delete(bool del = true) { d_del = del; }; void set_delete_no() { set_delete(false); }; void set_delete_yes() { set_delete(true); }; bool should_delete() const { return d_del; }; }; /* Constant object in initial state - template */ ObjectInfo const oi_init; /* Botan library initializer ... */ Botan::LibraryInitializer botan_init; /*============================================================================*/ MODULE = Botan PACKAGE = Botan PROTOTYPES: ENABLE void constant(char *name) CODE: using namespace Botan; errno = 0; switch (name[0]) { case 'F': if ( strEQ(name, "FULL_CHECK") ) XSRETURN_IV( FULL_CHECK ); // Decoder_Checking enum break; case 'I': if ( strEQ(name, "IGNORE_WS") ) XSRETURN_IV( IGNORE_WS ); // Decoder_Checking enum break; case 'N': if ( strEQ(name, "NONE") ) XSRETURN_IV( NONE ); // Decoder_Checking enum break; } errno = EINVAL; XSRETURN_UNDEF; # =========================== Botan::Chain ========================== MODULE = Botan PACKAGE = Botan::Chain Botan__Chain * Botan__Chain::new(f1 = 0, f2 = 0, f3 = 0, f4 = 0) Botan__Filter *f1; Botan__Filter *f2; Botan__Filter *f3; Botan__Filter *f4; PREINIT: ObjectInfo *f1_oi; ObjectInfo *f2_oi; ObjectInfo *f3_oi; ObjectInfo *f4_oi; CODE: try { RETVAL = new Botan__Chain(f1, f2, f3, f4); if ( f1 ) f1_oi->set_delete_no(); if ( f2 ) f2_oi->set_delete_no(); if ( f3 ) f3_oi->set_delete_no(); if ( f4 ) f4_oi->set_delete_no(); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__Chain::DESTROY() PREINIT: ObjectInfo *THIS_oi; CODE: if ( THIS_oi->should_delete() ) try { delete THIS; } catch (const std::exception &e) { croak(e.what()); } # =========================== Botan::Fork ========================== MODULE = Botan PACKAGE = Botan::Fork Botan__Fork * Botan__Fork::new(f1 = 0, f2 = 0, f3 = 0, f4 = 0) Botan__Filter *f1; Botan__Filter *f2; Botan__Filter *f3; Botan__Filter *f4; PREINIT: ObjectInfo *f1_oi; ObjectInfo *f2_oi; ObjectInfo *f3_oi; ObjectInfo *f4_oi; CODE: try { RETVAL = new Botan__Fork(f1, f2, f3, f4); if ( f1 ) f1_oi->set_delete_no(); if ( f2 ) f2_oi->set_delete_no(); if ( f3 ) f3_oi->set_delete_no(); if ( f4 ) f4_oi->set_delete_no(); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__Fork::DESTROY() PREINIT: ObjectInfo *THIS_oi; CODE: if ( THIS_oi->should_delete() ) try { delete THIS; } catch (const std::exception &e) { croak(e.what()); } # ============================ Botan::Base64_Decoder ============================ MODULE = Botan PACKAGE = Botan::Base64_Decoder Botan__Base64_Decoder * Botan__Base64_Decoder::new(checking = Botan::NONE) int checking; CODE: try { using namespace Botan; RETVAL = new Base64_Decoder((Decoder_Checking)checking); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__Base64_Decoder::DESTROY() PREINIT: ObjectInfo *THIS_oi; CODE: if ( THIS_oi->should_delete() ) try { delete THIS; } catch (const std::exception &e) { croak(e.what()); } # =========================== Botan::Base64_Encoder ========================== MODULE = Botan PACKAGE = Botan::Base64_Encoder Botan__Base64_Encoder * Botan__Base64_Encoder::new(breaks = false, length = 72) bool breaks; Botan__u32bit length; CODE: try { RETVAL = new Botan__Base64_Encoder(breaks, length); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__Base64_Encoder::DESTROY() PREINIT: ObjectInfo *THIS_oi; CODE: if ( THIS_oi->should_delete() ) try { delete THIS; } catch (const std::exception &e) { croak(e.what()); } # ============================ Botan::Hex_Decoder ============================ MODULE = Botan PACKAGE = Botan::Hex_Decoder Botan__Hex_Decoder * Botan__Hex_Decoder::new(checking = Botan::NONE) int checking; CODE: try { using namespace Botan; RETVAL = new Hex_Decoder((Decoder_Checking)checking); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__Hex_Decoder::DESTROY() PREINIT: ObjectInfo *THIS_oi; CODE: if ( THIS_oi->should_delete() ) try { delete THIS; } catch (const std::exception &e) { croak(e.what()); } # ============================ Botan::Hex_Encoder ============================ MODULE = Botan PACKAGE = Botan::Hex_Encoder Botan__Hex_Encoder * Botan__Hex_Encoder::new(breaks = false, length = 72, lcase = false) bool breaks; Botan__u32bit length; bool lcase; CODE: try { using Botan::Hex_Encoder; RETVAL = new Hex_Encoder(breaks, length, lcase ? Hex_Encoder::Lowercase : Hex_Encoder::Uppercase); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__Hex_Encoder::DESTROY() PREINIT: ObjectInfo *THIS_oi; CODE: if ( THIS_oi->should_delete() ) try { delete THIS; } catch (const std::exception &e) { croak(e.what()); } # ================================ Botan::OID ================================ MODULE = Botan PACKAGE = Botan::OID Botan__OID * Botan__OID::new(s) char *s; CODE: try { RETVAL = new Botan__OID(s); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__OID::DESTROY() CODE: try { delete THIS; } catch (const std::exception &e) { croak(e.what()); } char * Botan__OID::as_string() CODE: try { RETVAL = const_cast(THIS->as_string().c_str()); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL # ================================ Botan::OIDS ================================ MODULE = Botan PACKAGE = Botan::OIDS void add_oid(oid, name) Botan__OID *oid; char *name; CODE: try { Botan::OIDS::add_oid(*oid, name); } catch (const std::exception &e) { croak(e.what()); } char * lookup_by_oid(oid) Botan__OID *oid; CODE: try { RETVAL = const_cast(Botan::OIDS::lookup(*oid).c_str()); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL Botan__OID * lookup_by_name(name) char *name; CODE: try { RETVAL = new Botan__OID(Botan::OIDS::lookup(name)); } catch (const std::exception &e) { croak(e.what()); } char const * CLASS = "Botan::OID"; OUTPUT: RETVAL int have_oid(name) char *name; CODE: try { RETVAL = Botan::OIDS::have_oid(name); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL # ================================ Botan::Pipe ================================ MODULE = Botan PACKAGE = Botan::Pipe Botan__Pipe * Botan__Pipe::new(...) CODE: for (I32 i = 1; i < items; i++) { if ( !sv_isobject(ST(i)) || (SvTYPE(SvRV(ST(i))) != SVt_PVMG) ) croak("Botan::Pipe::new() -- arg %u is not " "a blessed SV reference", i +1); if ( !sv_derived_from(ST(i), "Botan::Filter") ) croak("Botan::Pipe::new() -- arg %u is not " "an object derived from Botan::Filter", i +1); MAGIC *mg = mg_find(SvRV(ST(i)), '~'); if ( mg == 0 || mg->mg_len != sizeof(ObjectInfo) || *(I32 *)(mg->mg_ptr) != ObjectInfo::SIGNVAL ) croak("Botan::Pipe::new() -- arg %u has no " "valid private magic data (ObjectInfo)", i +1); } try { RETVAL = new Botan__Pipe(); for (I32 i = 1; i < items; i++) { SV *osv = (SV *)SvRV(ST(i)); ObjectInfo *oi = (ObjectInfo *)(mg_find(osv, '~')->mg_ptr); RETVAL->append((Botan__Filter *)(SvIV(osv))); oi->set_delete_no(); } } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__Pipe::DESTROY() PREINIT: ObjectInfo *THIS_oi; CODE: try { delete THIS; } catch (const std::exception &e) { croak(e.what()); } void Botan__Pipe::write(s) SV *s; PREINIT: ObjectInfo *THIS_oi; CODE: STRLEN len; char *ptr = SvPV(s, len); try { THIS->write((unsigned char *)ptr, len); } catch (const std::exception &e) { croak(e.what()); } void Botan__Pipe::process_msg(s) SV *s; PREINIT: ObjectInfo *THIS_oi; CODE: STRLEN len; char *ptr = SvPV(s, len); try { THIS->process_msg((unsigned char *)ptr, len); } catch (const std::exception &e) { croak(e.what()); } Botan__u32bit Botan__Pipe::remaining(msgno = Botan::Pipe::DEFAULT_MESSAGE) Botan__u32bit msgno; PREINIT: ObjectInfo *THIS_oi; CODE: try { RETVAL = THIS->remaining(msgno); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL SV * Botan__Pipe::read(len = 0xFFFFFFFF, msgno = Botan::Pipe::DEFAULT_MESSAGE) Botan__u32bit len; Botan__u32bit msgno; PREINIT: ObjectInfo *THIS_oi; CODE: try { if ( len > THIS->remaining(msgno) ) len = THIS->remaining(msgno); RETVAL = NEWSV(0, len); SvPOK_on(RETVAL); if ( len > 0 ) SvCUR_set(RETVAL, THIS->read((unsigned char *)SvPVX(RETVAL), len, msgno)); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL SV * Botan__Pipe::peek(len = 0xFFFFFFFF, offset = 0, \ msgno = Botan::Pipe::DEFAULT_MESSAGE) Botan__u32bit len; Botan__u32bit offset; Botan__u32bit msgno; PREINIT: ObjectInfo *THIS_oi; CODE: try { if ( len > THIS->remaining(msgno) ) len = THIS->remaining(msgno); RETVAL = NEWSV(0, len); SvPOK_on(RETVAL); if ( len > 0 ) SvCUR_set(RETVAL, THIS->peek((unsigned char *)SvPVX(RETVAL), len, offset, msgno)); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL Botan__u32bit Botan__Pipe::default_msg() PREINIT: ObjectInfo *THIS_oi; CODE: try { RETVAL = THIS->default_msg(); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__Pipe::set_default_msg(msgno) Botan__u32bit msgno; PREINIT: ObjectInfo *THIS_oi; CODE: try { THIS->set_default_msg(msgno); } catch (const std::exception &e) { croak(e.what()); } Botan__u32bit Botan__Pipe::message_count() PREINIT: ObjectInfo *THIS_oi; CODE: try { RETVAL = THIS->message_count(); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL bool Botan__Pipe::end_of_data() PREINIT: ObjectInfo *THIS_oi; CODE: try { RETVAL = THIS->end_of_data(); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__Pipe::start_msg() PREINIT: ObjectInfo *THIS_oi; CODE: try { THIS->start_msg(); } catch (const std::exception &e) { croak(e.what()); } void Botan__Pipe::end_msg() PREINIT: ObjectInfo *THIS_oi; CODE: try { THIS->end_msg(); } catch (const std::exception &e) { croak(e.what()); } void Botan__Pipe::reset() PREINIT: ObjectInfo *THIS_oi; CODE: try { THIS->reset(); } catch (const std::exception &e) { croak(e.what()); } # ========================== Botan::X509_Certificate ========================== MODULE = Botan PACKAGE = Botan::X509_Certificate Botan__X509_Certificate * Botan__X509_Certificate::new(char *fn) CODE: try { RETVAL = new Botan__X509_Certificate(fn); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__X509_Certificate::DESTROY() CODE: try { delete THIS; } catch (const std::exception &e) { croak(e.what()); } unsigned int Botan__X509_Certificate::x509_version() CODE: try { RETVAL = THIS->x509_version(); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL char * Botan__X509_Certificate::start_time() CODE: try { RETVAL = const_cast(THIS->start_time().c_str()); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL char * Botan__X509_Certificate::end_time() CODE: try { RETVAL = const_cast(THIS->end_time().c_str()); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL char * Botan__X509_Certificate::subject_info(char *info) CODE: try { std::vector s = THIS->subject_info(info); if(s.size() > 0) RETVAL = const_cast(s[0].c_str()); else RETVAL = "err"; } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL char * Botan__X509_Certificate::issuer_info(char *info) CODE: try { std::vector s = THIS->subject_info(info); if(s.size() > 0) RETVAL = const_cast(s[0].c_str()); else RETVAL = "err"; } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL Botan__X509_DN * Botan__X509_Certificate::subject_dn() CODE: try { RETVAL = new Botan__X509_DN(THIS->subject_dn()); } catch (const std::exception &e) { croak(e.what()); } char const * CLASS = "Botan::X509_DN"; OUTPUT: RETVAL Botan__X509_DN * Botan__X509_Certificate::issuer_dn() CODE: try { RETVAL = new Botan__X509_DN(THIS->issuer_dn()); } catch (const std::exception &e) { croak(e.what()); } char const * CLASS = "Botan::X509_DN"; OUTPUT: RETVAL # ============================== Botan::X509_DN ============================== MODULE = Botan PACKAGE = Botan::X509_DN Botan__X509_DN * Botan__X509_DN::new() CODE: try { RETVAL = new Botan__X509_DN(); } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL void Botan__X509_DN::DESTROY() CODE: try { delete THIS; } catch (const std::exception &e) { croak(e.what()); } AV * Botan__X509_DN::get_attributes() CODE: try { using namespace std; using namespace Botan; typedef multimap::const_iterator rdn_iter; multimap const &atrmmap = THIS->get_attributes(); RETVAL = newAV(); for(rdn_iter i = atrmmap.begin(); i != atrmmap.end(); i++) { string const &atr = i->first.as_string(); string const &val = i->second; av_push(RETVAL, newSVpvn(atr.c_str(), atr.length())); av_push(RETVAL, newSVpvn(val.c_str(), val.length())); } } catch (const std::exception &e) { croak(e.what()); } OUTPUT: RETVAL