/*
 * This file was generated automatically by ExtUtils::ParseXS version 3.40 from the
 * contents of OpenSSL.xs. Do not edit this file, edit OpenSSL.xs instead.
 *
 *    ANY CHANGES MADE HERE WILL BE LOST!
 *
 */

#line 1 "OpenSSL.xs"
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/pkcs12.h>
#include <openssl/rand.h>
#include <sys/types.h>
#include <openssl/md2.h>
#include <openssl/md4.h>
#include <openssl/md5.h>
//#include <openssl/mdc2.h>
#include <openssl/ripemd.h>
#include <openssl/rsa.h>
#include <openssl/sha.h> // fingerprint.
#include <openssl/blowfish.h> // single packet blowfish encoding.
#include <openssl/rand.h>  // random generator.

//#define EDEBUG 1
#ifdef EDEBUG
#define XD(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
#else
#define XD(...)
#endif

static const char *ssl_error(void);

typedef X509           *OpenSSL__X509;
typedef X509_CRL       *OpenSSL__CRL;
typedef X509_NAME      *OpenSSL__Name;
typedef PKCS7          *OpenSSL__PKCS7;
typedef PKCS12         *OpenSSL__PKCS12;
typedef RSA            *OpenSSL__RSA;
typedef EVP_MD_CTX     *OpenSSL__Digest;
typedef EVP_CIPHER_CTX *OpenSSL__Cipher;
typedef BIGNUM	       *OpenSSL__BN;

static inline SV* output_ASN1_INTEGER(ASN1_INTEGER *ai, SV *sv)
{
	if(!ai)
          croak("got 0-ptr");
        if(ai->type != V_ASN1_INTEGER)
          croak("not asn1 integer type (%d)", ai->type);
        //return newSViv(ASN1_INTEGER_get(ai));
        sv_setiv(sv, ASN1_INTEGER_get(ai));
        return sv;
}

static inline SV* output_ASN1_UTCTIME(ASN1_UTCTIME *s, SV *sv)
{
	struct tm tm;
        int offs;
        char buf[64];

	if(!s)
          croak("got 0-ptr");
        if(s->type != V_ASN1_UTCTIME)
          croak("not asn1 utctime type (%d)", s->type);
        if(!ASN1_UTCTIME_check(s))
          croak("invalid UTC time.");
        // fuck openssl crap.
        memset(&tm, 0, sizeof tm);
#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
        tm.tm_year=g2(s->data);
        if(tm.tm_year < 50)
            tm.tm_year+=100;
         tm.tm_mon=g2(s->data+2)-1;
         tm.tm_mday=g2(s->data+4);
         tm.tm_hour=g2(s->data+6);
         tm.tm_min=g2(s->data+8);
         tm.tm_sec=g2(s->data+10);
         if(s->data[12] == 'Z')
              offs=0;
             else
               {
                offs=g2(s->data+13)*60+g2(s->data+15);
                if(s->data[12] == '-')
                    offs= -offs;
               }
#undef g2
             if(!strftime(buf, 63, "%a, %d  %b  %Y %H:%M:%S %z", &tm)) {
               croak("can't convert time.");
             }
          sv_setpv(sv, buf);
          return sv;
}

long bio_write_cb(struct bio_st *bm, int m, const char *ptr, int l, long x, long y)
{
	if(m == BIO_CB_WRITE) {
		SV *sv = (SV *) BIO_get_callback_arg(bm);
                sv_catpvn(sv, ptr, l);
        }
        if(m == BIO_CB_PUTS) {
          	SV *sv = (SV *) BIO_get_callback_arg(bm);
                l = strlen(ptr);
                sv_catpvn(sv, ptr, l);
        }
	return l;
}

static inline BIO* sv_bio_create(void)
{
	SV *sv;
        BIO *bio;
        sv = newSVpvn("",0);
        // mem is completely broken for write, so we use /dev/null
        // and use callbacks-hooks
        bio = BIO_new_file("/dev/null", "wb");
        BIO_set_callback(bio, bio_write_cb);
        BIO_set_callback_arg(bio, (void *)sv);
        return bio;
}

static inline BIO *sv_bio_create_file(SV *filename)
{
        STRLEN l;

        return BIO_new_file(SvPV(filename, l), "wb");
}

static inline SV * sv_bio_final(BIO *bio)
{
     SV* sv;
     
     BIO_flush(bio);
     sv = (SV *) BIO_get_callback_arg(bio);
     BIO_free_all (bio);
     // check for file:
     if(!sv)
      	sv = &PL_sv_undef; 
     return sv;
}

static inline void sv_bio_error(BIO *bio)
{
	SV *sv;
        sv = (SV *) BIO_get_callback_arg(bio);
        if(sv)
		sv_free(sv);
        BIO_free_all (bio);
}

static const char *ssl_error(void) // function leaks. :(
{
	BIO *bio;
        SV *sv;
        STRLEN l;

  	bio = sv_bio_create();
        ERR_print_errors(bio);
        sv = sv_bio_final(bio);
        ERR_clear_error();
        return SvPV(sv, l);	
}

static inline SV* output_BN(BIGNUM *n, SV *sv)
{
  if (!n)
    croak("parse error :)");

  sv_setpvn(sv, BN_bn2dec(n), 0);
  return sv;
}

static const char * digcvt(char *ret, const char *from, int len)
{
	static const char *htab = "0123456789abcdef";
        char *to = ret;
        int i;
        for(i = 0; i < len; i++) {
          *to++ = htab[(*from >> 4) & 0xf];
          *to++ = htab[*from++ & 0xf];
        }
        *to = 0;
        return ret;
}

/* mutt, anything else is broken ! */
static const char B64Chars[64] = {
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
    't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', '+', '/'
};

static unsigned char *mutt_to_base64 (unsigned char *out, const unsigned char *in, size_t len,
		     size_t olen)
{
  char *o = out;
  while (len >= 3 && olen > 10)
  {
    *out++ = B64Chars[in[0] >> 2];
    *out++ = B64Chars[((in[0] << 4) & 0x30) | (in[1] >> 4)];
    *out++ = B64Chars[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
    *out++ = B64Chars[in[2] & 0x3f];
    olen  -= 4;
    len   -= 3;
    in    += 3;
  }

  /* clean up remainder */
  if (len > 0 && olen > 4)
  {
    unsigned char fragment;

    *out++ = B64Chars[in[0] >> 2];
    fragment = (in[0] << 4) & 0x30;
    if (len > 1)
      fragment |= in[1] >> 4;
    *out++ = B64Chars[fragment];
    *out++ = (len < 2) ? '=' : B64Chars[(in[1] << 2) & 0x3c];
    *out++ = '=';
  }
  *out = '\0';
  return o;
}

static inline SV* hexsv(unsigned char *s, unsigned len)
{
        char *ret;
        SV *sv;
        ret = malloc((len<<1)+1);
        if(!ret)
          croak("malloc");
	sv = newSVpv(digcvt(ret, s,len), len <<1);
        free(ret);
        return sv;
}

static inline SV* base64sv(unsigned char *s, unsigned len)
{
        char *ret;
        SV *sv;
        int enc_cnt = ((len+ 2) / 3) << 2;
        ret = malloc(enc_cnt+1);
        if(!ret)
          croak("malloc");
	sv = newSVpv(mutt_to_base64(ret, s,len, enc_cnt+1), enc_cnt);
        free(ret);
        return sv;
        
}

#define FLAG_HEX 0x10
#define FLAG_BASE64 0x20
#define NO_FLAGS(x) ((x) &0xf)

static EVP_MD *_mds[8];

static int mds_booted = 0;

static void mds_boot (void)
{
	if(mds_booted)
          	return;
        mds_booted = 1;
	OpenSSL_add_all_digests();
        _mds[0] = EVP_md2();
        _mds[1] = EVP_md4();
        _mds[2] = EVP_md5();
        _mds[3] = EVP_sha();
        _mds[4] = EVP_sha1();
        _mds[5] = EVP_dss();
        _mds[6] = EVP_dss1();
//      _mds[7] = EVP_mdc2();
        _mds[7] = EVP_ripemd160(); 
}



static char *
dofp(X509 *x509, EVP_MD *digest)
{
   	unsigned char md[EVP_MAX_MD_SIZE];
   	unsigned static char s[EVP_MAX_MD_SIZE*3];
        int n, i;

   	if(!X509_digest(x509, digest, md, &n))
          	croak("Digest error: %s", ssl_error());
        for(i = 0; i < n; i++) {
          sprintf(&s[i*3], "%02X%c", md[i], (i + 1 == (int) n) ? '\0' : ':');
        }
	return s;
}

static inline SV *ol(X509_NAME *x)
{
	char *p;
	SV *sv = newSVpvn("",0);
        X509_NAME_oneline(x, (p=SvGROW(sv,8192)), 8192);
        SvCUR_set(sv, strlen(p));
        return sv;
}

#if 0
static void run_sha1(char *digest, const char *msg, int msglen)
{
        SHA_CTX ctx;
        
       if(!digest || !msg || msglen < 0)
         croak("run_sha1: null pointer or illegal message len");
    	SHA1_Init(&ctx);
        SHA1_Update(&ctx, msg, msglen);
        SHA1_Final(digest, &ctx);	
}
#endif
static bool is_privkey(RSA *key)
{
   return (key->n && key->e && key->d && key->p && key->q
	  && key->dmp1 && key->dmq1 && key->iqmp && key->d) ? 1 : 0;
}

typedef struct {
  EVP_CIPHER *func;
  char name[20];
} cip_list_st;

static cip_list_st cip_list[50];
static int cip_cnt = 0;

static inline char *wappla_fixname(const char *s)
{
	static char x[50];
        char *p;
        strcpy(x, s);
        while((p = strchr(x, '_'))) {
          	*p = '-';
        }
	return x;
}

static inline EVP_CIPHER *lookup_cipher(const char *name)
{
	int i;
        for(i = 0; i < cip_cnt;i++)
          if(!strcmp(name, cip_list[i].name))
            	return cip_list[i].func;
        return 0;
}

#define ADD_C_(x) cip_list[cip_cnt].func =  (EVP_##x()); \
		strcpy(cip_list[cip_cnt++].name, wappla_fixname(#x))

static int cipher_booted = 0;

static void cipher_boot(void)
{
	if(cipher_booted)
          	return;
        cipher_booted++;
	OpenSSL_add_all_ciphers();
#ifndef NO_DES
        ADD_C_(des_ecb);	ADD_C_(des_ede);	ADD_C_(des_ede3);
        ADD_C_(des_cfb);	ADD_C_(des_ede_cfb);	ADD_C_(des_ede3_cfb);
        ADD_C_(des_ofb);	ADD_C_(des_ede_ofb);	ADD_C_(des_ede3_ofb);
        ADD_C_(des_cbc);	ADD_C_(des_ede_cbc);	ADD_C_(des_ede3_cbc);
        ADD_C_(desx_cbc);
#endif
#ifndef NO_RC4
        ADD_C_(rc4);		ADD_C_(rc4_40);
#endif
#ifndef NO_IDEA
        ADD_C_(idea_ecb);	ADD_C_(idea_cfb);
        ADD_C_(idea_ofb);	ADD_C_(idea_cbc);
#endif
#ifndef NI_RC2
        ADD_C_(rc2_ecb);	ADD_C_(rc2_cbc);	ADD_C_(rc2_40_cbc);
        ADD_C_(rc2_64_cbc);	ADD_C_(rc2_cfb);	ADD_C_(rc2_ofb);
#endif
#ifndef NO_BF
        ADD_C_(bf_ecb);		ADD_C_(bf_cbc);
        ADD_C_(bf_cfb);		ADD_C_(bf_ofb);
#endif
#ifndef NO_CAST
        ADD_C_(cast5_ecb);	ADD_C_(cast5_cbc);
        ADD_C_(cast5_cfb);	ADD_C_(cast5_ofb);
#endif
#ifndef NO_RC5
	ADD_C_(rc5_32_12_16_cbc);	ADD_C_(rc5_32_12_16_ecb);
	ADD_C_(rc5_32_12_16_cfb);	ADD_C_(rc5_32_12_16_ofb);
#endif
} 


#line 405 "OpenSSL.c"
#ifndef PERL_UNUSED_VAR
#  define PERL_UNUSED_VAR(var) if (0) var = var
#endif

#ifndef dVAR
#  define dVAR		dNOOP
#endif


/* This stuff is not part of the API! You have been warned. */
#ifndef PERL_VERSION_DECIMAL
#  define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
#endif
#ifndef PERL_DECIMAL_VERSION
#  define PERL_DECIMAL_VERSION \
	  PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
#endif
#ifndef PERL_VERSION_GE
#  define PERL_VERSION_GE(r,v,s) \
	  (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
#endif
#ifndef PERL_VERSION_LE
#  define PERL_VERSION_LE(r,v,s) \
	  (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s))
#endif

/* XS_INTERNAL is the explicit static-linkage variant of the default
 * XS macro.
 *
 * XS_EXTERNAL is the same as XS_INTERNAL except it does not include
 * "STATIC", ie. it exports XSUB symbols. You probably don't want that
 * for anything but the BOOT XSUB.
 *
 * See XSUB.h in core!
 */


/* TODO: This might be compatible further back than 5.10.0. */
#if PERL_VERSION_GE(5, 10, 0) && PERL_VERSION_LE(5, 15, 1)
#  undef XS_EXTERNAL
#  undef XS_INTERNAL
#  if defined(__CYGWIN__) && defined(USE_DYNAMIC_LOADING)
#    define XS_EXTERNAL(name) __declspec(dllexport) XSPROTO(name)
#    define XS_INTERNAL(name) STATIC XSPROTO(name)
#  endif
#  if defined(__SYMBIAN32__)
#    define XS_EXTERNAL(name) EXPORT_C XSPROTO(name)
#    define XS_INTERNAL(name) EXPORT_C STATIC XSPROTO(name)
#  endif
#  ifndef XS_EXTERNAL
#    if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
#      define XS_EXTERNAL(name) void name(pTHX_ CV* cv __attribute__unused__)
#      define XS_INTERNAL(name) STATIC void name(pTHX_ CV* cv __attribute__unused__)
#    else
#      ifdef __cplusplus
#        define XS_EXTERNAL(name) extern "C" XSPROTO(name)
#        define XS_INTERNAL(name) static XSPROTO(name)
#      else
#        define XS_EXTERNAL(name) XSPROTO(name)
#        define XS_INTERNAL(name) STATIC XSPROTO(name)
#      endif
#    endif
#  endif
#endif

/* perl >= 5.10.0 && perl <= 5.15.1 */


/* The XS_EXTERNAL macro is used for functions that must not be static
 * like the boot XSUB of a module. If perl didn't have an XS_EXTERNAL
 * macro defined, the best we can do is assume XS is the same.
 * Dito for XS_INTERNAL.
 */
#ifndef XS_EXTERNAL
#  define XS_EXTERNAL(name) XS(name)
#endif
#ifndef XS_INTERNAL
#  define XS_INTERNAL(name) XS(name)
#endif

/* Now, finally, after all this mess, we want an ExtUtils::ParseXS
 * internal macro that we're free to redefine for varying linkage due
 * to the EXPORT_XSUB_SYMBOLS XS keyword. This is internal, use
 * XS_EXTERNAL(name) or XS_INTERNAL(name) in your code if you need to!
 */

#undef XS_EUPXS
#if defined(PERL_EUPXS_ALWAYS_EXPORT)
#  define XS_EUPXS(name) XS_EXTERNAL(name)
#else
   /* default to internal */
#  define XS_EUPXS(name) XS_INTERNAL(name)
#endif

#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
#define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)

/* prototype to pass -Wmissing-prototypes */
STATIC void
S_croak_xs_usage(const CV *const cv, const char *const params);

STATIC void
S_croak_xs_usage(const CV *const cv, const char *const params)
{
    const GV *const gv = CvGV(cv);

    PERL_ARGS_ASSERT_CROAK_XS_USAGE;

    if (gv) {
        const char *const gvname = GvNAME(gv);
        const HV *const stash = GvSTASH(gv);
        const char *const hvname = stash ? HvNAME(stash) : NULL;

        if (hvname)
	    Perl_croak_nocontext("Usage: %s::%s(%s)", hvname, gvname, params);
        else
	    Perl_croak_nocontext("Usage: %s(%s)", gvname, params);
    } else {
        /* Pants. I don't think that it should be possible to get here. */
	Perl_croak_nocontext("Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
    }
}
#undef  PERL_ARGS_ASSERT_CROAK_XS_USAGE

#define croak_xs_usage        S_croak_xs_usage

#endif

/* NOTE: the prototype of newXSproto() is different in versions of perls,
 * so we define a portable version of newXSproto()
 */
#ifdef newXS_flags
#define newXSproto_portable(name, c_impl, file, proto) newXS_flags(name, c_impl, file, proto, 0)
#else
#define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv)
#endif /* !defined(newXS_flags) */

#if PERL_VERSION_LE(5, 21, 5)
#  define newXS_deffile(a,b) Perl_newXS(aTHX_ a,b,file)
#else
#  define newXS_deffile(a,b) Perl_newXS_deffile(aTHX_ a,b)
#endif

#line 549 "OpenSSL.c"

XS_EUPXS(XS_OpenSSL__RSA_new_keygen); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_new_keygen)
{
    dVAR; dXSARGS;
    if (items < 0 || items > 2)
       croak_xs_usage(cv,  "bits = 128, e = 35");
    {
	IV	bits;
	IV	e;
	OpenSSL__RSA	RETVAL;

	if (items < 1)
	    bits = 128;
	else {
	    bits = (IV)SvIV(ST(0))
;
	}

	if (items < 2)
	    e = 35;
	else {
	    e = (IV)SvIV(ST(1))
;
	}
#line 402 "OpenSSL.xs"
	if(!(RETVAL = RSA_generate_key(bits, e, NULL, NULL)))
  		croak("RSA_generate_key");
#line 578 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::RSA", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__RSA_new_pubkey); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_new_pubkey)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "n, e");
    {
	char *	n = (char *)SvPV_nolen(ST(0))
;
	char *	e = (char *)SvPV_nolen(ST(1))
;
	OpenSSL__RSA	RETVAL;
#line 412 "OpenSSL.xs"
        RETVAL = RSA_new();
  	if (!RETVAL)
  		croak("can't allocate key");
        if(!(RETVAL->n = BN_new()) || !BN_dec2bn(&RETVAL->n, n)) {
  		RSA_free(RETVAL); croak("can't initialize n");
        }
	if(!(RETVAL->e = BN_new()) || !BN_dec2bn(&RETVAL->e, e)) {
  		RSA_free(RETVAL); croak("can't initialize e");
        }
        //key->p = 0, key->q = 0, key->dmp1 = 0, key->dmq1 = 0, key->iqmp = 0;
#line 613 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::RSA", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__RSA_new_privkey); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_new_privkey)
{
    dVAR; dXSARGS;
    if (items != 8)
       croak_xs_usage(cv,  "n, e, p, q, dmp1, dmq1, iqmp, d");
    {
	char *	n = (char *)SvPV_nolen(ST(0))
;
	char *	e = (char *)SvPV_nolen(ST(1))
;
	char *	p = (char *)SvPV_nolen(ST(2))
;
	char *	q = (char *)SvPV_nolen(ST(3))
;
	char *	dmp1 = (char *)SvPV_nolen(ST(4))
;
	char *	dmq1 = (char *)SvPV_nolen(ST(5))
;
	char *	iqmp = (char *)SvPV_nolen(ST(6))
;
	char *	d = (char *)SvPV_nolen(ST(7))
;
	OpenSSL__RSA	RETVAL;
#line 437 "OpenSSL.xs"
        int rc;

        RETVAL = RSA_new();
  	if (!RETVAL)
  		croak("can't allocate key");
        if(!(RETVAL->n = BN_new()) || !BN_dec2bn(&RETVAL->n, n)) {
  		RSA_free(RETVAL); croak("can't initialize n");
        }
	if(!(RETVAL->e = BN_new()) || !BN_dec2bn(&RETVAL->e, e)) {
  		RSA_free(RETVAL); croak("can't initialize e");
        }
	if(!(RETVAL->p = BN_new()) || !BN_dec2bn(&RETVAL->p, p)) {
  		RSA_free(RETVAL); croak("can't initialize p");
        }
	if(!(RETVAL->q = BN_new()) || !BN_dec2bn(&RETVAL->q, q)) {
  		RSA_free(RETVAL); croak("can't initialize q");
        }
	if(!(RETVAL->dmp1 = BN_new()) || !BN_dec2bn(&RETVAL->dmp1, dmp1)) {
  		RSA_free(RETVAL); croak("can't initialize dmp1");
        }
	if(!(RETVAL->dmq1 = BN_new()) || !BN_dec2bn(&RETVAL->dmq1, dmq1)) {
  		RSA_free(RETVAL); croak("can't initialize dmq1");
        }
	if(!(RETVAL->iqmp = BN_new()) || !BN_dec2bn(&RETVAL->iqmp, iqmp)) {
  		RSA_free(RETVAL); croak("can't initialize iqmp");
        }
	if(!(RETVAL->d = BN_new()) || !BN_dec2bn(&RETVAL->d, d)) {
  		RSA_free(RETVAL); croak("can't initialize d");
        }
	if((rc = RSA_check_key(RETVAL)) != 1) {
  		RSA_free(RETVAL); croak("RSA_check_key failed (%d).", rc);
        }
#line 682 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::RSA", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__RSA_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "key");
    {
	OpenSSL__RSA	key;

	if (SvROK(ST(0))) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    key = INT2PTR(OpenSSL__RSA,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not a reference",
			"OpenSSL::RSA::DESTROY",
			"key")
;
#line 477 "OpenSSL.xs"
  if (key) {
    	  XD("RSA_free(%p)\n", key);
	  RSA_free(key);
  }
#line 717 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__RSA_keysize); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_keysize)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "key");
    {
	OpenSSL__RSA	key;
	IV	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::RSA")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    key = INT2PTR(OpenSSL__RSA,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::RSA::keysize",
			"key", "OpenSSL::RSA")
;
#line 486 "OpenSSL.xs"
  	if (!key || !key->n)
  		croak("invalid key");
	RETVAL = BN_num_bits(key->n);
#line 747 "OpenSSL.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__RSA_check_key); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_check_key)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "key");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	OpenSSL__RSA	key;
	bool	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::RSA")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    key = INT2PTR(OpenSSL__RSA,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::RSA::check_key",
			"key", "OpenSSL::RSA")
;
#line 496 "OpenSSL.xs"
        if(!key)
  		XSRETURN_NO;
        if(RSA_check_key(key) == 1)
  		XSRETURN_YES;
        XSRETURN_NO;
#line 781 "OpenSSL.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_OpenSSL__RSA_n); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_n)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 1)
       croak_xs_usage(cv,  "key");
    {
	OpenSSL__RSA	key;
	OpenSSL__BN	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::RSA")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    key = INT2PTR(OpenSSL__RSA,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"key", "OpenSSL::RSA")
;
#line 515 "OpenSSL.xs"
   RETVAL = 0;
   	if(!key)
  		croak("invalid key");
  switch(ix) {
    case 0: RETVAL = key->n; break;
    case 1: RETVAL = key->e; break;
    case 2: RETVAL = key->d; break;
    case 3: RETVAL = key->p; break;
    case 4: RETVAL = key->q; break;
    case 5: RETVAL = key->dmp1; break;
    case 6: RETVAL = key->dmq1; break;
    case 7: RETVAL = key->iqmp; break;
    default:
      croak("huch");
  }
        if(!RETVAL)
  		croak("bignum not defined (maybe pubkey ?)");
#line 826 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::BN", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__RSA_is_privkey); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_is_privkey)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "key");
    {
	OpenSSL__RSA	key;
	bool	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::RSA")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    key = INT2PTR(OpenSSL__RSA,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::RSA::is_privkey",
			"key", "OpenSSL::RSA")
;
#line 540 "OpenSSL.xs"
   	RETVAL = is_privkey(key); 
#line 859 "OpenSSL.c"
	ST(0) = boolSV(RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__RSA_STORABLE_thaw); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_STORABLE_thaw)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "osv, cloning, sv");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	SV *	osv = ST(0)
;
	bool	cloning = (bool)SvTRUE(ST(1))
;
	SV *	sv = ST(2)
;
#line 550 "OpenSSL.xs"
  STRLEN len;
  char *p;
  unsigned int *i;
  RSA *key = NULL;
#line 886 "OpenSSL.c"
#line 555 "OpenSSL.xs"
  	if(cloning)
  		return;
        i = (unsigned int *) SvPV(sv, len);
        if(i[2] == 0xffffffff) {
          // public key
	  key = RSA_new();
          p = (char *) &i[3];
          key->n =  BN_bin2bn(p, i[0], NULL);
          key->e =  BN_bin2bn(&p[i[0]], i[1], NULL);
        } else if (i[8] == 0xffffffff) {
          // private key
       	  key = RSA_new();
          p = (char *) &i[9];
	  key->n = BN_bin2bn(p, i[0], NULL);
          p += i[0];
          key->e = BN_bin2bn(p, i[1], NULL);
          p += i[1];
          key->d = BN_bin2bn(p, i[2], NULL);
          p += i[2];
          key->p = BN_bin2bn(p, i[3], NULL);
          p += i[3];
          key->q = BN_bin2bn(p, i[4], NULL);
          p += i[4];
          key->dmp1 = BN_bin2bn(p, i[5], NULL);
          p += i[5];
          key->dmq1 = BN_bin2bn(p, i[6], NULL);
          p += i[6];
          key->iqmp = BN_bin2bn(p, i[7], NULL);
        }
	if(!key)
          croak("Illegal Storable format.");
          sv_setiv(SvRV(osv), (IV) key);
          //sv_setref_pv(SvRV(osv), "OpenSSL::RSA", newRV_noinc((void *) key);
          //sv_setiv(osv, (IV) key);
#line 922 "OpenSSL.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_OpenSSL__RSA_STORABLE_freeze); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_STORABLE_freeze)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "key, cloning");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	OpenSSL__RSA	key;
	bool	cloning = (bool)SvTRUE(ST(1))
;
#line 597 "OpenSSL.xs"
        STRLEN totlen;
#line 943 "OpenSSL.c"

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::RSA")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    key = INT2PTR(OpenSSL__RSA,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::RSA::STORABLE_freeze",
			"key", "OpenSSL::RSA")
;
#line 599 "OpenSSL.xs"
	if(cloning)
  		return;
        totlen = BN_num_bytes(key->n) + BN_num_bytes(key->e) + 3*sizeof(int);
        if(!is_privkey(key)) {
		int *y = malloc(totlen);
                int *x = y;
                char *p;
		*x++ = BN_num_bytes(key->n);
                *x++ = BN_num_bytes(key->e);
                *x++ = 0xffffffff;
                p = (char *) x;
                p += BN_bn2bin(key->n, p);
                p += BN_bn2bin(key->e, p);
                XPUSHs(sv_2mortal(newSVpvn((char *)y, p - (char *) y)));
                free(y);
        } else {
		int *y, *x;
                char *p;
                totlen += BN_num_bytes(key->d)
                  + BN_num_bytes(key->p)
                  + BN_num_bytes(key->q)
                  + BN_num_bytes(key->dmp1)
                  + BN_num_bytes(key->dmq1)
                  + BN_num_bytes(key->iqmp) + 6*sizeof(int);
		y = malloc(totlen);
                x = y;
		*x++ = BN_num_bytes(key->n);
                *x++ = BN_num_bytes(key->e);
		*x++ = BN_num_bytes(key->d);
                *x++ = BN_num_bytes(key->p);
		*x++ = BN_num_bytes(key->q);
                *x++ = BN_num_bytes(key->dmp1);
                *x++ = BN_num_bytes(key->dmq1);
                *x++ = BN_num_bytes(key->iqmp);
                *x++ = 0xffffffff;
                p = (char *) x;
                p += BN_bn2bin(key->n, p);
                p += BN_bn2bin(key->e, p);
                p += BN_bn2bin(key->d, p);
                p += BN_bn2bin(key->p, p);
                p += BN_bn2bin(key->q, p);
                p += BN_bn2bin(key->dmp1, p);
                p += BN_bn2bin(key->dmq1, p);
                p += BN_bn2bin(key->iqmp, p);
                XPUSHs(sv_2mortal(newSVpvn((char *)y, p - (char *) y)));
                free(y);
        }
#line 1002 "OpenSSL.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_OpenSSL__RSA_public_encrypt); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_public_encrypt)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 2)
       croak_xs_usage(cv,  "key, sv");
    {
	OpenSSL__RSA	key;
	SV *	sv = ST(1)
;
#line 661 "OpenSSL.xs"
   static int (*func[4])(int, unsigned char *, unsigned char *, RSA *, int) = { RSA_public_encrypt, RSA_public_decrypt, RSA_private_encrypt, RSA_private_decrypt };
   STRLEN len;
   int keylen;
   char *p;
   char *out;
   STRLEN rc;
#line 1027 "OpenSSL.c"
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::RSA")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    key = INT2PTR(OpenSSL__RSA,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"key", "OpenSSL::RSA")
;
#line 668 "OpenSSL.xs"
   	if(!SvPOK(sv))
  		croak ("need a string.");
   	p = SvPV(sv, len);
        keylen = BN_num_bits(key->n);
        if(!p || len < 1 || (len*8 > (keylen+7)&~0x7))
  		croak("illegal value");
        RETVAL = NEWSV(0, len + keylen);
        SvPOK_only(RETVAL);
        SvCUR_set(RETVAL, len + keylen);
        out = SvPV_nolen(RETVAL);
        if((ix&0x3) > 1 && !is_privkey(key))
                croak("need a private key.");
        rc = func[ix&0x3](len, p, out, key, RSA_PKCS1_PADDING);
        if(rc < 0) {
          	sv_free(RETVAL);
                RETVAL = &PL_sv_undef;
  		croak("crypto error... rc=%d inlen=%d", rc, len);
        }
        SvCUR_set(RETVAL, rc);
#line 1059 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__RSA_fingerprint); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__RSA_fingerprint)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "key");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	OpenSSL__RSA	key;
#line 695 "OpenSSL.xs"
         char *x;
         char dig[SHA_DIGEST_LENGTH];
         int nlen, elen;
#line 1081 "OpenSSL.c"

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::RSA")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    key = INT2PTR(OpenSSL__RSA,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::RSA::fingerprint",
			"key", "OpenSSL::RSA")
;
#line 699 "OpenSSL.xs"
        nlen = BN_num_bytes(key->n);
        elen = BN_num_bytes(key->e);
        x = malloc(nlen + elen);
        if(!x)
  		croak("malloc error");
        BN_bn2bin(key->n, x);
        BN_bn2bin(key->e, &x[nlen]);
        //un_sha1(dig, x, nlen+elen);	
        free(x);
        XPUSHs(sv_2mortal(newSVpvn(dig, SHA_DIGEST_LENGTH)));
#line 1103 "OpenSSL.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_OpenSSL__Name_new); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Name_new)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "class");
    {
	SV *	class = ST(0)
;
	OpenSSL__Name	RETVAL;
#line 718 "OpenSSL.xs"
  	if(!(RETVAL = X509_NAME_new())) {
                croak("X509_NAME_new");
        }
#line 1124 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::Name", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__Name_add); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Name_add)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "name, key, string");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	OpenSSL__Name	name;
	SV *	key = ST(1)
;
	SV *	string = ST(2)
;
#line 731 "OpenSSL.xs"
        STRLEN l, kl;
        char *p, *k;
        int ok;
#line 1154 "OpenSSL.c"

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::Name")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    name = INT2PTR(OpenSSL__Name,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::Name::add",
			"name", "OpenSSL::Name")
;
#line 735 "OpenSSL.xs"
        p = SvPV(string, l);
        if(SvIOK(key)) {
          ok = X509_NAME_add_entry_by_NID(name, SvIV(key), MBSTRING_ASC, p, -1, -1, 0);
        } else {
          k = SvPV(key, kl);
          ok = X509_NAME_add_entry_by_txt(name, k, MBSTRING_ASC, p, -1, -1, 0);
        }
	if(!ok)
          croak("X509_NAME_add_entry_by_*: %s", ssl_error());
#line 1175 "OpenSSL.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_OpenSSL__Name_count); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Name_count)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "name");
    {
	OpenSSL__Name	name;
	IV	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::Name")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    name = INT2PTR(OpenSSL__Name,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::Name::count",
			"name", "OpenSSL::Name")
;
#line 749 "OpenSSL.xs"
    	RETVAL = X509_NAME_entry_count(name);
#line 1204 "OpenSSL.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__Name_getall); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Name_getall)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "name");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	OpenSSL__Name	name;
#line 757 "OpenSSL.xs"
   	int cnt, i;
        X509_NAME_ENTRY *e;
        int nid;
        ASN1_STRING *s;
#line 1226 "OpenSSL.c"

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::Name")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    name = INT2PTR(OpenSSL__Name,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::Name::getall",
			"name", "OpenSSL::Name")
;
#line 762 "OpenSSL.xs"
    	cnt = X509_NAME_entry_count(name);
   	EXTEND(SP, cnt<<1);
        for(i = 0; i < cnt; i++) {
          e = X509_NAME_get_entry(name, i);
	  if(!e)
            	croak("X509_NAME_get_entry");
          nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
          s = X509_NAME_ENTRY_get_data(e);
          PUSHs(sv_2mortal(newSVpv(OBJ_nid2ln(nid),0)));
          PUSHs(sv_2mortal(newSVpvn(s->data, s->length)));
        }
#line 1249 "OpenSSL.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_OpenSSL__Name_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Name_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "name");
    {
	OpenSSL__Name	name;

	if (SvROK(ST(0))) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    name = INT2PTR(OpenSSL__Name,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not a reference",
			"OpenSSL::Name::DESTROY",
			"name")
;
#line 778 "OpenSSL.xs"
  	if(name) {
          	XD("X509_NAME_free(%p)\n", name);
  		X509_NAME_free(name);
        }
#line 1279 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__Rand_randbytes); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Rand_randbytes)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 1)
       croak_xs_usage(cv,  "nr");
    {
	IV	nr = (IV)SvIV(ST(0))
;
#line 817 "OpenSSL.xs"
  	char *p;
        int rc;
#line 1298 "OpenSSL.c"
	SV *	RETVAL;
#line 820 "OpenSSL.xs"
  	p = malloc(nr+1);
        if(!p)
  	   croak("malloc failed");
        rc = RAND_bytes(p, nr);
        if(rc != 1) {
           free(p);
  	   croak("RAND_bytes returned %d", rc);
        }
	switch(ix) {
          case 0:
        	RETVAL = newSVpvn(p, nr);
                break;
          case 1:
                RETVAL = hexsv(p, nr);
                break;
          default:
                RETVAL = base64sv(p, nr);
                break;
        }
        free(p);
#line 1321 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_new); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_new)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "class");
    {
	SV *	class = ST(0)
;
	OpenSSL__X509	RETVAL;
#line 873 "OpenSSL.xs"
  	if ((RETVAL = X509_new ()) == NULL)
  		croak("X509_new");

        if (!X509_set_version (RETVAL, 2))
          {
   	    X509_free (RETVAL);
            croak ("X509_set_version");
          }

	ASN1_INTEGER_set (X509_get_serialNumber (RETVAL), 0L);
#line 1350 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::X509", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_new_from_string); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_new_from_string)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 2)
       croak_xs_usage(cv,  "class, thing");
    {
	SV *	class = ST(0)
;
	SV *	thing = ST(1)
;
#line 894 "OpenSSL.xs"
  	BIO *bio;
        STRLEN l;
        char *p;
#line 1378 "OpenSSL.c"
	OpenSSL__X509	RETVAL;
#line 898 "OpenSSL.xs"
	p = SvPV (thing, l);
        if(ix == 1) {
          	bio = BIO_new_file(p, "r");
        } else {
        	bio = BIO_new_mem_buf (p, l);
        }
	if(!bio) 
  		croak(ssl_error());

        RETVAL = PEM_read_bio_X509 (bio, 0, 0, 0);
        BIO_free (bio);
        if(!RETVAL)
  		croak("PEM_read_bio_X509: %s", ssl_error());

#line 1395 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::X509", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;

	if (SvROK(ST(0))) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not a reference",
			"OpenSSL::X509::DESTROY",
			"x509")
;
#line 919 "OpenSSL.xs"
  	if (x509) {
          	XD("X509_free(%p)\n", x509);
	  	X509_free (x509);
                x509 = 0;
        }
#line 1431 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__X509_fingerprint_md5); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_fingerprint_md5)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
#line 933 "OpenSSL.xs"
   	EVP_MD *mds[] = { EVP_md5(), EVP_md2(), EVP_sha1() };
#line 1448 "OpenSSL.c"
	char *	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"x509", "OpenSSL::X509")
;
#line 935 "OpenSSL.xs"
   	RETVAL = dofp(x509, mds[ix]);
#line 1463 "OpenSSL.c"
	sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_subject); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_subject)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
	OpenSSL__Name	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::subject",
			"x509", "OpenSSL::X509")
;
#line 944 "OpenSSL.xs"
  	RETVAL = X509_NAME_dup (X509_get_subject_name(x509));
#line 1491 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::Name", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_issuer); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_issuer)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
	OpenSSL__Name	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::issuer",
			"x509", "OpenSSL::X509")
;
#line 952 "OpenSSL.xs"
  	RETVAL = X509_NAME_dup (X509_get_issuer_name(x509));
#line 1524 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::Name", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_subject_txt); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_subject_txt)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::subject_txt",
			"x509", "OpenSSL::X509")
;
#line 961 "OpenSSL.xs"
        RETVAL = ol(X509_get_subject_name(x509));
#line 1557 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_issuer_txt); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_issuer_txt)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::issuer_txt",
			"x509", "OpenSSL::X509")
;
#line 970 "OpenSSL.xs"
        RETVAL = ol(X509_get_issuer_name(x509));
#line 1586 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_serial); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_serial)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
	ASN1_INTEGER *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::serial",
			"x509", "OpenSSL::X509")
;
#line 978 "OpenSSL.xs"
    	RETVAL = X509_get_serialNumber(x509);
#line 1615 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    output_ASN1_INTEGER(RETVAL, RETVALSV);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_version); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_version)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
	int	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::version",
			"x509", "OpenSSL::X509")
;
#line 987 "OpenSSL.xs"
    	RETVAL = X509_get_version(x509);
#line 1649 "OpenSSL.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_notBefore); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_notBefore)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
	ASN1_UTCTIME *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::notBefore",
			"x509", "OpenSSL::X509")
;
#line 995 "OpenSSL.xs"
    	RETVAL = X509_get_notBefore(x509);
#line 1677 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    output_ASN1_UTCTIME(RETVAL, RETVALSV);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_notAfter); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_notAfter)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
	ASN1_UTCTIME *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::notAfter",
			"x509", "OpenSSL::X509")
;
#line 1003 "OpenSSL.xs"
    	RETVAL = X509_get_notAfter(x509);
#line 1710 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    output_ASN1_UTCTIME(RETVAL, RETVALSV);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_cert_type); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_cert_type)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
	int	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::cert_type",
			"x509", "OpenSSL::X509")
;
#line 1011 "OpenSSL.xs"
    	RETVAL = X509_certificate_type(x509, 0);
#line 1744 "OpenSSL.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_as_string); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_as_string)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items < 1)
       croak_xs_usage(cv,  "x509, ...");
    {
	OpenSSL__X509	x509;
#line 1022 "OpenSSL.xs"
    	BIO *bio;
#line 1762 "OpenSSL.c"
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"x509", "OpenSSL::X509")
;
#line 1024 "OpenSSL.xs"
        if((ix != 1 && items > 1) || (ix == 1 && items != 2))
              croak("OpenSSL::X509::%s: illegal/missing args", (ix == 1) ? "as_file" : " as_string");
        if(items > 1) { 
              bio = sv_bio_create_file(ST(1));
        } else {
             bio = sv_bio_create();
        }
        if(!bio)
                  croak("sv_bio_create");
        if(!PEM_write_bio_X509(bio, x509)) {
          	sv_bio_error(bio);
          	croak("PEM_write_bio_X509: %s", ssl_error());
        }
        RETVAL = sv_bio_final(bio);
#line 1789 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_info); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_info)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
#line 1045 "OpenSSL.xs"
   	BIO *bio;
#line 1807 "OpenSSL.c"
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::info",
			"x509", "OpenSSL::X509")
;
#line 1047 "OpenSSL.xs"
   	bio = sv_bio_create();
        if(!X509_print(bio,x509)) {
          	sv_bio_error(bio);
          	croak("X509_print: %s", ssl_error());
        }
	RETVAL = sv_bio_final(bio);
#line 1826 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__X509_set_issuer); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_set_issuer)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "x509, name");
    {
	OpenSSL__X509	x509;
	OpenSSL__Name	name;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::set_issuer",
			"x509", "OpenSSL::X509")
;

	if (SvROK(ST(1)) && sv_derived_from(ST(1), "OpenSSL::Name")) {
	    IV tmp = SvIV((SV*)SvRV(ST(1)));
	    name = INT2PTR(OpenSSL__Name,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::set_issuer",
			"name", "OpenSSL::Name")
;
#line 1061 "OpenSSL.xs"
  	X509_set_issuer_name(x509, X509_NAME_dup(name));
#line 1865 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__X509_set_subject); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_set_subject)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "x509, name");
    {
	OpenSSL__X509	x509;
	OpenSSL__Name	name;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::set_subject",
			"x509", "OpenSSL::X509")
;

	if (SvROK(ST(1)) && sv_derived_from(ST(1), "OpenSSL::Name")) {
	    IV tmp = SvIV((SV*)SvRV(ST(1)));
	    name = INT2PTR(OpenSSL__Name,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::set_subject",
			"name", "OpenSSL::Name")
;
#line 1068 "OpenSSL.xs"
  	X509_set_subject_name(x509, X509_NAME_dup(name));
#line 1902 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__X509_errstring); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__X509_errstring)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "x509");
    {
	OpenSSL__X509	x509;
#line 1074 "OpenSSL.xs"
  	BIO *bio;
#line 1918 "OpenSSL.c"
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::X509")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    x509 = INT2PTR(OpenSSL__X509,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::X509::errstring",
			"x509", "OpenSSL::X509")
;
#line 1076 "OpenSSL.xs"
  	bio = sv_bio_create();
        ERR_print_errors(bio);
        RETVAL = sv_bio_final(bio);
        ERR_clear_error();
#line 1935 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__Cipher_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Cipher_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "ctx");
    {
	OpenSSL__Cipher	ctx;

	if (SvROK(ST(0))) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    ctx = INT2PTR(OpenSSL__Cipher,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not a reference",
			"OpenSSL::Cipher::DESTROY",
			"ctx")
;
#line 1097 "OpenSSL.xs"
  	if(ctx) {
		EVP_CIPHER_CTX_cleanup(ctx);
  		free(ctx);
        }
#line 1966 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__Cipher_new_decrypt); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Cipher_new_decrypt)
{
    dVAR; dXSARGS;
    dXSI32;
    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    {
#line 1107 "OpenSSL.xs"
  	char *name;
        SV *svkey;
  	EVP_CIPHER *ci;
	char *key;
        char iv[EVP_MAX_IV_LENGTH];
        char k[EVP_MAX_KEY_LENGTH];
        int rc;
        STRLEN keylen;
#line 1989 "OpenSSL.c"
	OpenSSL__Cipher	RETVAL;
#line 1116 "OpenSSL.xs"
  	if(items < 2 || items > 3) {
          	croak("usage: new_[en|de]crypt(ciphname,key)");
        }
	name = SvPV_nolen(ST(items -2));
	svkey = ST(items - 1);
        memset(iv, 0, EVP_MAX_IV_LENGTH);
        memset(k, 0, EVP_MAX_KEY_LENGTH);

  	if(!(ci = lookup_cipher(name)))
  		croak("OpenSSL::Cipher::new: no such cipher \"%s\"", name);
        RETVAL = (EVP_CIPHER_CTX *) malloc(sizeof(EVP_CIPHER_CTX));
        if(!RETVAL)
  		croak("malloc error");
        key = SvPV(svkey, keylen);
	memcpy(k, key, (keylen <= ci->key_len) ? keylen : ci->key_len);
        rc = EVP_CipherInit(RETVAL, ci, k, iv, ix);
        memset(iv, 0, EVP_MAX_IV_LENGTH);
        //@@@ memset(k, 0, EVP_MAX_KEY_LENGTH);
        if(!rc) {
          free(RETVAL);
          croak("EVP_CipherInit");
        }
#line 2014 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::Cipher", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__Cipher_update); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Cipher_update)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "ctx, svin");
    {
	OpenSSL__Cipher	ctx;
	SV *	svin = ST(1)
;
#line 1147 "OpenSSL.xs"
  	unsigned char *in, *out;
        STRLEN il, ol;
#line 2039 "OpenSSL.c"
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::Cipher")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    ctx = INT2PTR(OpenSSL__Cipher,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::Cipher::update",
			"ctx", "OpenSSL::Cipher")
;
#line 1150 "OpenSSL.xs"
     	in = SvPV(svin, il);
        ol = (il + 63) & ~63;
        RETVAL = NEWSV(0, ol);
        SvPOK_only(RETVAL);
        SvCUR_set(RETVAL, ol);
        out = SvPV_nolen(RETVAL);
        if(!EVP_CipherUpdate(ctx, out, &ol, in, il)) {
          	sv_free(RETVAL);
  		croak("EVP_CipherUpdate");
        }
	SvCUR_set(RETVAL, ol);
#line 2063 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__Cipher_final); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Cipher_final)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "ctx");
    {
	OpenSSL__Cipher	ctx;
#line 1168 "OpenSSL.xs"
    	STRLEN ol;
        unsigned char *out;
#line 2082 "OpenSSL.c"
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::Cipher")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    ctx = INT2PTR(OpenSSL__Cipher,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::Cipher::final",
			"ctx", "OpenSSL::Cipher")
;
#line 1171 "OpenSSL.xs"
     	ol = 256;
	RETVAL = NEWSV(0, ol);
        SvPOK_only(RETVAL);
        SvCUR_set(RETVAL, ol);
        out = SvPV_nolen(RETVAL);
        if(!out)
  		croak("memory");
        if(!EVP_CipherFinal(ctx, out, &ol)) {
          sv_free(RETVAL);
          croak("EVP_CipherFinal %s", ssl_error());
        }
	SvCUR_set(RETVAL, ol);
#line 2107 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__Cipher_enum_ciphers); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Cipher_enum_ciphers)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
#line 1189 "OpenSSL.xs"
  	int i;
#line 2126 "OpenSSL.c"
#line 1191 "OpenSSL.xs"
   	EXTEND(SP, cip_cnt<<1);
        for(i = 0; i < cip_cnt; i++) {
          PUSHs(sv_2mortal(newSVpv(cip_list[i].name, 0)));
          PUSHs(sv_2mortal(newSViv(cip_list[i].func->key_len)));
        }
#line 2133 "OpenSSL.c"
	PUTBACK;
	return;
    }
}


XS_EUPXS(XS_OpenSSL__Digest_md2); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Digest_md2)
{
    dVAR; dXSARGS;
    dXSI32;
    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
    {
	SV *	RETVAL;
#line 1239 "OpenSSL.xs"
  	EVP_MD_CTX ctx;
	STRLEN l;
        char *p;
        unsigned char md[EVP_MAX_MD_SIZE];
        unsigned int md_len;
        int i;

     	EVP_DigestInit(&ctx, _mds[NO_FLAGS(ix)]);

        for (i = 0; i < items; i++)
          {
            p = SvPV(ST(i), l);
            EVP_DigestUpdate(&ctx, p, l);
          }

        EVP_DigestFinal(&ctx, md, &md_len);
        switch(ix & ~15) {
          case 0:
            	RETVAL = newSVpvn(md, md_len);
	  	break;
          case FLAG_HEX:
                RETVAL = hexsv(md, md_len);
                break;
          default:
                RETVAL = base64sv(md, md_len);
		break;
        }
#line 2177 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__Digest_new_md2); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Digest_new_md2)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
	OpenSSL__Digest	RETVAL;
#line 1282 "OpenSSL.xs"
   	RETVAL = (EVP_MD_CTX *) malloc(sizeof(EVP_MD_CTX));
	if(!RETVAL)
  		croak("out of memory.");
     	EVP_DigestInit(RETVAL, _mds[NO_FLAGS(ix)]);
#line 2199 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::Digest", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__Digest_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Digest_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "ctx");
    {
	OpenSSL__Digest	ctx;

	if (SvROK(ST(0))) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    ctx = INT2PTR(OpenSSL__Digest,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not a reference",
			"OpenSSL::Digest::DESTROY",
			"ctx")
;
#line 1293 "OpenSSL.xs"
  	if(ctx)
  		free(ctx);
#line 2232 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__Digest_update); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Digest_update)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "ctx, ...");
    {
	OpenSSL__Digest	ctx;
#line 1300 "OpenSSL.xs"
    	STRLEN l;
        char *p;
        int i;
#line 2250 "OpenSSL.c"

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::Digest")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    ctx = INT2PTR(OpenSSL__Digest,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::Digest::update",
			"ctx", "OpenSSL::Digest")
;
#line 1304 "OpenSSL.xs"
        for (i = 1; i < items; i++)
          {
            p = SvPV(ST(i), l);
            EVP_DigestUpdate(ctx, p, l);
          }
#line 2267 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__Digest_final); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__Digest_final)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 1)
       croak_xs_usage(cv,  "ctx");
    {
	OpenSSL__Digest	ctx;
#line 1317 "OpenSSL.xs"
        unsigned char md[EVP_MAX_MD_SIZE];
        unsigned int md_len;
#line 2285 "OpenSSL.c"
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::Digest")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    ctx = INT2PTR(OpenSSL__Digest,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"ctx", "OpenSSL::Digest")
;
#line 1320 "OpenSSL.xs"
      	EVP_DigestFinal(ctx, md, &md_len);
        switch(ix) {
          case 0:
            	RETVAL = newSVpvn(md, md_len);
            	break;
          case 1:
                RETVAL = hexsv(md, md_len);
                break;
          default:
                RETVAL = base64sv(md, md_len);
		break;
        }
#line 2310 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__HMAC_md2); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__HMAC_md2)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 2)
       croak_xs_usage(cv,  "svkey, sv");
    {
	SV *	svkey = ST(0)
;
	SV *	sv = ST(1)
;
#line 1376 "OpenSSL.xs"
	STRLEN l, keylen;
        char *p;
        char *key;
        unsigned char md[EVP_MAX_MD_SIZE];
        unsigned int md_len;
#line 2336 "OpenSSL.c"
	SV *	RETVAL;
#line 1382 "OpenSSL.xs"
        p = SvPV(sv, l);
        key = SvPV(svkey, keylen);
     	if(!HMAC(_mds[NO_FLAGS(ix)], key, keylen, p, l, md, &md_len))
  		croak("HMAC");
        switch(ix & ~15) {
          case 0:
            	RETVAL = newSVpvn(md, md_len);
	  	break;
          case FLAG_HEX:
                RETVAL = hexsv(md, md_len);
                break;
          default:
                RETVAL = base64sv(md, md_len);
		break;
        }
#line 2354 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__HMAC_new_md2); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__HMAC_new_md2)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
	OpenSSL__Digest	RETVAL;
#line 1413 "OpenSSL.xs"
   	RETVAL = (EVP_MD_CTX *) malloc(sizeof(EVP_MD_CTX));
	if(!RETVAL)
  		croak("out of memory.");
     	EVP_DigestInit(RETVAL, _mds[NO_FLAGS(ix)]);
#line 2376 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::Digest", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__HMAC_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__HMAC_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "ctx");
    {
	OpenSSL__Digest	ctx;

	if (SvROK(ST(0))) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    ctx = INT2PTR(OpenSSL__Digest,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not a reference",
			"OpenSSL::HMAC::DESTROY",
			"ctx")
;
#line 1424 "OpenSSL.xs"
  	if(ctx)
  		free(ctx);
#line 2409 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__HMAC_update); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__HMAC_update)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "ctx, ...");
    {
	OpenSSL__Digest	ctx;
#line 1431 "OpenSSL.xs"
    	STRLEN l;
        char *p;
        int i;
#line 2427 "OpenSSL.c"

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::Digest")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    ctx = INT2PTR(OpenSSL__Digest,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::HMAC::update",
			"ctx", "OpenSSL::Digest")
;
#line 1435 "OpenSSL.xs"
        for (i = 1; i < items; i++)
          {
            p = SvPV(ST(i), l);
            EVP_DigestUpdate(ctx, p, l);
          }
#line 2444 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__HMAC_final); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__HMAC_final)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 1)
       croak_xs_usage(cv,  "ctx");
    {
	OpenSSL__Digest	ctx;
#line 1448 "OpenSSL.xs"
        unsigned char md[EVP_MAX_MD_SIZE];
        unsigned int md_len;
#line 2462 "OpenSSL.c"
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::Digest")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    ctx = INT2PTR(OpenSSL__Digest,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"ctx", "OpenSSL::Digest")
;
#line 1451 "OpenSSL.xs"
      	EVP_DigestFinal(ctx, md, &md_len);
        switch(ix) {
          case 0:
            	RETVAL = newSVpvn(md, md_len);
            	break;
          case 1:
                RETVAL = hexsv(md, md_len);
                break;
          default:
                RETVAL = base64sv(md, md_len);
		break;
        }
#line 2487 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__PKCS7_new); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__PKCS7_new)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
	OpenSSL__PKCS7	RETVAL;
#line 1472 "OpenSSL.xs"
  	if(!(RETVAL = PKCS7_new())) {
                croak("PKCS7_new");
        }
#line 2507 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::PKCS7", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__PKCS7_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__PKCS7_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "p7");
    {
	OpenSSL__PKCS7	p7;

	if (SvROK(ST(0))) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    p7 = INT2PTR(OpenSSL__PKCS7,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not a reference",
			"OpenSSL::PKCS7::DESTROY",
			"p7")
;
#line 1483 "OpenSSL.xs"
   	if(p7) {
     		XD("PKCS7_free(%p)\n", p7);
  		PKCS7_free(p7);
        }
#line 2542 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__PKCS12_new); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__PKCS12_new)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "class");
    {
	SV *	class = ST(0)
;
	OpenSSL__PKCS12	RETVAL;
#line 1495 "OpenSSL.xs"
  	if(!(RETVAL = PKCS12_new())) {
                croak("PKCS12_new");
        }
#line 2562 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::PKCS12", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__PKCS12_new_from_string); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__PKCS12_new_from_string)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 2)
       croak_xs_usage(cv,  "class, sv");
    {
	SV *	class = ST(0)
;
	SV *	sv = ST(1)
;
#line 1508 "OpenSSL.xs"
        BIO *bio;
        char *s;
        STRLEN len;
#line 2590 "OpenSSL.c"
	OpenSSL__PKCS12	RETVAL;
#line 1512 "OpenSSL.xs"
      	s = SvPV(sv, len);
        if(ix == 1) {
          	bio = BIO_new_file(s, "r");
        } else {
        	bio = BIO_new_mem_buf (s, len);
        }
        if(!bio)
          croak("BIO_new_mem_buf");
        if(!(RETVAL = d2i_PKCS12_bio(bio, 0))) {
		BIO_free(bio);
         	croak("d2i_PKCS12_BIO: %s", ssl_error());
         }
	BIO_free(bio);
#line 2606 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::PKCS12", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__PKCS12_mac_ok); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__PKCS12_mac_ok)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "p12, pwd");
    {
	OpenSSL__PKCS12	p12;
	char *	pwd = (char *)SvPV_nolen(ST(1))
;
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::PKCS12")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    p12 = INT2PTR(OpenSSL__PKCS12,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::PKCS12::mac_ok",
			"p12", "OpenSSL::PKCS12")
;
#line 1535 "OpenSSL.xs"
   	RETVAL = (PKCS12_verify_mac(p12, pwd, strlen(pwd))) ? &PL_sv_yes : &PL_sv_no;
#line 2641 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__PKCS12_changepass); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__PKCS12_changepass)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "p12, oldpwd, newpwd");
    {
	OpenSSL__PKCS12	p12;
	SV *	oldpwd = ST(1)
;
	SV *	newpwd = ST(2)
;
#line 1545 "OpenSSL.xs"
    	char *op = 0;
        char *np = 0;
#line 2664 "OpenSSL.c"

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::PKCS12")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    p12 = INT2PTR(OpenSSL__PKCS12,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::PKCS12::changepass",
			"p12", "OpenSSL::PKCS12")
;
#line 1548 "OpenSSL.xs"
    	if(oldpwd != &PL_sv_undef)
  		op = SvPV_nolen(oldpwd);
    	if(newpwd != &PL_sv_undef)
  		np = SvPV_nolen(newpwd);
    	if(!PKCS12_newpass(p12, op, np)) {
      		croak("PKCS12_newpass: %s", ssl_error());
    	}
#line 2683 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__PKCS12_as_string); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__PKCS12_as_string)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items < 1)
       croak_xs_usage(cv,  "p12, ...");
    {
	OpenSSL__PKCS12	p12;
#line 1563 "OpenSSL.xs"
        BIO *bio;
#line 2700 "OpenSSL.c"
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::PKCS12")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    p12 = INT2PTR(OpenSSL__PKCS12,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"p12", "OpenSSL::PKCS12")
;
#line 1565 "OpenSSL.xs"
     	if((ix != 1 && items > 1) || (ix == 1 && items != 2))
            croak("OpenSSL::PKCS12::%s: illegal/missing args", (ix == 1) ? "as_file" : "as_string");
   	if(items > 1) {
   	   bio = sv_bio_create_file(ST(1));
        } else {
           bio = sv_bio_create();
        }
	if(!bio)
  		croak("sv_bio_create");
        if(!i2d_PKCS12_bio(bio, p12)) {
          	sv_bio_error(bio);
                croak("i2d_PKCS12_bio: %s", ssl_error());
        }
	RETVAL = sv_bio_final(bio);
#line 2727 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__PKCS12_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__PKCS12_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "p12");
    {
	OpenSSL__PKCS12	p12;

	if (SvROK(ST(0))) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    p12 = INT2PTR(OpenSSL__PKCS12,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not a reference",
			"OpenSSL::PKCS12::DESTROY",
			"p12")
;
#line 1586 "OpenSSL.xs"
   	if(p12) {
     		XD("PKCS12_free(%p)\n", p12);
  		PKCS12_free(p12);
   	}
#line 2758 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__CRL_new_from_string); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__CRL_new_from_string)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 2)
       croak_xs_usage(cv,  "class, thing");
    {
	SV *	class = ST(0)
;
	SV *	thing = ST(1)
;
#line 1601 "OpenSSL.xs"
  	BIO *bio;
        STRLEN l;
        char *p;
#line 2780 "OpenSSL.c"
	OpenSSL__CRL	RETVAL;
#line 1605 "OpenSSL.xs"
	p = SvPV(thing, l);
        if(ix == 1) {
          	bio = BIO_new_file(p, "r");
        } else {
        	bio = BIO_new_mem_buf (p, l);
        }
	if(!bio) 
  		croak(ssl_error());

        RETVAL = PEM_read_bio_X509_CRL (bio, 0, 0, 0);
        BIO_free (bio);
        if(!RETVAL)
  		croak("PEM_read_bio_X509_CRL: %s", ssl_error());

#line 2797 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::CRL", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__CRL_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__CRL_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "crl");
    {
	OpenSSL__CRL	crl;

	if (SvROK(ST(0))) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    crl = INT2PTR(OpenSSL__CRL,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not a reference",
			"OpenSSL::CRL::DESTROY",
			"crl")
;
#line 1626 "OpenSSL.xs"
  	if (crl) {
     		XD("X509_CRL_free (%p)\n", crl);
	  	X509_CRL_free(crl);
                crl = 0;
        }
#line 2833 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__CRL_info); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__CRL_info)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "crl");
    {
	OpenSSL__CRL	crl;
#line 1636 "OpenSSL.xs"
   	BIO *bio;
#line 2849 "OpenSSL.c"
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::CRL")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    crl = INT2PTR(OpenSSL__CRL,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::CRL::info",
			"crl", "OpenSSL::CRL")
;
#line 1638 "OpenSSL.xs"
   	bio = sv_bio_create();
        if(!X509_CRL_print(bio,crl)) {
          	sv_bio_error(bio);
          	croak("X509_CRL_print: %s", ssl_error());
        }
	RETVAL = sv_bio_final(bio);
#line 2868 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

XS_EUPXS(XS_OpenSSL__BN_new); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_new)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "class, ...");
    {
	SV *	class = ST(0)
;
	OpenSSL__BN	RETVAL;
#line 1659 "OpenSSL.xs"
        unsigned char *p;
    	RETVAL = BN_new();
	BN_init(RETVAL);
        if(items == 2) {
          p = SvPV(ST(1), PL_na);
  	  BN_dec2bn(&RETVAL, p);
        } else {
          BN_zero(RETVAL);
        }
#line 2899 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::BN", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__BN_clone); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_clone)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "bn");
    {
	OpenSSL__BN	bn;
	OpenSSL__BN	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    bn = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::BN::clone",
			"bn", "OpenSSL::BN")
;
#line 1675 "OpenSSL.xs"
    	RETVAL = BN_dup(bn);
#line 2932 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::BN", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__BN_add); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_add)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 2)
       croak_xs_usage(cv,  "bn1, bn2");
    {
	OpenSSL__BN	bn1;
	OpenSSL__BN	bn2;
	OpenSSL__BN	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    bn1 = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"bn1", "OpenSSL::BN")
;

	if (SvROK(ST(1)) && sv_derived_from(ST(1), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(1)));
	    bn2 = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"bn2", "OpenSSL::BN")
;
#line 1686 "OpenSSL.xs"
    	RETVAL = BN_new();
        BN_init(RETVAL);
        switch(ix) {
          case 0:
        	BN_add(RETVAL, bn1, bn2);
                break;
          case 1:
                BN_sub(RETVAL, bn1, bn2);
                break;
        }
#line 2986 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::BN", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__BN_mul); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_mul)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 2)
       croak_xs_usage(cv,  "bn1, bn2");
    {
	OpenSSL__BN	bn1;
	OpenSSL__BN	bn2;
#line 1708 "OpenSSL.xs"
        BN_CTX  *ctx;
#line 3010 "OpenSSL.c"
	OpenSSL__BN	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    bn1 = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"bn1", "OpenSSL::BN")
;

	if (SvROK(ST(1)) && sv_derived_from(ST(1), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(1)));
	    bn2 = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"bn2", "OpenSSL::BN")
;
#line 1710 "OpenSSL.xs"
        ctx = BN_CTX_new();
        BN_CTX_init(ctx);
    	RETVAL = BN_new();
        BN_init(RETVAL);
        switch(ix) {
          case 0:
        	BN_mul(RETVAL, bn1, bn2, ctx);
                break;
          case 1:
                 {
                   BIGNUM *tmp = BN_new();
                   BN_init(tmp);
                   if(BN_is_zero(bn2)) {
                     BN_clear_free(tmp);
                     croak("Illegal division by zero");
                   }
                   BN_div(RETVAL, tmp, bn1, bn2, ctx);
                   BN_clear_free(tmp);
                 }
                break;
          case 2:
                 {
                   BIGNUM *tmp = BN_new();
                   BN_init(tmp);
                   if(BN_is_zero(bn2)) {
                     BN_clear_free(tmp);
                     croak("Illegal modulus zero");
                   }
                   BN_div(tmp, RETVAL, bn1, bn2, ctx);
                   BN_clear_free(tmp);
                 }
                break;
          case 3:
                 {
                   BN_exp(RETVAL, bn1, bn2, ctx);
                 }
                break;
        }
        BN_CTX_free(ctx);
#line 3072 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::BN", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__BN_icmp); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_icmp)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "bn1, bn2");
    {
	OpenSSL__BN	bn1;
	OpenSSL__BN	bn2;
	IV	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    bn1 = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::BN::icmp",
			"bn1", "OpenSSL::BN")
;

	if (SvROK(ST(1)) && sv_derived_from(ST(1), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(1)));
	    bn2 = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::BN::icmp",
			"bn2", "OpenSSL::BN")
;
#line 1757 "OpenSSL.xs"
	RETVAL = BN_cmp(bn1,bn2);
#line 3117 "OpenSSL.c"
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__BN_inc); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_inc)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 1)
       croak_xs_usage(cv,  "bn");
    {
	OpenSSL__BN	bn;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    bn = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"bn", "OpenSSL::BN")
;
#line 1767 "OpenSSL.xs"
   	((ix) ? BN_sub_word : BN_add_word)(bn, 1);
#line 3145 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_OpenSSL__BN_stringify); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_stringify)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "bn");
    {
	OpenSSL__BN	bn;
#line 1774 "OpenSSL.xs"
    	char *p;
#line 3161 "OpenSSL.c"
	SV *	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    bn = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::BN::stringify",
			"bn", "OpenSSL::BN")
;
#line 1776 "OpenSSL.xs"
        p = BN_bn2dec(bn);
    	RETVAL = newSVpv(p,0);
        free(p);
#line 3177 "OpenSSL.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__BN_lshift); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_lshift)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 2)
       croak_xs_usage(cv,  "bn, cnt");
    {
	OpenSSL__BN	bn;
	IV	cnt = (IV)SvIV(ST(1))
;
	OpenSSL__BN	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    bn = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"bn", "OpenSSL::BN")
;
#line 1789 "OpenSSL.xs"
    	RETVAL = BN_new();
        BN_init(RETVAL);
        if(ix)
  		BN_rshift(RETVAL,bn,cnt);
        else
        	BN_lshift(RETVAL, bn, cnt);
#line 3214 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::BN", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__BN_sqr); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_sqr)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "bn");
    {
	OpenSSL__BN	bn;
#line 1802 "OpenSSL.xs"
    	BN_CTX *ctx;
#line 3236 "OpenSSL.c"
	OpenSSL__BN	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    bn = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::BN::sqr",
			"bn", "OpenSSL::BN")
;
#line 1804 "OpenSSL.xs"
        ctx = BN_CTX_new();
        BN_CTX_init(ctx);
    	RETVAL = BN_new();
        BN_init(RETVAL);
        BN_sqr(RETVAL, bn, ctx);
        BN_CTX_free(ctx);
#line 3255 "OpenSSL.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, "OpenSSL::BN", (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__BN_bnbool); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_bnbool)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "bn");
    {
	OpenSSL__BN	bn;
	bool	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    bn = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::BN::bnbool",
			"bn", "OpenSSL::BN")
;
#line 1817 "OpenSSL.xs"
	RETVAL = !BN_is_zero(bn);
#line 3288 "OpenSSL.c"
	ST(0) = boolSV(RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__BN_isprime); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_isprime)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "bn");
    {
	OpenSSL__BN	bn;
#line 1825 "OpenSSL.xs"
   	BN_CTX *ctx;
#line 3305 "OpenSSL.c"
	bool	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "OpenSSL::BN")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    bn = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"OpenSSL::BN::isprime",
			"bn", "OpenSSL::BN")
;
#line 1827 "OpenSSL.xs"
        ctx = BN_CTX_new();
        BN_CTX_init(ctx);
	RETVAL = BN_is_prime(bn, /*30*/0, 0, ctx, 0);
#line 3321 "OpenSSL.c"
	ST(0) = boolSV(RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_OpenSSL__BN_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_OpenSSL__BN_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "bn");
    {
	OpenSSL__BN	bn;

	if (SvROK(ST(0))) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    bn = INT2PTR(OpenSSL__BN,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not a reference",
			"OpenSSL::BN::DESTROY",
			"bn")
;
#line 1838 "OpenSSL.xs"
    	BN_clear_free(bn);
#line 3348 "OpenSSL.c"
    }
    XSRETURN_EMPTY;
}

#ifdef __cplusplus
extern "C"
#endif
XS_EXTERNAL(boot_OpenSSL); /* prototype to pass -Wmissing-prototypes */
XS_EXTERNAL(boot_OpenSSL)
{
#if PERL_VERSION_LE(5, 21, 5)
    dVAR; dXSARGS;
#else
    dVAR; dXSBOOTARGSXSAPIVERCHK;
#endif
#if (PERL_REVISION == 5 && PERL_VERSION < 9)
    char* file = __FILE__;
#else
    const char* file = __FILE__;
#endif

    PERL_UNUSED_VAR(file);

    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
#if PERL_VERSION_LE(5, 21, 5)
    XS_VERSION_BOOTCHECK;
#  ifdef XS_APIVERSION_BOOTCHECK
    XS_APIVERSION_BOOTCHECK;
#  endif
#endif

        newXS_deffile("OpenSSL::RSA::new_keygen", XS_OpenSSL__RSA_new_keygen);
        newXS_deffile("OpenSSL::RSA::new_pubkey", XS_OpenSSL__RSA_new_pubkey);
        newXS_deffile("OpenSSL::RSA::new_privkey", XS_OpenSSL__RSA_new_privkey);
        newXS_deffile("OpenSSL::RSA::DESTROY", XS_OpenSSL__RSA_DESTROY);
        newXS_deffile("OpenSSL::RSA::keysize", XS_OpenSSL__RSA_keysize);
        newXS_deffile("OpenSSL::RSA::check_key", XS_OpenSSL__RSA_check_key);
        cv = newXS_deffile("OpenSSL::RSA::d", XS_OpenSSL__RSA_n);
        XSANY.any_i32 = 2;
        cv = newXS_deffile("OpenSSL::RSA::dmp1", XS_OpenSSL__RSA_n);
        XSANY.any_i32 = 5;
        cv = newXS_deffile("OpenSSL::RSA::dmq1", XS_OpenSSL__RSA_n);
        XSANY.any_i32 = 6;
        cv = newXS_deffile("OpenSSL::RSA::e", XS_OpenSSL__RSA_n);
        XSANY.any_i32 = 1;
        cv = newXS_deffile("OpenSSL::RSA::iqmp", XS_OpenSSL__RSA_n);
        XSANY.any_i32 = 7;
        cv = newXS_deffile("OpenSSL::RSA::n", XS_OpenSSL__RSA_n);
        XSANY.any_i32 = 0;
        cv = newXS_deffile("OpenSSL::RSA::p", XS_OpenSSL__RSA_n);
        XSANY.any_i32 = 3;
        cv = newXS_deffile("OpenSSL::RSA::q", XS_OpenSSL__RSA_n);
        XSANY.any_i32 = 4;
        newXS_deffile("OpenSSL::RSA::is_privkey", XS_OpenSSL__RSA_is_privkey);
        newXS_deffile("OpenSSL::RSA::STORABLE_thaw", XS_OpenSSL__RSA_STORABLE_thaw);
        newXS_deffile("OpenSSL::RSA::STORABLE_freeze", XS_OpenSSL__RSA_STORABLE_freeze);
        cv = newXS_deffile("OpenSSL::RSA::decrypt", XS_OpenSSL__RSA_public_encrypt);
        XSANY.any_i32 = 7;
        cv = newXS_deffile("OpenSSL::RSA::encrypt", XS_OpenSSL__RSA_public_encrypt);
        XSANY.any_i32 = 4;
        cv = newXS_deffile("OpenSSL::RSA::private_decrypt", XS_OpenSSL__RSA_public_encrypt);
        XSANY.any_i32 = 3;
        cv = newXS_deffile("OpenSSL::RSA::private_encrypt", XS_OpenSSL__RSA_public_encrypt);
        XSANY.any_i32 = 2;
        cv = newXS_deffile("OpenSSL::RSA::public_decrypt", XS_OpenSSL__RSA_public_encrypt);
        XSANY.any_i32 = 1;
        cv = newXS_deffile("OpenSSL::RSA::public_encrypt", XS_OpenSSL__RSA_public_encrypt);
        XSANY.any_i32 = 0;
        cv = newXS_deffile("OpenSSL::RSA::sign", XS_OpenSSL__RSA_public_encrypt);
        XSANY.any_i32 = 6;
        cv = newXS_deffile("OpenSSL::RSA::verify", XS_OpenSSL__RSA_public_encrypt);
        XSANY.any_i32 = 5;
        newXS_deffile("OpenSSL::RSA::fingerprint", XS_OpenSSL__RSA_fingerprint);
        (void)newXSproto_portable("OpenSSL::Name::new", XS_OpenSSL__Name_new, file, "$");
        (void)newXSproto_portable("OpenSSL::Name::add", XS_OpenSSL__Name_add, file, "$$$");
        (void)newXSproto_portable("OpenSSL::Name::count", XS_OpenSSL__Name_count, file, "$");
        (void)newXSproto_portable("OpenSSL::Name::getall", XS_OpenSSL__Name_getall, file, "$");
        (void)newXSproto_portable("OpenSSL::Name::DESTROY", XS_OpenSSL__Name_DESTROY, file, "$");
        cv = newXSproto_portable("OpenSSL::Rand::randbytes", XS_OpenSSL__Rand_randbytes, file, "$");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("OpenSSL::Rand::randbytes_base64", XS_OpenSSL__Rand_randbytes, file, "$");
        XSANY.any_i32 = 2;
        cv = newXSproto_portable("OpenSSL::Rand::randbytes_hex", XS_OpenSSL__Rand_randbytes, file, "$");
        XSANY.any_i32 = 1;
        (void)newXSproto_portable("OpenSSL::X509::new", XS_OpenSSL__X509_new, file, "$");
        cv = newXSproto_portable("OpenSSL::X509::new_from_file", XS_OpenSSL__X509_new_from_string, file, "$$");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("OpenSSL::X509::new_from_string", XS_OpenSSL__X509_new_from_string, file, "$$");
        XSANY.any_i32 = 0;
        (void)newXSproto_portable("OpenSSL::X509::DESTROY", XS_OpenSSL__X509_DESTROY, file, "$");
        cv = newXSproto_portable("OpenSSL::X509::fingerprint_md2", XS_OpenSSL__X509_fingerprint_md5, file, "$");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("OpenSSL::X509::fingerprint_md5", XS_OpenSSL__X509_fingerprint_md5, file, "$");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("OpenSSL::X509::fingerprint_sha1", XS_OpenSSL__X509_fingerprint_md5, file, "$");
        XSANY.any_i32 = 2;
        (void)newXSproto_portable("OpenSSL::X509::subject", XS_OpenSSL__X509_subject, file, "$");
        (void)newXSproto_portable("OpenSSL::X509::issuer", XS_OpenSSL__X509_issuer, file, "$");
        (void)newXSproto_portable("OpenSSL::X509::subject_txt", XS_OpenSSL__X509_subject_txt, file, "$");
        (void)newXSproto_portable("OpenSSL::X509::issuer_txt", XS_OpenSSL__X509_issuer_txt, file, "$");
        (void)newXSproto_portable("OpenSSL::X509::serial", XS_OpenSSL__X509_serial, file, "$");
        (void)newXSproto_portable("OpenSSL::X509::version", XS_OpenSSL__X509_version, file, "$");
        (void)newXSproto_portable("OpenSSL::X509::notBefore", XS_OpenSSL__X509_notBefore, file, "$");
        (void)newXSproto_portable("OpenSSL::X509::notAfter", XS_OpenSSL__X509_notAfter, file, "$");
        (void)newXSproto_portable("OpenSSL::X509::cert_type", XS_OpenSSL__X509_cert_type, file, "$");
        cv = newXSproto_portable("OpenSSL::X509::as_file", XS_OpenSSL__X509_as_string, file, "$;$");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("OpenSSL::X509::as_string", XS_OpenSSL__X509_as_string, file, "$;$");
        XSANY.any_i32 = 0;
        (void)newXSproto_portable("OpenSSL::X509::info", XS_OpenSSL__X509_info, file, "$");
        (void)newXSproto_portable("OpenSSL::X509::set_issuer", XS_OpenSSL__X509_set_issuer, file, "$$");
        (void)newXSproto_portable("OpenSSL::X509::set_subject", XS_OpenSSL__X509_set_subject, file, "$$");
        (void)newXSproto_portable("OpenSSL::X509::errstring", XS_OpenSSL__X509_errstring, file, "$");
        (void)newXSproto_portable("OpenSSL::Cipher::DESTROY", XS_OpenSSL__Cipher_DESTROY, file, "$");
        cv = newXSproto_portable("OpenSSL::Cipher::new_decrypt", XS_OpenSSL__Cipher_new_decrypt, file, ";@");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("OpenSSL::Cipher::new_encrypt", XS_OpenSSL__Cipher_new_decrypt, file, ";@");
        XSANY.any_i32 = 1;
        (void)newXSproto_portable("OpenSSL::Cipher::update", XS_OpenSSL__Cipher_update, file, "$$");
        (void)newXSproto_portable("OpenSSL::Cipher::final", XS_OpenSSL__Cipher_final, file, "$");
        (void)newXSproto_portable("OpenSSL::Cipher::enum_ciphers", XS_OpenSSL__Cipher_enum_ciphers, file, "");
        cv = newXSproto_portable("OpenSSL::Digest::dss", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x5;
        cv = newXSproto_portable("OpenSSL::Digest::dss1", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x6;
        cv = newXSproto_portable("OpenSSL::Digest::dss1_base64", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x26;
        cv = newXSproto_portable("OpenSSL::Digest::dss1_hex", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x16;
        cv = newXSproto_portable("OpenSSL::Digest::dss_base64", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x25;
        cv = newXSproto_portable("OpenSSL::Digest::dss_hex", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x15;
        cv = newXSproto_portable("OpenSSL::Digest::md2", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("OpenSSL::Digest::md2_base64", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x20;
        cv = newXSproto_portable("OpenSSL::Digest::md2_hex", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x10;
        cv = newXSproto_portable("OpenSSL::Digest::md4", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x1;
        cv = newXSproto_portable("OpenSSL::Digest::md4_base64", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x21;
        cv = newXSproto_portable("OpenSSL::Digest::md4_hex", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x11;
        cv = newXSproto_portable("OpenSSL::Digest::md5", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x2;
        cv = newXSproto_portable("OpenSSL::Digest::md5_base64", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x22;
        cv = newXSproto_portable("OpenSSL::Digest::md5_hex", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x12;
        cv = newXSproto_portable("OpenSSL::Digest::mdc2", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x7;
        cv = newXSproto_portable("OpenSSL::Digest::mdc2_base64", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x27;
        cv = newXSproto_portable("OpenSSL::Digest::mdc2_hex", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x17;
        cv = newXSproto_portable("OpenSSL::Digest::ripemd160", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x8;
        cv = newXSproto_portable("OpenSSL::Digest::ripemd160_base64", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x28;
        cv = newXSproto_portable("OpenSSL::Digest::ripemd160_hex", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x18;
        cv = newXSproto_portable("OpenSSL::Digest::sha", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x3;
        cv = newXSproto_portable("OpenSSL::Digest::sha1", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x4;
        cv = newXSproto_portable("OpenSSL::Digest::sha1_base64", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x24;
        cv = newXSproto_portable("OpenSSL::Digest::sha1_hex", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x14;
        cv = newXSproto_portable("OpenSSL::Digest::sha_base64", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x23;
        cv = newXSproto_portable("OpenSSL::Digest::sha_hex", XS_OpenSSL__Digest_md2, file, ";@");
        XSANY.any_i32 = 0x13;
        cv = newXSproto_portable("OpenSSL::Digest::mew_sha", XS_OpenSSL__Digest_new_md2, file, "");
        XSANY.any_i32 = 0x3;
        cv = newXSproto_portable("OpenSSL::Digest::new_dss", XS_OpenSSL__Digest_new_md2, file, "");
        XSANY.any_i32 = 0x5;
        cv = newXSproto_portable("OpenSSL::Digest::new_dss1", XS_OpenSSL__Digest_new_md2, file, "");
        XSANY.any_i32 = 0x6;
        cv = newXSproto_portable("OpenSSL::Digest::new_md2", XS_OpenSSL__Digest_new_md2, file, "");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("OpenSSL::Digest::new_md4", XS_OpenSSL__Digest_new_md2, file, "");
        XSANY.any_i32 = 0x1;
        cv = newXSproto_portable("OpenSSL::Digest::new_md5", XS_OpenSSL__Digest_new_md2, file, "");
        XSANY.any_i32 = 0x2;
        cv = newXSproto_portable("OpenSSL::Digest::new_mdc2", XS_OpenSSL__Digest_new_md2, file, "");
        XSANY.any_i32 = 0x7;
        cv = newXSproto_portable("OpenSSL::Digest::new_ripemd160", XS_OpenSSL__Digest_new_md2, file, "");
        XSANY.any_i32 = 0x8;
        cv = newXSproto_portable("OpenSSL::Digest::new_sha1", XS_OpenSSL__Digest_new_md2, file, "");
        XSANY.any_i32 = 0x4;
        (void)newXSproto_portable("OpenSSL::Digest::DESTROY", XS_OpenSSL__Digest_DESTROY, file, "$");
        (void)newXSproto_portable("OpenSSL::Digest::update", XS_OpenSSL__Digest_update, file, "$;@");
        cv = newXSproto_portable("OpenSSL::Digest::final", XS_OpenSSL__Digest_final, file, "$");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("OpenSSL::Digest::final_base64", XS_OpenSSL__Digest_final, file, "$");
        XSANY.any_i32 = 2;
        cv = newXSproto_portable("OpenSSL::Digest::final_hex", XS_OpenSSL__Digest_final, file, "$");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("OpenSSL::HMAC::dss", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x5;
        cv = newXSproto_portable("OpenSSL::HMAC::dss1", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x6;
        cv = newXSproto_portable("OpenSSL::HMAC::dss1_base64", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x26;
        cv = newXSproto_portable("OpenSSL::HMAC::dss1_hex", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x16;
        cv = newXSproto_portable("OpenSSL::HMAC::dss_base64", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x25;
        cv = newXSproto_portable("OpenSSL::HMAC::dss_hex", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x15;
        cv = newXSproto_portable("OpenSSL::HMAC::md2", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("OpenSSL::HMAC::md2_base64", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x20;
        cv = newXSproto_portable("OpenSSL::HMAC::md2_hex", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x10;
        cv = newXSproto_portable("OpenSSL::HMAC::md4", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x1;
        cv = newXSproto_portable("OpenSSL::HMAC::md4_base64", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x21;
        cv = newXSproto_portable("OpenSSL::HMAC::md4_hex", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x11;
        cv = newXSproto_portable("OpenSSL::HMAC::md5", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x2;
        cv = newXSproto_portable("OpenSSL::HMAC::md5_base64", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x22;
        cv = newXSproto_portable("OpenSSL::HMAC::md5_hex", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x12;
        cv = newXSproto_portable("OpenSSL::HMAC::mdc2", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x7;
        cv = newXSproto_portable("OpenSSL::HMAC::mdc2_base64", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x27;
        cv = newXSproto_portable("OpenSSL::HMAC::mdc2_hex", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x17;
        cv = newXSproto_portable("OpenSSL::HMAC::ripemd160", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x8;
        cv = newXSproto_portable("OpenSSL::HMAC::ripemd160_base64", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x28;
        cv = newXSproto_portable("OpenSSL::HMAC::ripemd160_hex", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x18;
        cv = newXSproto_portable("OpenSSL::HMAC::sha", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x3;
        cv = newXSproto_portable("OpenSSL::HMAC::sha1", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x4;
        cv = newXSproto_portable("OpenSSL::HMAC::sha1_base64", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x24;
        cv = newXSproto_portable("OpenSSL::HMAC::sha1_hex", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x14;
        cv = newXSproto_portable("OpenSSL::HMAC::sha_base64", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x23;
        cv = newXSproto_portable("OpenSSL::HMAC::sha_hex", XS_OpenSSL__HMAC_md2, file, "$$");
        XSANY.any_i32 = 0x13;
        cv = newXSproto_portable("OpenSSL::HMAC::mew_sha", XS_OpenSSL__HMAC_new_md2, file, "");
        XSANY.any_i32 = 0x3;
        cv = newXSproto_portable("OpenSSL::HMAC::new_dss", XS_OpenSSL__HMAC_new_md2, file, "");
        XSANY.any_i32 = 0x5;
        cv = newXSproto_portable("OpenSSL::HMAC::new_dss1", XS_OpenSSL__HMAC_new_md2, file, "");
        XSANY.any_i32 = 0x6;
        cv = newXSproto_portable("OpenSSL::HMAC::new_md2", XS_OpenSSL__HMAC_new_md2, file, "");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("OpenSSL::HMAC::new_md4", XS_OpenSSL__HMAC_new_md2, file, "");
        XSANY.any_i32 = 0x1;
        cv = newXSproto_portable("OpenSSL::HMAC::new_md5", XS_OpenSSL__HMAC_new_md2, file, "");
        XSANY.any_i32 = 0x2;
        cv = newXSproto_portable("OpenSSL::HMAC::new_mdc2", XS_OpenSSL__HMAC_new_md2, file, "");
        XSANY.any_i32 = 0x7;
        cv = newXSproto_portable("OpenSSL::HMAC::new_ripemd160", XS_OpenSSL__HMAC_new_md2, file, "");
        XSANY.any_i32 = 0x8;
        cv = newXSproto_portable("OpenSSL::HMAC::new_sha1", XS_OpenSSL__HMAC_new_md2, file, "");
        XSANY.any_i32 = 0x4;
        (void)newXSproto_portable("OpenSSL::HMAC::DESTROY", XS_OpenSSL__HMAC_DESTROY, file, "$");
        (void)newXSproto_portable("OpenSSL::HMAC::update", XS_OpenSSL__HMAC_update, file, "$;@");
        cv = newXSproto_portable("OpenSSL::HMAC::final", XS_OpenSSL__HMAC_final, file, "$");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("OpenSSL::HMAC::final_base64", XS_OpenSSL__HMAC_final, file, "$");
        XSANY.any_i32 = 2;
        cv = newXSproto_portable("OpenSSL::HMAC::final_hex", XS_OpenSSL__HMAC_final, file, "$");
        XSANY.any_i32 = 1;
        (void)newXSproto_portable("OpenSSL::PKCS7::new", XS_OpenSSL__PKCS7_new, file, "");
        (void)newXSproto_portable("OpenSSL::PKCS7::DESTROY", XS_OpenSSL__PKCS7_DESTROY, file, "$");
        (void)newXSproto_portable("OpenSSL::PKCS12::new", XS_OpenSSL__PKCS12_new, file, "$");
        cv = newXSproto_portable("OpenSSL::PKCS12::new_from_file", XS_OpenSSL__PKCS12_new_from_string, file, "$$");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("OpenSSL::PKCS12::new_from_string", XS_OpenSSL__PKCS12_new_from_string, file, "$$");
        XSANY.any_i32 = 0;
        (void)newXSproto_portable("OpenSSL::PKCS12::mac_ok", XS_OpenSSL__PKCS12_mac_ok, file, "$$");
        (void)newXSproto_portable("OpenSSL::PKCS12::changepass", XS_OpenSSL__PKCS12_changepass, file, "$$$");
        cv = newXSproto_portable("OpenSSL::PKCS12::as_file", XS_OpenSSL__PKCS12_as_string, file, "$;$");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("OpenSSL::PKCS12::as_string", XS_OpenSSL__PKCS12_as_string, file, "$;$");
        XSANY.any_i32 = 0;
        (void)newXSproto_portable("OpenSSL::PKCS12::DESTROY", XS_OpenSSL__PKCS12_DESTROY, file, "$");
        cv = newXSproto_portable("OpenSSL::CRL::new_from_file", XS_OpenSSL__CRL_new_from_string, file, "$$");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("OpenSSL::CRL::new_from_string", XS_OpenSSL__CRL_new_from_string, file, "$$");
        XSANY.any_i32 = 0;
        (void)newXSproto_portable("OpenSSL::CRL::DESTROY", XS_OpenSSL__CRL_DESTROY, file, "$");
        (void)newXSproto_portable("OpenSSL::CRL::info", XS_OpenSSL__CRL_info, file, "$");
        (void)newXSproto_portable("OpenSSL::BN::new", XS_OpenSSL__BN_new, file, "$;@");
        (void)newXSproto_portable("OpenSSL::BN::clone", XS_OpenSSL__BN_clone, file, "$");
        cv = newXSproto_portable("OpenSSL::BN::add", XS_OpenSSL__BN_add, file, "$$");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("OpenSSL::BN::sub", XS_OpenSSL__BN_add, file, "$$");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("OpenSSL::BN::div", XS_OpenSSL__BN_mul, file, "$$");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("OpenSSL::BN::exp", XS_OpenSSL__BN_mul, file, "$$");
        XSANY.any_i32 = 3;
        cv = newXSproto_portable("OpenSSL::BN::mod", XS_OpenSSL__BN_mul, file, "$$");
        XSANY.any_i32 = 2;
        cv = newXSproto_portable("OpenSSL::BN::mul", XS_OpenSSL__BN_mul, file, "$$");
        XSANY.any_i32 = 0;
        (void)newXSproto_portable("OpenSSL::BN::icmp", XS_OpenSSL__BN_icmp, file, "$$");
        cv = newXSproto_portable("OpenSSL::BN::dec", XS_OpenSSL__BN_inc, file, "$");
        XSANY.any_i32 = 1;
        cv = newXSproto_portable("OpenSSL::BN::inc", XS_OpenSSL__BN_inc, file, "$");
        XSANY.any_i32 = 0;
        (void)newXSproto_portable("OpenSSL::BN::stringify", XS_OpenSSL__BN_stringify, file, "$");
        cv = newXSproto_portable("OpenSSL::BN::lshift", XS_OpenSSL__BN_lshift, file, "$$");
        XSANY.any_i32 = 0;
        cv = newXSproto_portable("OpenSSL::BN::rshift", XS_OpenSSL__BN_lshift, file, "$$");
        XSANY.any_i32 = 1;
        (void)newXSproto_portable("OpenSSL::BN::sqr", XS_OpenSSL__BN_sqr, file, "$");
        (void)newXSproto_portable("OpenSSL::BN::bnbool", XS_OpenSSL__BN_bnbool, file, "$");
        (void)newXSproto_portable("OpenSSL::BN::isprime", XS_OpenSSL__BN_isprime, file, "$");
        (void)newXSproto_portable("OpenSSL::BN::DESTROY", XS_OpenSSL__BN_DESTROY, file, "$");

    /* Initialisation Section */

#line 789 "OpenSSL.xs"
{
       int fd;
       int rc;
       ERR_load_RAND_strings();
       fd = open("/dev/urandom", O_RDONLY);
       if(fd != -1) {
            char buf[64];
            rc = read(fd, buf, 64);
            if(rc < 1) {
                warn ("read /dev/urandom");
            } else {
                RAND_seed(buf, rc);
            }
            close(fd);
       } else {
          warn ("can't open /dev/urandom");
       }
}

#line 849 "OpenSSL.xs"
{
	// We have joy we have fun we have seasons in the sun...
	OpenSSL_add_all_algorithms();
        OpenSSL_add_all_ciphers();
        OpenSSL_add_all_digests();
        SSL_load_error_strings();
	ERR_load_PEM_strings();
        ERR_load_PKCS7_strings();
        ERR_load_PKCS12_strings();
        ERR_load_ASN1_strings();
        ERR_load_crypto_strings();
        ERR_load_RAND_strings();
        ERR_load_X509_strings();
        ERR_load_X509V3_strings();
        ERR_load_DH_strings();
        ERR_load_DSA_strings();
        ERR_load_RSA_strings();
}

#line 1089 "OpenSSL.xs"
{
	cipher_boot();
}

#line 1205 "OpenSSL.xs"
{
	mds_boot();
}

#line 1340 "OpenSSL.xs"
{
	mds_boot();
}

#line 3737 "OpenSSL.c"

    /* End of Initialisation Section */

#if PERL_VERSION_LE(5, 21, 5)
#  if PERL_VERSION_GE(5, 9, 0)
    if (PL_unitcheckav)
        call_list(PL_scopestack_ix, PL_unitcheckav);
#  endif
    XSRETURN_YES;
#else
    Perl_xs_boot_epilog(aTHX_ ax);
#endif
}

