diff options
Diffstat (limited to 'wrappers/perl-xs/Botan.xs')
-rw-r--r-- | wrappers/perl-xs/Botan.xs | 829 |
1 files changed, 829 insertions, 0 deletions
diff --git a/wrappers/perl-xs/Botan.xs b/wrappers/perl-xs/Botan.xs new file mode 100644 index 000000000..ded129d2e --- /dev/null +++ b/wrappers/perl-xs/Botan.xs @@ -0,0 +1,829 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#ifdef __cplusplus +} +#endif + +#include <botan/asn1_obj.h> +#include <botan/asn1_oid.h> +#include <botan/base64.h> +#include <botan/basefilt.h> +#include <botan/hex.h> +#include <botan/init.h> +#include <botan/oids.h> +#include <botan/x509cert.h> +#include <botan/x509_ext.h> + + +/* 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<char *>(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<char *>(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<char *>(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<char *>(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<std::string> s = THIS->subject_info(info); + + if(s.size() > 0) + RETVAL = const_cast<char *>(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<std::string> s = THIS->subject_info(info); + + if(s.size() > 0) + RETVAL = const_cast<char *>(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<OID, string>::const_iterator rdn_iter; + + multimap<OID, string> 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 |