Net-SSLeay

 view release on metacpan or  search on metacpan

SSLeay.xs  view on Meta::CPAN

#if defined(WIN32)

int
SSL_set_fd(s,fd)
     SSL *   s
     perl_filehandle_t     fd
     CODE:
     RETVAL = SSL_set_fd(s,_get_osfhandle(fd));
     OUTPUT:
     RETVAL

int
SSL_set_rfd(s,fd)
     SSL *   s
     perl_filehandle_t     fd
     CODE:
     RETVAL = SSL_set_rfd(s,_get_osfhandle(fd));
     OUTPUT:
     RETVAL

int
SSL_set_wfd(s,fd)
     SSL *   s
     perl_filehandle_t     fd
     CODE:
     RETVAL = SSL_set_wfd(s,_get_osfhandle(fd));
     OUTPUT:
     RETVAL

#else

int
SSL_set_fd(s,fd)
     SSL *   s
     perl_filehandle_t     fd

int
SSL_set_rfd(s,fd)
     SSL *   s
     perl_filehandle_t     fd

int
SSL_set_wfd(s,fd)
     SSL *   s
     perl_filehandle_t     fd

#endif

int
SSL_get_fd(s)
     SSL *   s

void
SSL_read(s,max=32768)
	SSL *   s
	int     max
    PREINIT:
	char *buf;
	int got;
	int succeeded = 1;
    PPCODE:
	New(0, buf, max, char);

	got = SSL_read(s, buf, max);
	if (got <= 0 && SSL_ERROR_ZERO_RETURN != SSL_get_error(s, got))
	       succeeded = 0;

	/* If in list context, return 2-item list:
	 *   first return value:  data gotten, or undef on error (got<0)
	 *   second return value: result from SSL_read()
	 */
	if (GIMME_V==G_LIST) {
	    EXTEND(SP, 2);
	    PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, got) : newSV(0)));
	    PUSHs(sv_2mortal(newSViv(got)));

	/* If in scalar or void context, return data gotten, or undef on error. */
	} else {
	    EXTEND(SP, 1);
	    PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, got) : newSV(0)));
	}

	Safefree(buf);

void
SSL_peek(s,max=32768)
	SSL *   s
	int     max
    PREINIT:
	char *buf;
	int got;
	int succeeded = 1;
    PPCODE:
	New(0, buf, max, char);

	got = SSL_peek(s, buf, max);
	if (got <= 0 && SSL_ERROR_ZERO_RETURN != SSL_get_error(s, got))
	       succeeded = 0;

	/* If in list context, return 2-item list:
	 *   first return value:  data gotten, or undef on error (got<0)
	 *   second return value: result from SSL_peek()
	 */
	if (GIMME_V==G_LIST) {
	    EXTEND(SP, 2);
	    PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, got) : newSV(0)));
	    PUSHs(sv_2mortal(newSViv(got)));
	    
	    /* If in scalar or void context, return data gotten, or undef on error. */
	} else {
	    EXTEND(SP, 1);
	    PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, got) : newSV(0)));
	}
	Safefree(buf);

#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 1.1.1 */

void
SSL_read_ex(s,max=32768)
	SSL *   s
	int     max
    PREINIT:
	char *buf;
	size_t readbytes;
	int succeeded;
    PPCODE:
	Newx(buf, max, char);

	succeeded = SSL_read_ex(s, buf, max, &readbytes);

	/* Return 2-item list:
	 *   first return value:  data gotten, or undef on error
	 *   second return value: result from SSL_read_ex()
	 */
	EXTEND(SP, 2);
	PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, readbytes) : newSV(0)));
	PUSHs(sv_2mortal(newSViv(succeeded)));

	Safefree(buf);


void
SSL_peek_ex(s,max=32768)
	SSL *   s
	int     max
    PREINIT:
	char *buf;
	size_t readbytes;
	int succeeded;
    PPCODE:
	Newx(buf, max, char);

	succeeded = SSL_peek_ex(s, buf, max, &readbytes);

	/* Return 2-item list:
	 *   first return value:  data gotten, or undef on error
	 *   second return value: result from SSL_peek_ex()
	 */
	EXTEND(SP, 2);
	PUSHs(sv_2mortal(succeeded ? newSVpvn(buf, readbytes) : newSV(0)));
	PUSHs(sv_2mortal(newSViv(succeeded)));

	Safefree(buf);

void
SSL_write_ex(s,buf)
	SSL *   s
    PREINIT:
	STRLEN len;
	size_t written;
	int succeeded;
    INPUT:
	char *  buf = SvPV( ST(1), len);
    PPCODE:
	succeeded = SSL_write_ex(s, buf, len, &written);

	/* Return 2-item list:
	 *   first return value:  data gotten, or undef on error
	 *   second return value: result from SSL_read_ex()
	 */
	EXTEND(SP, 2);
	PUSHs(sv_2mortal(newSVuv(written)));
	PUSHs(sv_2mortal(newSViv(succeeded)));

#endif

int
SSL_write(s,buf)
     SSL *   s
     PREINIT:
     STRLEN len;
     INPUT:
     char *  buf = SvPV( ST(1), len);
     CODE:
     RETVAL = SSL_write (s, buf, (int)len);
     OUTPUT:
     RETVAL

int
SSL_write_partial(s,from,count,buf)
     SSL *   s
     int     from
     int     count
     PREINIT:
     STRLEN ulen;
     IV len;
     INPUT:
     char *  buf = SvPV( ST(3), ulen);
     CODE:
      /*
     if (SvROK( ST(3) )) {
       SV* t = SvRV( ST(3) );
       buf = SvPV( t, len);
     } else
       buf = SvPV( ST(3), len);
       */
     PR4("write_partial from=%d count=%d len=%lu\n",from,count,ulen);
     /*PR2("buf='%s'\n",&buf[from]); / * too noisy */
     len = (IV)ulen;
     len -= from;
     if (len < 0) {
       croak("from beyound end of buffer");
       RETVAL = -1;
     } else
       RETVAL = SSL_write (s, &(buf[from]), (count<=len)?count:len);
     OUTPUT:
     RETVAL

int
SSL_use_RSAPrivateKey(s,rsa)
     SSL *              s
     RSA *              rsa

int

SSLeay.xs  view on Meta::CPAN

OPENSSL_init_crypto(uint64_t opts, SV *sv_settings = &PL_sv_undef)
    PREINIT:
	const OPENSSL_INIT_SETTINGS *settings = NULL;
    CODE:
	if (sv_settings != &PL_sv_undef)
	    settings = INT2PTR(OPENSSL_INIT_SETTINGS *, SvIV(sv_settings));
	RETVAL = OPENSSL_init_crypto(opts, settings);
    OUTPUT:
        RETVAL

#endif /* NET_SSLEAY_32BIT_INT_PERL */

#endif /* OpenSSL 1.1.0-pre3 */

#if (OPENSSL_VERSION_NUMBER >= 0x10100003L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x3060000fL) /* OpenSSL 1.1.0-pre3 or LibreSSL 3.6.0 */

void
OPENSSL_cleanup()

#endif /* OpenSSL 1.1.0-pre3 or LibreSSL 3.6.0 */

#if OPENSSL_VERSION_NUMBER >= 0x10100003L && !defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 1.1.0-pre3 */

OPENSSL_INIT_SETTINGS *
OPENSSL_INIT_new()

#endif /* OpenSSL 1.1.0-pre3 */

#if OPENSSL_VERSION_NUMBER >= 0x1010102fL && !defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 1.1.1b */

int
OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *init, const char *filename)

int
OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *init, const char *name)

void
OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *init)

#endif /* OpenSSL 1.1.0-pre3 */

#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 3.0.0-alpha1 */

void
OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *init, unsigned long flags)

#endif /* OpenSSL 3.0.0-alpha1 */

int
SSL_CTX_set_cipher_list(s,str)
     SSL_CTX *              s
     char *             str

void
SSL_get_ciphers(s)
        SSL *              s
    PREINIT:
        STACK_OF(SSL_CIPHER) *sk = NULL;
        const SSL_CIPHER *c;
        int i;
    PPCODE:
        sk = SSL_get_ciphers(s);
        if( sk == NULL ) {
            XSRETURN_EMPTY;
        }
        for (i=0; i<sk_SSL_CIPHER_num(sk); i++) {
            c = sk_SSL_CIPHER_value(sk, i);
            XPUSHs(sv_2mortal(newSViv(PTR2IV(c))));
        }

const char *
SSL_get_cipher_list(s,n)
     SSL *              s
     int                n

int
SSL_set_cipher_list(s,str)
     SSL *              s
     char *       str

const char *
SSL_get_cipher(s)
     SSL *              s

void
SSL_get_shared_ciphers(s,ignored_param1=0,ignored_param2=0)
        SSL *s
        int ignored_param1
        int ignored_param2
    PREINIT:
        char buf[8192];
    CODE:
        ST(0) = sv_newmortal();   /* undef to start with */
        if(SSL_get_shared_ciphers(s, buf, sizeof(buf)))
            sv_setpvn(ST(0), buf, strlen(buf));

X509 *
SSL_get_peer_certificate(s)
     SSL *              s

void
SSL_get_peer_cert_chain(s)
     SSL *              s
    PREINIT:
        STACK_OF(X509) *chain = NULL;
        X509 *x;
	int i;
    PPCODE:
	chain = SSL_get_peer_cert_chain(s);
	if( chain == NULL ) {
	    XSRETURN_EMPTY;
	}
	for (i=0; i<sk_X509_num(chain); i++) {
	    x = sk_X509_value(chain, i);
	    XPUSHs(sv_2mortal(newSViv(PTR2IV(x))));
	}

void
SSL_set_verify(s,mode,callback)
        SSL * s
        int mode
        SV * callback
    CODE:
        if (callback==NULL || !SvOK(callback)) {
            SSL_set_verify(s, mode, NULL);
            cb_data_advanced_put(s, "ssleay_verify_callback!!func", NULL);
        }
        else {
            cb_data_advanced_put(s, "ssleay_verify_callback!!func", newSVsv(callback));
            SSL_set_verify(s, mode, &ssleay_verify_callback_invoke);
        }

void
SSL_set_bio(s,rbio,wbio)
     SSL *              s
     BIO *              rbio
     BIO *              wbio

BIO *
SSL_get_rbio(s)
     SSL *              s

BIO *
SSL_get_wbio(s)
     SSL *              s


SSL_SESSION *
SSL_SESSION_new()

int
SSL_SESSION_print(fp,ses)
     BIO *              fp
     SSL_SESSION *      ses

void
SSL_SESSION_free(ses)
     SSL_SESSION *      ses

#if OPENSSL_VERSION_NUMBER >= 0x10101001L && !defined(LIBRESSL_VERSION_NUMBER)

int
SSL_SESSION_is_resumable(ses)
     SSL_SESSION *      ses

SSL_SESSION *
SSL_SESSION_dup(sess)
     SSL_SESSION * sess

#endif
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 1.1.1 */

void
SSL_set_post_handshake_auth(SSL *ssl, int val)

int
SSL_verify_client_post_handshake(SSL *ssl)

#endif

void
i2d_SSL_SESSION(sess)
	SSL_SESSION * sess
    PREINIT:
	STRLEN len;
	unsigned char *pc,*pi;
    PPCODE:
	if (!(len = i2d_SSL_SESSION(sess,NULL))) croak("invalid SSL_SESSION");
	Newx(pc,len,unsigned char);
	if (!pc) croak("out of memory");
	pi = pc;
	i2d_SSL_SESSION(sess,&pi);
	XPUSHs(sv_2mortal(newSVpv((char*)pc,len)));
	Safefree(pc);


SSL_SESSION *
d2i_SSL_SESSION(pv)
	SV *pv
    CODE:
	RETVAL = NULL;
	if (SvPOK(pv)) {
	    const unsigned char *p;
	    STRLEN len;
	    p = (unsigned char*)SvPV(pv,len);
	    RETVAL = d2i_SSL_SESSION(NULL,&p,len);
	}
    OUTPUT:
	RETVAL

#if (OPENSSL_VERSION_NUMBER >= 0x10100004L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL)

int
SSL_SESSION_up_ref(sess)
     SSL_SESSION * sess

#endif

int
SSL_set_session(to,ses)
     SSL *              to
     SSL_SESSION *      ses

#define REM30 "SSLeay-0.9.0 defines these as macros. I expand them here for safety's sake"

SSL_SESSION *
SSL_get_session(s)
	SSL *              s
	ALIAS:
		SSL_get0_session = 1

SSL_SESSION *
SSL_get1_session(s)
     SSL *              s

X509 *
SSL_get_certificate(s)
     SSL *              s

SSL_CTX *
SSL_get_SSL_CTX(s)
     SSL *              s

#if OPENSSL_VERSION_NUMBER >= 0x0090806fL

SSL_CTX *
SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx)

SSLeay.xs  view on Meta::CPAN

            SSL_set_default_passwd_cb(ssl, &ssleay_ssl_passwd_cb_invoke);
        }

void
SSL_set_default_passwd_cb_userdata(ssl,data=&PL_sv_undef)
        SSL * ssl
        SV * data
    CODE:
        /* SSL_set_default_passwd_cb_userdata is set in SSL_set_default_passwd_cb */
        if (data==NULL || !SvOK(data)) {
            cb_data_advanced_put(ssl, "ssleay_ssl_passwd_cb!!data", NULL);
        }
        else {
            cb_data_advanced_put(ssl, "ssleay_ssl_passwd_cb!!data", newSVsv(data));
        }

#endif /* !LibreSSL */
#endif /* >= 1.1.0f */

#if (OPENSSL_VERSION_NUMBER >= 0x10100001L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x3060000fL)

void
SSL_set_security_level(SSL * ssl, int level)

int
SSL_get_security_level(SSL * ssl)

#endif

#if (OPENSSL_VERSION_NUMBER >= 0x10101007L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x3050000fL)

int
SSL_set_num_tickets(SSL *ssl, size_t num_tickets)

size_t
SSL_get_num_tickets(SSL *ssl)

#endif

#if (OPENSSL_VERSION_NUMBER >= 0x10101003L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x3040000fL)

int
SSL_set_ciphersuites(SSL *ssl, const char *str)

#endif

#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER) /* OpenSSL 1.0.2 */

long
SSL_set1_sigalgs_list(SSL *ssl, const char *str)

long
SSL_set1_client_sigalgs_list(SSL *ssl, const char *str)

void
SSL_get_sigalgs(SSL *ssl, int idx)
    PREINIT:
        int n_sigalgs;
        int psign = NID_undef, phash = NID_undef, psignhash = NID_undef;
        unsigned char rsig = 0, rhash = 0;
    PPCODE:
        n_sigalgs = SSL_get_sigalgs(ssl, idx,
                                    &psign, &phash, &psignhash,
                                    &rsig, &rhash);

        EXTEND(SP, 6);
        PUSHs(sv_2mortal(newSViv(n_sigalgs)));
        PUSHs(sv_2mortal(newSViv(psign)));
        PUSHs(sv_2mortal(newSViv(phash)));
        PUSHs(sv_2mortal(newSViv(psignhash)));
        PUSHs(sv_2mortal(newSVuv(rsig)));
        PUSHs(sv_2mortal(newSVuv(rhash)));

void
SSL_get_shared_sigalgs(SSL *ssl, int idx)
    PREINIT:
        int n_sigalgs;
        int psign = NID_undef, phash = NID_undef, psignhash = NID_undef;
        unsigned char rsig = 0, rhash = 0;
    PPCODE:
        n_sigalgs = SSL_get_shared_sigalgs(ssl, idx,
                                    &psign, &phash, &psignhash,
                                    &rsig, &rhash);

        EXTEND(SP, 6);
        PUSHs(sv_2mortal(newSViv(n_sigalgs)));
        PUSHs(sv_2mortal(newSViv(psign)));
        PUSHs(sv_2mortal(newSViv(phash)));
        PUSHs(sv_2mortal(newSViv(psignhash)));
        PUSHs(sv_2mortal(newSVuv(rsig)));
        PUSHs(sv_2mortal(newSVuv(rhash)));

#endif

const BIO_METHOD *
BIO_f_ssl()

const BIO_METHOD *
BIO_s_mem()

unsigned long
ERR_get_error()

unsigned long
ERR_peek_error()

void
ERR_put_error(lib,func,reason,file,line)
     int                lib
     int                func
     int                reason
     char *             file
     int                line

void
ERR_clear_error()

char *
ERR_error_string(error,buf=NULL)
     unsigned long      error
     char *             buf
     CODE:
     RETVAL = ERR_error_string(error,buf);
     OUTPUT:
     RETVAL

void
SSL_load_error_strings()

void
ERR_load_crypto_strings()

int
SSL_FIPS_mode_set(int onoff)
       CODE:
#ifdef USE_ITHREADS
               MUTEX_LOCK(&LIB_init_mutex);
#endif
#ifdef OPENSSL_FIPS
               RETVAL = FIPS_mode_set(onoff);

SSLeay.xs  view on Meta::CPAN

		X509_CRL_get0_lastUpdate = 1

ASN1_TIME *
X509_CRL_get_nextUpdate(X509_CRL *x)
	  ALIAS:
		X509_CRL_get0_nextUpdate = 1

int
X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm)
	  ALIAS:
		X509_CRL_set1_lastUpdate = 1

int
X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm)
	  ALIAS:
		X509_CRL_set1_nextUpdate = 1

#endif

int
X509_CRL_verify(X509_CRL *a, EVP_PKEY *r)

int
X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)

int
P_X509_CRL_set_serial(crl,crl_number)
        X509_CRL *crl
        ASN1_INTEGER * crl_number;
    CODE:
        RETVAL = 0;
        if (crl && crl_number)
            if (X509_CRL_add1_ext_i2d(crl, NID_crl_number, crl_number, 0, 0)) RETVAL = 1;
    OUTPUT:
        RETVAL

ASN1_INTEGER *
P_X509_CRL_get_serial(crl)
        X509_CRL *crl
    INIT:
        int i;
    CODE:
        RETVAL = (ASN1_INTEGER *)X509_CRL_get_ext_d2i(crl, NID_crl_number, &i, NULL);
        if (!RETVAL || i==-1) XSRETURN_UNDEF;
    OUTPUT:
        RETVAL

void
P_X509_CRL_add_revoked_serial_hex(crl,serial_hex,rev_time,reason_code=0,comp_time=NULL)
        X509_CRL *crl
        char * serial_hex
        ASN1_TIME *rev_time
        long reason_code
        ASN1_TIME *comp_time
    PREINIT:
        BIGNUM *bn = NULL;
        ASN1_INTEGER *sn;
        X509_REVOKED *rev;
        ASN1_ENUMERATED *rsn = NULL;
        int rv;
    PPCODE:
        rv=0;
        rev = X509_REVOKED_new();
        if (rev) {
            if (BN_hex2bn(&bn, serial_hex)) {
                sn = BN_to_ASN1_INTEGER(bn, NULL);
                if (sn) {
                    X509_REVOKED_set_serialNumber(rev, sn);
                    ASN1_INTEGER_free(sn);
                    rv = 1;
                }
                BN_free(bn);
            }
        }
        if (!rv) XSRETURN_IV(0);

        if (!rev_time) XSRETURN_IV(0);
        if (!X509_REVOKED_set_revocationDate(rev, rev_time)) XSRETURN_IV(0);

        if(reason_code) {
            rv = 0;
            rsn = ASN1_ENUMERATED_new();
            if (rsn) {
                if (ASN1_ENUMERATED_set(rsn, reason_code))
                    if (X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rsn, 0, 0))
                        rv=1;
                ASN1_ENUMERATED_free(rsn);
            }
            if (!rv) XSRETURN_IV(0);
        }

        if(comp_time) {
            X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0);
        }

        if(!X509_CRL_add0_revoked(crl, rev)) XSRETURN_IV(0);
        XSRETURN_IV(1);

X509_REQ *
X509_REQ_new()

void
X509_REQ_free(X509_REQ *x)

X509_NAME *
X509_REQ_get_subject_name(X509_REQ *x)

int
X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)

int
X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)

EVP_PKEY *
X509_REQ_get_pubkey(X509_REQ *x)

int
X509_REQ_sign(X509_REQ *x, EVP_PKEY *pk, const EVP_MD *md)

int
X509_REQ_verify(X509_REQ *x, EVP_PKEY *r)

int
X509_REQ_set_version(X509_REQ *x, long version)

long
X509_REQ_get_version(X509_REQ *x)

int
X509_REQ_get_attr_count(const X509_REQ *req);

int
X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos=-1)

int
X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, int lastpos=-1)

int
X509_REQ_add1_attr_by_NID(req,nid,type,bytes)
        X509_REQ *req
        int nid
        int type
    PREINIT:
        STRLEN len;
    INPUT:
        unsigned char *bytes = (unsigned char *)SvPV(ST(3), len);
    CODE:
        RETVAL = X509_REQ_add1_attr_by_NID(req,nid,type,bytes,len);
    OUTPUT:
        RETVAL

void
P_X509_REQ_get_attr(req,n)
        X509_REQ *req
        int n
    INIT:
        X509_ATTRIBUTE * att;
        int count, i;
        ASN1_STRING * s;
	ASN1_TYPE * t;
    PPCODE:
        att = X509_REQ_get_attr(req,n);
	count = X509_ATTRIBUTE_count(att);
	for (i=0; i<count; i++) {
	    t = X509_ATTRIBUTE_get0_type(att, i);
	    s = t->value.asn1_string;
            XPUSHs(sv_2mortal(newSViv(PTR2IV(s))));
	}

int
P_X509_REQ_add_extensions(x,...)
        X509_REQ *x
    PREINIT:
        int i=1;
        int nid;
        char *data;
        X509_EXTENSION *ex;
        STACK_OF(X509_EXTENSION) *stack;
    CODE:
        if (items>1) {
            RETVAL = 1;
            stack = sk_X509_EXTENSION_new_null();
            while(i+1<items) {
                nid = SvIV(ST(i));
                data = SvPV_nolen(ST(i+1));
                i+=2;
                ex = X509V3_EXT_conf_nid(NULL, NULL, nid, data);
                if (ex)
                    sk_X509_EXTENSION_push(stack, ex);
                else
                    RETVAL = 0;
            }
            X509_REQ_add_extensions(x, stack);
            sk_X509_EXTENSION_pop_free(stack, X509_EXTENSION_free);
        }
        else
            RETVAL = 0;
    OUTPUT:
        RETVAL

int
P_X509_add_extensions(x,ca_cert,...)
        X509 *x
        X509 *ca_cert
    PREINIT:
        int i=2;
        int nid;
        char *data;
        X509_EXTENSION *ex;
        X509V3_CTX ctx;
    CODE:
        if (items>1) {
            RETVAL = 1;
            while(i+1<items) {
                nid = SvIV(ST(i));
                data = SvPV_nolen(ST(i+1));
                i+=2;
                X509V3_set_ctx(&ctx, ca_cert, x, NULL, NULL, 0);
                ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, data);
                if (ex) {
                    X509_add_ext(x,ex,-1);
                    X509_EXTENSION_free(ex);
                }
                else {
                    warn("failure during X509V3_EXT_conf_nid() for nid=%d\n", nid);
                    ERR_print_errors_fp(stderr);
                    RETVAL = 0;
                }
            }
        }
        else
            RETVAL = 0;
    OUTPUT:
            RETVAL

int
P_X509_CRL_add_extensions(x,ca_cert,...)
        X509_CRL *x
        X509 *ca_cert
    PREINIT:
        int i=2;
        int nid;
        char *data;
        X509_EXTENSION *ex;
        X509V3_CTX ctx;
    CODE:
        if (items>1) {
            RETVAL = 1;
            while(i+1<items) {
                nid = SvIV(ST(i));
                data = SvPV_nolen(ST(i+1));
                i+=2;
                X509V3_set_ctx(&ctx, ca_cert, NULL, NULL, x, 0);
                ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, data);
                if (ex) {
                    X509_CRL_add_ext(x,ex,-1);
                    X509_EXTENSION_free(ex);
                }
                else {
                    warn("failure during X509V3_EXT_conf_nid() for nid=%d\n", nid);
                    ERR_print_errors_fp(stderr);
                    RETVAL = 0;
                }
            }
        }
        else
            RETVAL = 0;
    OUTPUT:
            RETVAL

void
P_X509_copy_extensions(x509_req,x509,override=1)
        X509_REQ *x509_req
        X509 *x509
        int override
    PREINIT:
        STACK_OF(X509_EXTENSION) *exts = NULL;
        X509_EXTENSION *ext, *tmpext;
        ASN1_OBJECT *obj;
        int i, idx, ret = 1;
    PPCODE:
        if (!x509 || !x509_req) XSRETURN_IV(0);
        exts = X509_REQ_get_extensions(x509_req);
        for(i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
            ext = sk_X509_EXTENSION_value(exts, i);
            obj = X509_EXTENSION_get_object(ext);
            idx = X509_get_ext_by_OBJ(x509, obj, -1);
            /* Does extension exist? */
            if (idx != -1) {
                if (override) continue; /* don't override existing extension */
                /* Delete all extensions of same type */
                do {
                    tmpext = X509_get_ext(x509, idx);
                    X509_delete_ext(x509, idx);
                    X509_EXTENSION_free(tmpext);
                    idx = X509_get_ext_by_OBJ(x509, obj, -1);
                } while (idx != -1);
            }
            if (!X509_add_ext(x509, ext, -1)) ret = 0;
        }
        sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
        XSRETURN_IV(ret);

X509 *
X509_STORE_CTX_get_current_cert(x509_store_ctx)
     X509_STORE_CTX * 	x509_store_ctx

#if (OPENSSL_VERSION_NUMBER >= 0x10100005L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL) /* OpenSSL 1.1.0-pre5, LibreSSL 2.7.0 */

X509 *
X509_STORE_CTX_get0_cert(x509_store_ctx)
    X509_STORE_CTX *x509_store_ctx

#endif

STACK_OF(X509) *
X509_STORE_CTX_get1_chain(x509_store_ctx)
    X509_STORE_CTX *x509_store_ctx


int
X509_STORE_CTX_get_ex_new_index(argl,argp=NULL,new_func=NULL,dup_func=NULL,free_func=NULL)
     long argl
     void *  argp
     CRYPTO_EX_new *   new_func
     CRYPTO_EX_dup *   dup_func
     CRYPTO_EX_free *  free_func

void *
X509_STORE_CTX_get_ex_data(x509_store_ctx,idx)
     X509_STORE_CTX * x509_store_ctx
     int idx

void *
X509_STORE_CTX_get_app_data(x509_store_ctx)
     X509_STORE_CTX *  x509_store_ctx
  CODE:
  RETVAL = X509_STORE_CTX_get_ex_data(x509_store_ctx,0);
  OUTPUT:
  RETVAL

void
X509_get_fingerprint(cert,type)
		X509 * 	cert
		char *	type
	PREINIT:
		const EVP_MD *digest_tp = NULL;
		unsigned char digest[EVP_MAX_MD_SIZE];
		unsigned int dsz, k = 0;
		char text[EVP_MAX_MD_SIZE * 3 + 1];
	CODE:
#ifndef OPENSSL_NO_MD5
		if (!k && !strcmp(type,"md5")) {
		 	k = 1; digest_tp = EVP_md5();
		}
#endif
		if (!k && !strcmp(type,"sha1")) {
			k = 1; digest_tp = EVP_sha1();
		}
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_SHA256
		if (!k && !strcmp(type,"sha256")) {
			k = 1; digest_tp = EVP_sha256();
		}
#endif
#endif
		if (!k && !strcmp(type,"ripemd160")) {
			k = 1; digest_tp = EVP_ripemd160();
		}
		if (!k)	/* Default digest */
			digest_tp = EVP_sha1();
		if ( digest_tp == NULL ) {
			/* Out of memory */
			XSRETURN_UNDEF;
		}
		if (!X509_digest(cert, digest_tp, digest, &dsz)) {
			/* Out of memory */
			XSRETURN_UNDEF;
		}
		text[0] = '\0';
		for(k=0; k<dsz; k++) {
			sprintf(&text[strlen(text)], "%02X:", digest[k]);
		}
		text[strlen(text)-1] = '\0';
		ST(0) = sv_newmortal();   /* Undefined to start with */
		sv_setpvn( ST(0), text, strlen(text));

void
X509_get_subjectAltNames(cert)
	X509 *      cert
	PREINIT:
	int                    i, j, count = 0;
	X509_EXTENSION         *subjAltNameExt = NULL;
	STACK_OF(GENERAL_NAME) *subjAltNameDNs = NULL;
	GENERAL_NAME           *subjAltNameDN  = NULL;
	int                    num_gnames;
	PPCODE:
	if (  (i = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)) >= 0
		&& (subjAltNameExt = X509_get_ext(cert, i))
		&& (subjAltNameDNs = (STACK_OF(GENERAL_NAME) *)X509V3_EXT_d2i(subjAltNameExt)))
	{
		num_gnames = sk_GENERAL_NAME_num(subjAltNameDNs);

		for (j = 0; j < num_gnames; j++)
                {
		     subjAltNameDN = sk_GENERAL_NAME_value(subjAltNameDNs, j);

                     switch (subjAltNameDN->type)
                     {
                     case GEN_OTHERNAME:
                         EXTEND(SP, 2);
                         count++;
                         PUSHs(sv_2mortal(newSViv(subjAltNameDN->type)));
#if (OPENSSL_VERSION_NUMBER >= 0x1010000f && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL)
                         PUSHs(sv_2mortal(newSVpv((const char*)ASN1_STRING_get0_data(subjAltNameDN->d.otherName->value->value.utf8string), ASN1_STRING_length(subjAltNameDN->d.otherName->value->value.utf8string))));
#else
                         PUSHs(sv_2mortal(newSVpv((const char*)ASN1_STRING_data(subjAltNameDN->d.otherName->value->value.utf8string), ASN1_STRING_length(subjAltNameDN->d.otherName->value->value.utf8string))));
#endif
                         break;

                     case GEN_EMAIL:
                     case GEN_DNS:
                     case GEN_URI:
                         EXTEND(SP, 2);
                         count++;
                         PUSHs(sv_2mortal(newSViv(subjAltNameDN->type)));
#if (OPENSSL_VERSION_NUMBER >= 0x1010000f && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL)
                         PUSHs(sv_2mortal(newSVpv((const char*)ASN1_STRING_get0_data(subjAltNameDN->d.ia5), ASN1_STRING_length(subjAltNameDN->d.ia5))));
#else
                         PUSHs(sv_2mortal(newSVpv((const char*)ASN1_STRING_data(subjAltNameDN->d.ia5), ASN1_STRING_length(subjAltNameDN->d.ia5))));
#endif
                         break;

                     case GEN_DIRNAME:
                         {
                         char * buf = X509_NAME_oneline(subjAltNameDN->d.dirn, NULL, 0);
                         EXTEND(SP, 2);
                         count++;
                         PUSHs(sv_2mortal(newSViv(subjAltNameDN->type)));
                         PUSHs(sv_2mortal(newSVpv((buf), strlen((buf)))));
                         }
                         break;

                     case GEN_RID:
                         {
			 char buf[2501]; /* Much more than what's suggested on OBJ_obj2txt manual page */
                         int len = OBJ_obj2txt(buf, sizeof(buf), subjAltNameDN->d.rid, 1);
			 if (len < 0 || len > (int)((sizeof(buf) - 1)))
			   break; /* Skip bad or overly long RID */
                         EXTEND(SP, 2);
                         count++;
                         PUSHs(sv_2mortal(newSViv(subjAltNameDN->type)));
                         PUSHs(sv_2mortal(newSVpv(buf, 0)));
                         }
                         break;

                     case GEN_IPADD:
                         EXTEND(SP, 2);
                         count++;
                         PUSHs(sv_2mortal(newSViv(subjAltNameDN->type)));
                         PUSHs(sv_2mortal(newSVpv((const char*)subjAltNameDN->d.ip->data, subjAltNameDN->d.ip->length)));
                         break;

                     }
		}
		sk_GENERAL_NAME_pop_free(subjAltNameDNs, GENERAL_NAME_free);
	}
	XSRETURN(count * 2);

void
P_X509_get_crl_distribution_points(cert)
        X509 * cert
    INIT:
        GENERAL_NAMES *gnames;
        GENERAL_NAME *gn;
        STACK_OF(DIST_POINT) *points;
        DIST_POINT *p;
        int i, j;
    PPCODE:
        points = (STACK_OF(DIST_POINT) *)X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL);
        for (i = 0; i < sk_DIST_POINT_num(points); i++) {
            p = sk_DIST_POINT_value(points, i);
            if (!p->distpoint)
                continue;
            if (p->distpoint->type == 0) {
                /* full name */
                gnames = p->distpoint->name.fullname;
                for (j = 0; j < sk_GENERAL_NAME_num(gnames); j++) {
                    gn = sk_GENERAL_NAME_value(gnames, j);

                    if (gn->type == GEN_URI) {
#if (OPENSSL_VERSION_NUMBER >= 0x1010000f && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL)
                        XPUSHs(sv_2mortal(newSVpv((char*)ASN1_STRING_get0_data(gn->d.ia5),ASN1_STRING_length(gn->d.ia5))));
#else
                        XPUSHs(sv_2mortal(newSVpv((char*)ASN1_STRING_data(gn->d.ia5),ASN1_STRING_length(gn->d.ia5))));
#endif
                    }
                }
            }
            else {
                /* relative name - not supported */
                /* XXX-TODO: the code below is just an idea; do not enable it without proper test case
                BIO *bp;
                char *buf;
                int n;
                X509_NAME ntmp;
                ntmp.entries = p->distpoint->name.relativename;
                bp = BIO_new(BIO_s_mem());
                if (bp) {
                    X509_NAME_print_ex(bp, &ntmp, 0, XN_FLAG_RFC2253);
                    n = BIO_ctrl_pending(bp);
                    New(0, buf, n, char);
                    if (buf) {
                        j = BIO_read(bp,buf,n);
                        if (j>=0 && j<=n) XPUSHs(sv_2mortal(newSVpvn(buf,j)));
                        Safefree(buf);
                    }
                    BIO_free(bp);
                }
                */
            }
        }
        sk_DIST_POINT_pop_free(points, DIST_POINT_free);

void
P_X509_get_ocsp_uri(cert)
	X509 * cert
	PREINIT:
	AUTHORITY_INFO_ACCESS *info;
	int i;
    PPCODE:
	info = (AUTHORITY_INFO_ACCESS *)X509_get_ext_d2i(cert, NID_info_access, NULL, NULL);
	if (!info) XSRETURN_UNDEF;

	for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
	    ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
	    if (OBJ_obj2nid(ad->method) == NID_ad_OCSP
		&& ad->location->type == GEN_URI) {
#if (OPENSSL_VERSION_NUMBER >= 0x1010000f && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL)
		XPUSHs(sv_2mortal(newSVpv(
		    (char*)ASN1_STRING_get0_data(ad->location->d.uniformResourceIdentifier),
		    ASN1_STRING_length(ad->location->d.uniformResourceIdentifier)
		)));
#else
		XPUSHs(sv_2mortal(newSVpv(
		    (char*)ASN1_STRING_data(ad->location->d.uniformResourceIdentifier),
		    ASN1_STRING_length(ad->location->d.uniformResourceIdentifier)
		)));
#endif
		if (GIMME_V == G_SCALAR) break; /* get only first */
	    }
	}
	AUTHORITY_INFO_ACCESS_free(info);


void
P_X509_get_ext_key_usage(cert,format=0)
        X509 * cert
        int format
    PREINIT:
        EXTENDED_KEY_USAGE *extusage;
        int i, nid;
        char buffer[100]; /* openssl doc: a buffer length of 80 should be more than enough to handle any OID encountered in practice */
        ASN1_OBJECT *o;
    PPCODE:
        extusage = (EXTENDED_KEY_USAGE *)X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL);
        for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
           o = sk_ASN1_OBJECT_value(extusage,i);
           nid = OBJ_obj2nid(o);
           OBJ_obj2txt(buffer, sizeof(buffer)-1, o, 1);
           if(format==0)
               XPUSHs(sv_2mortal(newSVpv(buffer,0)));          /* format 0: oid */
           else if(format==1 && nid>0)
               XPUSHs(sv_2mortal(newSViv(nid)));               /* format 1: nid */
           else if(format==2 && nid>0)
               XPUSHs(sv_2mortal(newSVpv(OBJ_nid2sn(nid),0))); /* format 2: shortname */
           else if(format==3 && nid>0)
               XPUSHs(sv_2mortal(newSVpv(OBJ_nid2ln(nid),0))); /* format 3: longname */
        }
        EXTENDED_KEY_USAGE_free(extusage);

void
P_X509_get_key_usage(cert)
        X509 * cert
    INIT:
        ASN1_BIT_STRING * u;
    PPCODE:
        u = (ASN1_BIT_STRING *)X509_get_ext_d2i(cert, NID_key_usage, NULL, NULL);
        if (u) {
            if (ASN1_BIT_STRING_get_bit(u,0)) XPUSHs(sv_2mortal(newSVpv("digitalSignature",0)));
            if (ASN1_BIT_STRING_get_bit(u,1)) XPUSHs(sv_2mortal(newSVpv("nonRepudiation",0)));
            if (ASN1_BIT_STRING_get_bit(u,2)) XPUSHs(sv_2mortal(newSVpv("keyEncipherment",0)));
            if (ASN1_BIT_STRING_get_bit(u,3)) XPUSHs(sv_2mortal(newSVpv("dataEncipherment",0)));
            if (ASN1_BIT_STRING_get_bit(u,4)) XPUSHs(sv_2mortal(newSVpv("keyAgreement",0)));
            if (ASN1_BIT_STRING_get_bit(u,5)) XPUSHs(sv_2mortal(newSVpv("keyCertSign",0)));
            if (ASN1_BIT_STRING_get_bit(u,6)) XPUSHs(sv_2mortal(newSVpv("cRLSign",0)));
            if (ASN1_BIT_STRING_get_bit(u,7)) XPUSHs(sv_2mortal(newSVpv("encipherOnly",0)));
            if (ASN1_BIT_STRING_get_bit(u,8)) XPUSHs(sv_2mortal(newSVpv("decipherOnly",0)));
            ASN1_BIT_STRING_free(u);
        }

void
P_X509_get_netscape_cert_type(cert)
        X509 * cert
    INIT:
        ASN1_BIT_STRING * u;
    PPCODE:
        u = (ASN1_BIT_STRING *)X509_get_ext_d2i(cert, NID_netscape_cert_type, NULL, NULL);
        if (u) {
            if (ASN1_BIT_STRING_get_bit(u,0)) XPUSHs(sv_2mortal(newSVpv("client",0)));
            if (ASN1_BIT_STRING_get_bit(u,1)) XPUSHs(sv_2mortal(newSVpv("server",0)));
            if (ASN1_BIT_STRING_get_bit(u,2)) XPUSHs(sv_2mortal(newSVpv("email",0)));
            if (ASN1_BIT_STRING_get_bit(u,3)) XPUSHs(sv_2mortal(newSVpv("objsign",0)));
            if (ASN1_BIT_STRING_get_bit(u,4)) XPUSHs(sv_2mortal(newSVpv("reserved",0)));
            if (ASN1_BIT_STRING_get_bit(u,5)) XPUSHs(sv_2mortal(newSVpv("sslCA",0)));
            if (ASN1_BIT_STRING_get_bit(u,6)) XPUSHs(sv_2mortal(newSVpv("emailCA",0)));
            if (ASN1_BIT_STRING_get_bit(u,7)) XPUSHs(sv_2mortal(newSVpv("objCA",0)));
            ASN1_BIT_STRING_free(u);
        }

int
X509_get_ext_by_NID(x,nid,loc=-1)
	X509* x
	int nid
	int loc

X509_EXTENSION *
X509_get_ext(x,loc)
	X509* x
	int loc

int
X509_EXTENSION_get_critical(X509_EXTENSION *ex)

ASN1_OCTET_STRING *
X509_EXTENSION_get_data(X509_EXTENSION *ne)

ASN1_OBJECT *
X509_EXTENSION_get_object(X509_EXTENSION *ex)

int
X509_get_ext_count(X509 *x)

int
X509_CRL_get_ext_count(X509_CRL *x)

int
X509_CRL_get_ext_by_NID(x,ni,loc=-1)
        X509_CRL* x
        int ni
        int loc

X509_EXTENSION *
X509_CRL_get_ext(x,loc)
   X509_CRL* x
   int loc

void
X509V3_EXT_print(ext,flags=0,utf8_decode=0)
        X509_EXTENSION * ext
        unsigned long flags
        int utf8_decode
    PREINIT:
        BIO * bp;
        char * buf;
        int i, n;
        int indent=0;

SSLeay.xs  view on Meta::CPAN

    X509_STORE *ctx
    int trust

int
X509_STORE_set1_param(ctx, pm)
    X509_STORE *ctx
    X509_VERIFY_PARAM *pm

#endif

X509_LOOKUP_METHOD *
X509_LOOKUP_hash_dir()

void
X509_LOOKUP_add_dir(lookup, dir, type)
    X509_LOOKUP * lookup
    char * dir
    int type

int
X509_load_cert_file(ctx, file, type)
    X509_LOOKUP *ctx
    char *file
    int type

int
X509_load_crl_file(ctx, file, type)
    X509_LOOKUP *ctx
    char *file
    int type

int
X509_load_cert_crl_file(ctx, file, type)
    X509_LOOKUP *ctx
    char *file
    int type

const char *
X509_verify_cert_error_string(n)
    long n

ASN1_INTEGER *
ASN1_INTEGER_new()

void
ASN1_INTEGER_free(ASN1_INTEGER *i)

int
ASN1_INTEGER_set(ASN1_INTEGER *i, long val)

long
ASN1_INTEGER_get(ASN1_INTEGER *a)

void
P_ASN1_INTEGER_set_hex(i,str)
        ASN1_INTEGER * i
        char * str
    INIT:
        BIGNUM *bn;
        int rv = 1;
    PPCODE:
        bn = BN_new();
        if (!BN_hex2bn(&bn, str)) XSRETURN_IV(0);
        if (!BN_to_ASN1_INTEGER(bn, i)) rv = 0;
        BN_free(bn);
        XSRETURN_IV(rv);

void
P_ASN1_INTEGER_set_dec(i,str)
        ASN1_INTEGER * i
        char * str
    INIT:
        BIGNUM *bn;
        int rv = 1;
    PPCODE:
        bn = BN_new();
        if (!BN_dec2bn(&bn, str)) XSRETURN_IV(0);
        if (!BN_to_ASN1_INTEGER(bn, i)) rv = 0;
        BN_free(bn);
        XSRETURN_IV(rv);

void
P_ASN1_INTEGER_get_hex(i)
        ASN1_INTEGER * i
    INIT:
        BIGNUM *bn;
        char *result;
    PPCODE:
        bn = BN_new();
        if (!bn) XSRETURN_UNDEF;
        ASN1_INTEGER_to_BN(i, bn);
        result = BN_bn2hex(bn);
        BN_free(bn);
        if (!result) XSRETURN_UNDEF;
        XPUSHs(sv_2mortal(newSVpv((const char*)result, strlen(result))));
        OPENSSL_free(result);

void
P_ASN1_INTEGER_get_dec(i)
        ASN1_INTEGER * i
    INIT:
        BIGNUM *bn;
        char *result;
    PPCODE:
        bn = BN_new();
        if (!bn) XSRETURN_UNDEF;
        ASN1_INTEGER_to_BN(i, bn);
        result = BN_bn2dec(bn);
        BN_free(bn);
        if (!result) XSRETURN_UNDEF;
        XPUSHs(sv_2mortal(newSVpv((const char*)result, strlen(result))));
        OPENSSL_free(result);

void
P_ASN1_STRING_get(s,utf8_decode=0)
        ASN1_STRING * s
        int utf8_decode
    PREINIT:
        SV * u8;
    PPCODE:
#if (OPENSSL_VERSION_NUMBER >= 0x1010000f && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL)
        u8 = newSVpv((const char*)ASN1_STRING_get0_data(s), ASN1_STRING_length(s));
#else
        u8 = newSVpv((const char*)ASN1_STRING_data(s), ASN1_STRING_length(s));
#endif
        if (utf8_decode) sv_utf8_decode(u8);
        XPUSHs(sv_2mortal(u8));

#if (OPENSSL_VERSION_NUMBER >= 0x1010000f && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL)

const ASN1_TIME *
X509_get0_notBefore(const X509 *cert)

const ASN1_TIME *
X509_get0_notAfter(const X509 *cert)

ASN1_TIME *
X509_getm_notBefore(const X509 *cert)
	ALIAS:
		X509_get_notBefore = 1

ASN1_TIME *
X509_getm_notAfter(const X509 *cert)
	ALIAS:
		X509_get_notAfter = 1

#else /* plain get_ is deprecated */

ASN1_TIME *
X509_get_notBefore(X509 *cert)
	ALIAS:
		X509_get0_notBefore = 1
		X509_getm_notBefore = 2

ASN1_TIME *
X509_get_notAfter(X509 *cert)
	ALIAS:
		X509_get0_notAfter = 1
		X509_getm_notAfter = 2

#endif

ASN1_TIME *
X509_gmtime_adj(s, adj)
     ASN1_TIME * s
     long adj

ASN1_TIME *
ASN1_TIME_set(s,t)
     ASN1_TIME *s
     time_t t

void
ASN1_TIME_free(s)
     ASN1_TIME *s

time_t
ASN1_TIME_timet(s)
     ASN1_TIME *s
     CODE:

SSLeay.xs  view on Meta::CPAN

                /* unencrypted key */
                PEM_write_bio_PrivateKey(bp,pk,NULL,(unsigned char *)passwd,passwd_len,cb,u);
            }
            n = BIO_ctrl_pending(bp);
            New(0, buf, n, char);
            if (buf) {
                i = BIO_read(bp,buf,n);
                if (i>=0 && i<=n) sv_setpvn(ST(0), buf, i);
                Safefree(buf);
            }
            BIO_free(bp);
        }

int
CTX_use_PKCS12_file(ctx, file, password=NULL)
        SSL_CTX *ctx
        char *file
        char *password
    PREINIT:
        PKCS12 *p12;
        EVP_PKEY *private_key;
        X509 *certificate;
        BIO *bio;
    CODE:
        RETVAL = 0;
        bio = BIO_new_file(file, "rb");
        if (bio) {
            OPENSSL_add_all_algorithms_noconf();
            if ((p12 = d2i_PKCS12_bio(bio, NULL))) {
                if (PKCS12_parse(p12, password, &private_key, &certificate, NULL)) {
                    if (private_key) {
                        if (SSL_CTX_use_PrivateKey(ctx, private_key)) RETVAL = 1;
                        EVP_PKEY_free(private_key);
                    }
                    if (certificate) {
                        if (SSL_CTX_use_certificate(ctx, certificate)) RETVAL = 1;
                        X509_free(certificate);
                    }
                }
                PKCS12_free(p12);
            }
            if (!RETVAL) ERR_print_errors_fp(stderr);
            BIO_free(bio);
        }
    OUTPUT:
        RETVAL

void
P_PKCS12_load_file(file, load_chain=0, password=NULL)
        char *file
        int load_chain
        char *password
    PREINIT:
        PKCS12 *p12;
        EVP_PKEY *private_key = NULL;
        X509 *certificate = NULL;
        STACK_OF(X509) *cachain = NULL;
        X509 *x;
        BIO *bio;
        int i, result;
    PPCODE:
        bio = BIO_new_file(file, "rb");
        if (bio) {
            OPENSSL_add_all_algorithms_noconf();
            if ((p12 = d2i_PKCS12_bio(bio, NULL))) {
                if(load_chain)
                    result= PKCS12_parse(p12, password, &private_key, &certificate, &cachain);
                else
                    result= PKCS12_parse(p12, password, &private_key, &certificate, NULL);
                if (result) {
                    if (private_key)
                        XPUSHs(sv_2mortal(newSViv(PTR2IV(private_key))));
                    else
                        XPUSHs(sv_2mortal(newSVpv(NULL,0))); /* undef */
                    if (certificate)
                        XPUSHs(sv_2mortal(newSViv(PTR2IV(certificate))));
                    else
                        XPUSHs(sv_2mortal(newSVpv(NULL,0))); /* undef */
                    if (cachain) {
                        for (i=0; i<sk_X509_num(cachain); i++) {
                            x = sk_X509_value(cachain, i);
                            XPUSHs(sv_2mortal(newSViv(PTR2IV(x))));
                        }
                        sk_X509_free(cachain);
                    }
                }
                PKCS12_free(p12);
            }
            BIO_free(bio);
        }

#ifndef OPENSSL_NO_MD2

void
MD2(data)
	PREINIT:
	STRLEN len;
	unsigned char md[MD2_DIGEST_LENGTH];
	unsigned char * ret;
	INPUT:
	unsigned char* data = (unsigned char *) SvPV( ST(0), len);
	CODE:
	ret = MD2(data,len,md);
	if (ret!=NULL) {
		XSRETURN_PVN((char *) md, MD2_DIGEST_LENGTH);
	} else {
		XSRETURN_UNDEF;
	}

#endif

#ifndef OPENSSL_NO_MD4

void
MD4(data)
	PREINIT:
	STRLEN len;
	unsigned char md[MD4_DIGEST_LENGTH];
	INPUT:
	unsigned char* data = (unsigned char *) SvPV( ST(0), len );
	CODE:

SSLeay.xs  view on Meta::CPAN


int
BIO_eof(s)
     BIO *   s

int
BIO_pending(s)
     BIO *   s

int
BIO_wpending(s)
     BIO *   s

int
BIO_ssl_copy_session_id(to,from)
     BIO *	to
     BIO *	from

void
BIO_ssl_shutdown(ssl_bio)
     BIO *	ssl_bio

int
SSL_add_client_CA(ssl,x)
     SSL *	ssl
     X509 *	x

const char *
SSL_alert_desc_string(value)
     int 	value

const char *
SSL_alert_desc_string_long(value)
     int 	value

const char *
SSL_alert_type_string(value)
     int 	value

const char *
SSL_alert_type_string_long(value)
     int 	value

long
SSL_callback_ctrl(ssl,i,fp)
     SSL *  ssl
     int    i
     callback_no_ret * fp

int
SSL_check_private_key(ctx)
     SSL *	ctx

# /* buf and size were required with Net::SSLeay 1.88 and earlier. */
# /* With OpenSSL 0.9.8l and older compile can warn about discarded const. */
void
SSL_CIPHER_description(const SSL_CIPHER *cipher, char *unused_buf=NULL, int unused_size=0)
    PREINIT:
        char *description;
        char buf[512];
    PPCODE:
        description = SSL_CIPHER_description(cipher, buf, sizeof(buf));
        if(description == NULL) {
            XSRETURN_EMPTY;
        }
        XPUSHs(sv_2mortal(newSVpv(description, 0)));

const char *
SSL_CIPHER_get_name(const SSL_CIPHER *c)

int
SSL_CIPHER_get_bits(c, ...)
        const SSL_CIPHER *      c
    CODE:
        int alg_bits;
        RETVAL = SSL_CIPHER_get_bits(c, &alg_bits);
        if (items > 2) croak("SSL_CIPHER_get_bits: Need to call with one or two parameters");
        if (items > 1) sv_setsv(ST(1), sv_2mortal(newSViv(alg_bits)));
    OUTPUT:
        RETVAL

const char *
SSL_CIPHER_get_version(const SSL_CIPHER *cipher)

#if OPENSSL_VERSION_NUMBER >= 0x10101001L && !defined(LIBRESSL_VERSION_NUMBER)

const EVP_MD *
SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c)

#endif /* OpenSSL 1.1.1-pre1 */

#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x3040000fL) /* LibreSSL >= 3.4.0 */

const SSL_CIPHER *
SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)

#endif

#ifndef OPENSSL_NO_COMP

int
SSL_COMP_add_compression_method(id,cm)
     int 	id
     COMP_METHOD *	cm

#endif

int
SSL_CTX_add_client_CA(ctx,x)
     SSL_CTX *	ctx
     X509 *	x

long
SSL_CTX_callback_ctrl(ctx,i,fp)
     SSL_CTX *  ctx
     int        i
     callback_no_ret * fp

int
SSL_CTX_check_private_key(ctx)
     SSL_CTX *	ctx

SSLeay.xs  view on Meta::CPAN

	    cb_data_advanced_put(ctx, "ssleay_ssl_ctx_client_hello_cb!!arg", newSVsv(arg));
	    SSL_CTX_set_client_hello_cb(ctx, ssl_client_hello_cb_fn_invoke, NULL);
	}

int
SSL_client_hello_isv2(SSL *s)

unsigned int
SSL_client_hello_get0_legacy_version(SSL *s)

void
SSL_client_hello_get0_random(SSL *s)
    PREINIT:
	const unsigned char *out = NULL;
	size_t outlen;
    CODE:
	outlen = SSL_client_hello_get0_random(s, &out);
	if (outlen == 0) XSRETURN_PV("");
	ST(0) = sv_newmortal();
	sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);

void
SSL_client_hello_get0_session_id(SSL *s)
    PREINIT:
	const unsigned char *out = NULL;
	size_t outlen;
    CODE:
	outlen = SSL_client_hello_get0_session_id(s, &out);
	if (outlen == 0) XSRETURN_PV("");
	ST(0) = sv_newmortal();
	sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);

void
SSL_client_hello_get0_ciphers(SSL *s)
    PREINIT:
	const unsigned char *out = NULL;
	size_t outlen;
    CODE:
	outlen = SSL_client_hello_get0_ciphers(s, &out);
	if (outlen == 0) XSRETURN_PV("");
	ST(0) = sv_newmortal();
	sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);

void
SSL_client_hello_get0_compression_methods(SSL *s)
    PREINIT:
	const unsigned char *out = NULL;
	size_t outlen;
    CODE:
	outlen = SSL_client_hello_get0_compression_methods(s, &out);
	if (outlen == 0) XSRETURN_PV("");
	ST(0) = sv_newmortal();
	sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);

void
SSL_client_hello_get1_extensions_present(SSL *s)
    PREINIT:
	int ret, *out = NULL, i;
	size_t outlen;
	AV *av;
    PPCODE:
	ret = SSL_client_hello_get1_extensions_present(s, &out, &outlen);
	if (ret != 1) XSRETURN_UNDEF;

	av = newAV();
	mXPUSHs(newRV_noinc((SV*)av));
	for (i=0; i < outlen; i++) {
	    av_push(av, newSViv(*(out + i)));
	}
	OPENSSL_free(out);

#if OPENSSL_VERSION_NUMBER >= 0x30200000L && !defined(LIBRESSL_VERSION_NUMBER)

void
SSL_client_hello_get_extension_order(SSL *s)
    PREINIT:
	int ret, i;
	uint16_t *exts;
	size_t num_exts;
	AV *av;
    PPCODE:
	ret = SSL_client_hello_get_extension_order(s, NULL, &num_exts);
	if (ret != 1) XSRETURN_UNDEF;

	Newx(exts, num_exts, uint16_t);
	ret = SSL_client_hello_get_extension_order(s, exts, &num_exts);
	if (ret != 1) {
	    Safefree(exts);
	    XSRETURN_UNDEF;
	}

	av = newAV();
	mXPUSHs(newRV_noinc((SV*)av));
	for (i=0; i < num_exts; i++) {
	    av_push(av, newSViv(*(exts + i)));
	}
	Safefree(exts);

#endif

void
SSL_client_hello_get0_ext(SSL *s, unsigned int type)
    PREINIT:
	int ret;
	const unsigned char *out = NULL;
	size_t outlen;
    CODE:
	ret = SSL_client_hello_get0_ext(s, type, &out, &outlen);
	if (ret != 1) XSRETURN_UNDEF;

	ST(0) = sv_newmortal();
	sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);

#endif

int
SSL_set_purpose(s,purpose)
     SSL *	s
     int 	purpose

void
SSL_set_quiet_shutdown(ssl,mode)
     SSL *	ssl
     int 	mode

void
SSL_set_shutdown(ssl,mode)
     SSL *	ssl
     int 	mode

int
SSL_set_trust(s,trust)
     SSL *	s
     int 	trust

void
SSL_set_verify_depth(s,depth)
     SSL *	s
     int 	depth

void

SSLeay.xs  view on Meta::CPAN

       ret = RSA_new();
       if(!ret) {
	   simple_cb_data_free(cb_data);
	   BN_free(e);
           croak("Net::SSLeay: RSA_generate_key perl function could not create RSA structure.\n");
       }
#if (OPENSSL_VERSION_NUMBER >= 0x10100001L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x2070000fL)
       new_cb = BN_GENCB_new();
       if(!new_cb) {
	   simple_cb_data_free(cb_data);
	   BN_free(e);
	   RSA_free(ret);
	   croak("Net::SSLeay: RSA_generate_key perl function could not create BN_GENCB structure.\n");
       }
       BN_GENCB_set_old(new_cb, ssleay_RSA_generate_key_cb_invoke, cb_data);
       rc = RSA_generate_key_ex(ret, bits, e, new_cb);
       BN_GENCB_free(new_cb);
#else
       BN_GENCB_set_old(&new_cb, ssleay_RSA_generate_key_cb_invoke, cb_data);
       rc = RSA_generate_key_ex(ret, bits, e, &new_cb);
#endif
       simple_cb_data_free(cb_data);
       BN_free(e);
       if (rc == -1 || ret == NULL) {
           if (ret) RSA_free(ret);
           croak("Net::SSLeay: Couldn't generate RSA key");
       }
       e = NULL;
       RETVAL = ret;
    OUTPUT:
        RETVAL

#else

RSA *
RSA_generate_key(bits,e,perl_cb=&PL_sv_undef,perl_data=&PL_sv_undef)
        int bits
        unsigned long e
        SV* perl_cb
        SV* perl_data
    PREINIT:
        simple_cb_data_t* cb = NULL;
    CODE:
        cb = simple_cb_data_new(perl_cb, perl_data);
        RETVAL = RSA_generate_key(bits, e, ssleay_RSA_generate_key_cb_invoke, cb);
        simple_cb_data_free(cb);
    OUTPUT:
        RETVAL

#endif

void
RSA_get_key_parameters(rsa)
	    RSA * rsa
PREINIT:
#if (!defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x1010000fL)) || (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x3050000fL))
    const BIGNUM *n, *e, *d;
    const BIGNUM *p, *q;
    const BIGNUM *dmp1, *dmq1, *iqmp;
#endif
PPCODE:
{
#if (!defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x1010000fL)) || (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x3050000fL))
    RSA_get0_key(rsa, &n, &e, &d);
    RSA_get0_factors(rsa, &p, &q);
    RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
    /* Caution: returned list consists of SV pointers to BIGNUMs, which would need to be blessed as Crypt::OpenSSL::Bignum for further use */
    XPUSHs(bn2sv(n));
    XPUSHs(bn2sv(e));
    XPUSHs(bn2sv(d));
    XPUSHs(bn2sv(p));
    XPUSHs(bn2sv(q));
    XPUSHs(bn2sv(dmp1));
    XPUSHs(bn2sv(dmq1));
    XPUSHs(bn2sv(iqmp));
#else
    /* Caution: returned list consists of SV pointers to BIGNUMs, which would need to be blessed as Crypt::OpenSSL::Bignum for further use */
    XPUSHs(bn2sv(rsa->n));
    XPUSHs(bn2sv(rsa->e));
    XPUSHs(bn2sv(rsa->d));
    XPUSHs(bn2sv(rsa->p));
    XPUSHs(bn2sv(rsa->q));
    XPUSHs(bn2sv(rsa->dmp1));
    XPUSHs(bn2sv(rsa->dmq1));
    XPUSHs(bn2sv(rsa->iqmp));
#endif
}

void
RSA_free(r)
    RSA * r

X509 *
X509_new()

void
X509_free(a)
    X509 * a

X509_CRL *
d2i_X509_CRL_bio(BIO *bp,X509_CRL **unused=NULL)

X509_REQ *
d2i_X509_REQ_bio(BIO *bp,X509_REQ **unused=NULL)

X509 *
d2i_X509_bio(BIO *bp,X509 **unused=NULL)

DH *
PEM_read_bio_DHparams(bio,x=NULL,cb=NULL,u=NULL)
	BIO  * bio
	DH ** x
	pem_password_cb * cb
	void * u

X509_CRL *
PEM_read_bio_X509_CRL(bio,x=NULL,cb=NULL,u=NULL)
	BIO  * bio
	X509_CRL ** x
	pem_password_cb * cb
	void * u

SSLeay.xs  view on Meta::CPAN

OBJ_dup(o)
    ASN1_OBJECT *o

ASN1_OBJECT *
OBJ_nid2obj(n)
    int n

const char *
OBJ_nid2ln(n)
    int n

const char *
OBJ_nid2sn(n)
    int n

int
OBJ_obj2nid(o)
    ASN1_OBJECT *o

ASN1_OBJECT *
OBJ_txt2obj(s, no_name=0)
    const char *s
    int no_name

void
OBJ_obj2txt(a, no_name=0)
    ASN1_OBJECT *a
    int no_name
    PREINIT:
    char buf[100]; /* openssl doc: a buffer length of 80 should be more than enough to handle any OID encountered in practice */
    int  len;
    CODE:
    len = OBJ_obj2txt(buf, sizeof(buf), a, no_name);
    ST(0) = sv_newmortal();
    sv_setpvn(ST(0), buf, len);

int
OBJ_txt2nid(s)
    const char *s

int
OBJ_ln2nid(s)
    const char *s

int
OBJ_sn2nid(s)
    const char *s

int
OBJ_cmp(a, b)
    ASN1_OBJECT *a
    ASN1_OBJECT *b

void
X509_pubkey_digest(data,type)
        const X509 *data
        const EVP_MD *type
    PREINIT:
        unsigned char md[EVP_MAX_MD_SIZE];
        unsigned int md_size;
    PPCODE:
        if (X509_pubkey_digest(data,type,md,&md_size))
            XSRETURN_PVN((char *)md, md_size);
        else
            XSRETURN_UNDEF;

void
X509_digest(data,type)
        const X509 *data
        const EVP_MD *type
    PREINIT:
        unsigned char md[EVP_MAX_MD_SIZE];
        unsigned int md_size;
    PPCODE:
        if (X509_digest(data,type,md,&md_size))
            XSRETURN_PVN((char *)md, md_size);
        XSRETURN_UNDEF;

void
X509_CRL_digest(data,type)
        const X509_CRL *data
        const EVP_MD *type
    PREINIT:
        unsigned char md[EVP_MAX_MD_SIZE];
        unsigned int md_size;
    PPCODE:
        if (X509_CRL_digest(data,type,md,&md_size))
            XSRETURN_PVN((char *)md, md_size);
        XSRETURN_UNDEF;

void
X509_REQ_digest(data,type)
        const X509_REQ *data
        const EVP_MD *type
    PREINIT:
        unsigned char md[EVP_MAX_MD_SIZE];
        unsigned int md_size;
    PPCODE:
        if (X509_REQ_digest(data,type,md,&md_size))
            XSRETURN_PVN((char *)md, md_size);
        XSRETURN_UNDEF;

void
X509_NAME_digest(data,type)
        const X509_NAME *data
        const EVP_MD *type
    PREINIT:
        unsigned char md[EVP_MAX_MD_SIZE];
        unsigned int md_size;
    PPCODE:
        if (X509_NAME_digest(data,type,md,&md_size))
            XSRETURN_PVN((char *)md, md_size);
        XSRETURN_UNDEF;

unsigned long
X509_subject_name_hash(X509 *x)

unsigned long
X509_issuer_name_hash(X509 *a)

unsigned long
X509_issuer_and_serial_hash(X509 *a)

ASN1_OBJECT *
P_X509_get_signature_alg(x)
        X509 * x
    CODE:
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (LIBRESSL_VERSION_NUMBER >= 0x3050000fL)
        RETVAL = (X509_get0_tbs_sigalg(x)->algorithm);
#else
        RETVAL = (x->cert_info->signature->algorithm);
#endif
    OUTPUT:
        RETVAL

ASN1_OBJECT *
P_X509_get_pubkey_alg(x)
        X509 * x
    PREINIT:
    CODE:
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
    {
	X509_ALGOR * algor;
        X509_PUBKEY_get0_param(0, 0, 0, &algor, X509_get_X509_PUBKEY(x));
        RETVAL = (algor->algorithm);
    }
#else
        RETVAL = (x->cert_info->key->algor->algorithm);
#endif
    OUTPUT:
        RETVAL

void
X509_get_X509_PUBKEY(x)
   const X509 *x
   PREINIT:
   X509_PUBKEY *pkey;
   STRLEN len;
   unsigned char *pc, *pi;
   PPCODE:
   if (!(pkey = X509_get_X509_PUBKEY(x))) croak("invalid certificate");
   if (!(len = i2d_X509_PUBKEY(pkey, NULL))) croak("invalid certificate public key");
   Newx(pc,len,unsigned char);
   if (!pc) croak("out of memory");
   pi = pc;
   i2d_X509_PUBKEY(pkey, &pi);
   if (pi-pc != len) croak("invalid encoded length");
   XPUSHs(sv_2mortal(newSVpv((char*)pc,len)));
   Safefree(pc);

#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_NEXTPROTONEG) && !defined(LIBRESSL_VERSION_NUMBER)

int
SSL_CTX_set_next_protos_advertised_cb(ctx,callback,data=&PL_sv_undef)
        SSL_CTX * ctx
        SV * callback
        SV * data
    CODE:
        RETVAL = 1;
        if (callback==NULL || !SvOK(callback)) {
            SSL_CTX_set_next_protos_advertised_cb(ctx, NULL, NULL);
            cb_data_advanced_put(ctx, "next_protos_advertised_cb!!func", NULL);
            cb_data_advanced_put(ctx, "next_protos_advertised_cb!!data", NULL);
            PR1("SSL_CTX_set_next_protos_advertised_cb - undef\n");
        }
        else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVAV)) {
            /* callback param array ref like ['proto1','proto2'] */
            cb_data_advanced_put(ctx, "next_protos_advertised_cb!!func", NULL);
            cb_data_advanced_put(ctx, "next_protos_advertised_cb!!data", newSVsv(callback));
            SSL_CTX_set_next_protos_advertised_cb(ctx, next_protos_advertised_cb_invoke, ctx);
            PR2("SSL_CTX_set_next_protos_advertised_cb - simple ctx=%p\n",ctx);
        }
        else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVCV)) {
            cb_data_advanced_put(ctx, "next_protos_advertised_cb!!func", newSVsv(callback));
            cb_data_advanced_put(ctx, "next_protos_advertised_cb!!data", newSVsv(data));
            SSL_CTX_set_next_protos_advertised_cb(ctx, next_protos_advertised_cb_invoke, ctx);
            PR2("SSL_CTX_set_next_protos_advertised_cb - advanced ctx=%p\n",ctx);
        }
        else {
            RETVAL = 0;
        }
    OUTPUT:
        RETVAL

int
SSL_CTX_set_next_proto_select_cb(ctx,callback,data=&PL_sv_undef)
        SSL_CTX * ctx
        SV * callback
        SV * data
    CODE: 
        RETVAL = 1;
        if (callback==NULL || !SvOK(callback)) {
            SSL_CTX_set_next_proto_select_cb(ctx, NULL, NULL);
            cb_data_advanced_put(ctx, "next_proto_select_cb!!func", NULL);
            cb_data_advanced_put(ctx, "next_proto_select_cb!!data", NULL);
            PR1("SSL_CTX_set_next_proto_select_cb - undef\n");
        }
        else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVAV)) {
            /* callback param array ref like ['proto1','proto2'] */
            cb_data_advanced_put(ctx, "next_proto_select_cb!!func", NULL);
            cb_data_advanced_put(ctx, "next_proto_select_cb!!data", newSVsv(callback));
            SSL_CTX_set_next_proto_select_cb(ctx, next_proto_select_cb_invoke, ctx);
            PR2("SSL_CTX_set_next_proto_select_cb - simple ctx=%p\n",ctx);
        }
        else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVCV)) {
            cb_data_advanced_put(ctx, "next_proto_select_cb!!func", newSVsv(callback));
            cb_data_advanced_put(ctx, "next_proto_select_cb!!data", newSVsv(data));
            SSL_CTX_set_next_proto_select_cb(ctx, next_proto_select_cb_invoke, ctx);
            PR2("SSL_CTX_set_next_proto_select_cb - advanced ctx=%p\n",ctx);
        }
        else {
            RETVAL = 0;
        }
    OUTPUT:
        RETVAL

void
P_next_proto_negotiated(s)
        const SSL *s
    PREINIT:
        const unsigned char *data;
        unsigned int len;
    PPCODE:
        SSL_get0_next_proto_negotiated(s, &data, &len);
        XPUSHs(sv_2mortal(newSVpv((char *)data, len)));

void
P_next_proto_last_status(s)
        const SSL *s
    PPCODE:
        XPUSHs(sv_2mortal(newSVsv(cb_data_advanced_get((void*)s, "next_proto_select_cb!!last_status"))));

#endif

#if OPENSSL_VERSION_NUMBER >= 0x10000000L

#if !defined(OPENSSL_NO_TLSEXT)

int
SSL_set_tlsext_status_type(SSL *ssl,int cmd)

long
SSL_set_tlsext_status_ocsp_resp(ssl,staple)
        SSL *  ssl
    PREINIT:
        char * p;
        STRLEN staplelen;
    INPUT:
        char *  staple = SvPV( ST(1), staplelen);
    CODE:
        /* OpenSSL will free the memory */
        New(0, p, staplelen, char);
        memcpy(p, staple, staplelen);
        RETVAL = SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,staplelen,(void *)p);
    OUTPUT:
        RETVAL

int
SSL_CTX_set_tlsext_status_cb(ctx,callback,data=&PL_sv_undef)
	SSL_CTX * ctx
	SV * callback
	SV * data
    CODE:
	RETVAL = 1;
	if (callback==NULL || !SvOK(callback)) {
	    cb_data_advanced_put(ctx, "tlsext_status_cb!!func", NULL);
	    cb_data_advanced_put(ctx, "tlsext_status_cb!!data", NULL);
	    SSL_CTX_set_tlsext_status_cb(ctx, NULL);
	} else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVCV)) {
	    cb_data_advanced_put(ctx, "tlsext_status_cb!!func", newSVsv(callback));
	    cb_data_advanced_put(ctx, "tlsext_status_cb!!data", newSVsv(data));
	    SSL_CTX_set_tlsext_status_cb(ctx, tlsext_status_cb_invoke);
	} else {
	    croak("argument must be code reference");
	}
    OUTPUT:
	RETVAL

int
SSL_set_session_ticket_ext_cb(ssl,callback,data=&PL_sv_undef)
        SSL *  ssl
        SV *  callback
        SV *  data
    CODE:
        RETVAL = 1;
        if (callback==NULL || !SvOK(callback)) {
            cb_data_advanced_put(ssl, "session_ticket_ext_cb!!func", NULL);
            cb_data_advanced_put(ssl, "session_ticket_ext_cb!!data", NULL);
            SSL_set_session_ticket_ext_cb(ssl, NULL, NULL);
        } else if (SvROK(callback) && (SvTYPE(SvRV(callback)) == SVt_PVCV)) {
            cb_data_advanced_put(ssl, "session_ticket_ext_cb!!func", newSVsv(callback));
            cb_data_advanced_put(ssl, "session_ticket_ext_cb!!data", newSVsv(data));
            SSL_set_session_ticket_ext_cb(ssl, (tls_session_ticket_ext_cb_fn)&session_ticket_ext_cb_invoke, ssl);
        } else {
            croak("argument must be code reference");
        }
    OUTPUT:
        RETVAL

int
SSL_set_session_ticket_ext(ssl,ticket)
        SSL *ssl
    PREINIT:
        unsigned char * p;
        STRLEN ticketlen;
    INPUT:
        unsigned char * ticket = (unsigned char *)SvPV( ST(1), ticketlen);
    CODE:
        RETVAL = 0;
        if (ticketlen > 0) {
            Newx(p, ticketlen, unsigned char);
            if (!p)
                croak("Net::SSLeay: set_session_ticket_ext could not allocate memory.\n");
            memcpy(p, ticket, ticketlen);
            RETVAL = SSL_set_session_ticket_ext(ssl, p, ticketlen);
            Safefree(p);
        }
    OUTPUT:
        RETVAL

#endif

OCSP_RESPONSE *
d2i_OCSP_RESPONSE(pv)
	SV *pv
    CODE:
	RETVAL = NULL;
	if (SvPOK(pv)) {
	    const unsigned char *p;
	    STRLEN len;
	    p = (unsigned char*)SvPV(pv,len);
	    RETVAL = d2i_OCSP_RESPONSE(NULL,&p,len);
	}
    OUTPUT:
	RETVAL

void
i2d_OCSP_RESPONSE(r)
	OCSP_RESPONSE * r
	PREINIT:
	STRLEN len;
	unsigned char *pc,*pi;
    PPCODE:
	if (!(len = i2d_OCSP_RESPONSE(r,NULL))) croak("invalid OCSP response");
	Newx(pc,len,unsigned char);
	if (!pc) croak("out of memory");
	pi = pc;
	i2d_OCSP_RESPONSE(r,&pi);
	XPUSHs(sv_2mortal(newSVpv((char*)pc,len)));
	Safefree(pc);

void
OCSP_RESPONSE_free(r)
    OCSP_RESPONSE * r


OCSP_REQUEST *
d2i_OCSP_REQUEST(pv)
	SV *pv
    CODE:
	RETVAL = NULL;
	if (SvPOK(pv)) {
	    const unsigned char *p;
	    STRLEN len;
	    p = (unsigned char*)SvPV(pv,len);
	    RETVAL = d2i_OCSP_REQUEST(NULL,&p,len);
	}
    OUTPUT:
	RETVAL

void
i2d_OCSP_REQUEST(r)
	OCSP_REQUEST * r
	PREINIT:
	STRLEN len;
	unsigned char *pc,*pi;
    PPCODE:
	if (!(len = i2d_OCSP_REQUEST(r,NULL))) croak("invalid OCSP request");
	Newx(pc,len,unsigned char);
	if (!pc) croak("out of memory");
	pi = pc;
	i2d_OCSP_REQUEST(r,&pi);
	XPUSHs(sv_2mortal(newSVpv((char*)pc,len)));
	Safefree(pc);


void
OCSP_REQUEST_free(r)
    OCSP_REQUEST * r


const char *
OCSP_response_status_str(long status)

long
OCSP_response_status(OCSP_RESPONSE *r)

void
SSL_OCSP_cert2ids(ssl,...)
	SSL *ssl
PREINIT:
	SSL_CTX *ctx;
	X509_STORE *store;
	STACK_OF(X509) *chain;
	X509 *cert,*issuer;
	OCSP_CERTID *id;
	int i;
	STRLEN len;
	unsigned char *pi;
    PPCODE:

	if (!ssl) croak("not a SSL object");
	ctx = SSL_get_SSL_CTX(ssl);
	if (!ctx) croak("invalid SSL object - no context");
	store = SSL_CTX_get_cert_store(ctx);
	chain = SSL_get_peer_cert_chain(ssl);

	for(i=0;i<items-1;i++) {
	    cert = INT2PTR(X509*,SvIV(ST(i+1)));
	    if (X509_check_issued(cert,cert) == X509_V_OK)
		croak("no OCSP request for self-signed certificate");
	    if (!(issuer = find_issuer(cert,store,chain)))
		croak("cannot find issuer certificate");
	    id = OCSP_cert_to_id(EVP_sha1(),cert,issuer);
	    X509_free(issuer);
	    if (!id)
		croak("out of memory for generating OCSP certid");

	    pi = NULL;
	    if (!(len = i2d_OCSP_CERTID(id,&pi)))
		croak("OCSP certid has no length");
	    XPUSHs(sv_2mortal(newSVpvn((char *)pi, len)));

	    OPENSSL_free(pi);
	    OCSP_CERTID_free(id);
	}


OCSP_REQUEST *
OCSP_ids2req(...)
	PREINIT:
	OCSP_REQUEST *req;
	OCSP_CERTID *id;
	int i;
    CODE:

	req = OCSP_REQUEST_new();
	if (!req) croak("out of memory");
	OCSP_request_add1_nonce(req,NULL,-1);

	for(i=0;i<items;i++) {
	    STRLEN len;
	    const unsigned char *p = (unsigned char*)SvPV(ST(i),len);
	    id = d2i_OCSP_CERTID(NULL,&p,len);
	    if (!id) {
		OCSP_REQUEST_free(req);
		croak("failed to get OCSP certid from string");
	    }
	    OCSP_request_add0_id(req,id);
	}
	RETVAL = req;
    OUTPUT:
	RETVAL



int
SSL_OCSP_response_verify(ssl,rsp,svreq=NULL,flags=0)
	SSL *ssl
	OCSP_RESPONSE *rsp

SSLeay.xs  view on Meta::CPAN


	bsr = OCSP_response_get1_basic(rsp);
	if (!bsr) croak("invalid OCSP response");

	/* if we get a nonce it should match our nonce, if we get no nonce
	 * it was probably pre-signed */
	if (svreq && SvOK(svreq) &&
	    (req = INT2PTR(OCSP_REQUEST*,SvIV(svreq)))) {
	    i = OCSP_check_nonce(req,bsr);
	    if ( i <= 0 ) {
		if (i == -1) {
		    TRACE(2,"SSL_OCSP_response_verify: no nonce in response");
		} else {
		    OCSP_BASICRESP_free(bsr);
		    croak("nonce in OCSP response does not match request");
		}
	    }
	}

	RETVAL = 0;
	if ((store = SSL_CTX_get_cert_store(ctx))) {
	    /* add the SSL uchain to the uchain of the OCSP basic response, this
	     * looks like the easiest way to handle the case where the OCSP
	     * response does not contain the chain up to the trusted root */
	    STACK_OF(X509) *chain = SSL_get_peer_cert_chain(ssl);
	    for(i=0;i<sk_X509_num(chain);i++) {
		OCSP_basic_add1_cert(bsr, sk_X509_value(chain,i));
	    }
	    TRACE(1,"run basic verify");
	    RETVAL = OCSP_basic_verify(bsr, NULL, store, flags);
	    if (chain && !RETVAL) {
		/* some CAs don't add a certificate to their OCSP responses and
		 * openssl does not include the trusted CA which signed the
		 * lowest chain certificate when looking for the signer.
		 * So find this CA ourself and retry verification. */
		X509 *issuer;
		X509 *last = sk_X509_value(chain,sk_X509_num(chain)-1);
		ERR_clear_error(); /* clear error from last OCSP_basic_verify */
		if (last && (issuer = find_issuer(last,store,chain))) {
		    OCSP_basic_add1_cert(bsr, issuer);
		    X509_free(issuer);
		    TRACE(1,"run OCSP_basic_verify with issuer for last chain element");
		    RETVAL = OCSP_basic_verify(bsr, NULL, store, flags);
		}
	    }
	}
	OCSP_BASICRESP_free(bsr);
    OUTPUT:
	RETVAL


void
OCSP_response_results(rsp,...)
	OCSP_RESPONSE *rsp
    PREINIT:
	OCSP_BASICRESP *bsr;
	int i,want_array;
	time_t nextupd = 0;
	time_t gmtoff = -1;
	int getall,sksn;
    PPCODE:

	bsr = OCSP_response_get1_basic(rsp);
	if (!bsr) croak("invalid OCSP response");

	want_array = (GIMME_V == G_LIST);
	getall = (items <= 1);
	sksn = OCSP_resp_count(bsr);

	for(i=0; i < (getall ? sksn : items-1); i++) {
	    const char *error = NULL;
	    OCSP_SINGLERESP *sir = NULL;
	    OCSP_CERTID *certid = NULL;
	    SV *idsv = NULL;
	    int first, status, revocationReason;
	    ASN1_GENERALIZEDTIME *revocationTime, *thisupdate, *nextupdate;

	    if(getall) {
		sir = OCSP_resp_get0(bsr,i);
	    } else {
		STRLEN len;
		const unsigned char *p;

		idsv = ST(i+1);
		if (!SvOK(idsv)) croak("undefined certid in arguments");
		p = (unsigned char*)SvPV(idsv,len);
		if (!(certid = d2i_OCSP_CERTID(NULL,&p,len))) {
		    error = "failed to get OCSP certid from string";
		    goto end;
		}
                first = OCSP_resp_find(bsr, certid, -1); /* Find the first matching */
                if (first >= 0)
                    sir = OCSP_resp_get0(bsr,first);
	    }

	    if (sir)
	    {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
		status = OCSP_single_get0_status(sir, &revocationReason, &revocationTime, &thisupdate, &nextupdate);
#else
		status = sir->certStatus->type;
		if (status == V_OCSP_CERTSTATUS_REVOKED)
		    revocationTime = sir->certStatus->value.revoked->revocationTime;
		thisupdate = sir->thisUpdate;
		nextupdate = sir->nextUpdate;
#endif
		if (status == V_OCSP_CERTSTATUS_REVOKED) {
		    error = "certificate status is revoked";
		} else if (status != V_OCSP_CERTSTATUS_GOOD) {
		    error = "certificate status is unknown";
		}
		else if (!OCSP_check_validity(thisupdate, nextupdate, 0, -1)) {
		    error = "response not yet valid or expired";
		}
	    } else {
	        error = "cannot find entry for certificate in OCSP response";
	    }

	    end:
	    if (want_array) {
		AV *idav = newAV();

SSLeay.xs  view on Meta::CPAN

        else {
            RETVAL = 0;
        }
    OUTPUT:
        RETVAL

int
SSL_CTX_set_alpn_protos(ctx,data=&PL_sv_undef)
        SSL_CTX * ctx
        SV * data
    PREINIT:
        unsigned char *alpn_data;
        unsigned char alpn_len;

    CODE:
        RETVAL = -1;

        if (!SvROK(data) || (SvTYPE(SvRV(data)) != SVt_PVAV))
            croak("Net::SSLeay: CTX_set_alpn_protos needs a single array reference.\n");
        alpn_len = next_proto_helper_AV2protodata((AV*)SvRV(data), NULL);
        Newx(alpn_data, alpn_len, unsigned char);
        if (!alpn_data)
            croak("Net::SSLeay: CTX_set_alpn_protos could not allocate memory.\n");
        alpn_len = next_proto_helper_AV2protodata((AV*)SvRV(data), alpn_data);
        RETVAL = SSL_CTX_set_alpn_protos(ctx, alpn_data, alpn_len);
        Safefree(alpn_data);

    OUTPUT:
        RETVAL

int
SSL_set_alpn_protos(ssl,data=&PL_sv_undef)
        SSL * ssl
        SV * data
    PREINIT:
        unsigned char *alpn_data;
        unsigned char alpn_len;

    CODE:
        RETVAL = -1;

        if (!SvROK(data) || (SvTYPE(SvRV(data)) != SVt_PVAV))
            croak("Net::SSLeay: set_alpn_protos needs a single array reference.\n");
        alpn_len = next_proto_helper_AV2protodata((AV*)SvRV(data), NULL);
        Newx(alpn_data, alpn_len, unsigned char);
        if (!alpn_data)
            croak("Net::SSLeay: set_alpn_protos could not allocate memory.\n");
        alpn_len = next_proto_helper_AV2protodata((AV*)SvRV(data), alpn_data);
        RETVAL = SSL_set_alpn_protos(ssl, alpn_data, alpn_len);
        Safefree(alpn_data);

    OUTPUT:
        RETVAL

void
P_alpn_selected(s)
        const SSL *s
    PREINIT:
        const unsigned char *data;
        unsigned int len;
    PPCODE:
        SSL_get0_alpn_selected(s, &data, &len);
        XPUSHs(sv_2mortal(newSVpv((char *)data, len)));

#endif

#if OPENSSL_VERSION_NUMBER >= 0x10001000L

void
SSL_export_keying_material(ssl, outlen, label, context=&PL_sv_undef)
        SSL * ssl
        int outlen
        SV * context
    PREINIT:
        unsigned char *  out;
        STRLEN llen;
        STRLEN contextlen = 0;
        char *context_arg = NULL;
        int use_context = 0;
        int ret;
    INPUT:
        char *  label = SvPV( ST(2), llen);
    PPCODE:
        Newx(out, outlen, unsigned char);

        if (context != &PL_sv_undef) {
            use_context = 1;
            context_arg = SvPV( ST(3), contextlen);
        }
        ret = SSL_export_keying_material(ssl, out, outlen, label, llen, (unsigned char*)context_arg, contextlen, use_context);
        PUSHs(sv_2mortal(ret>0 ? newSVpvn((const char *)out, outlen) : newSV(0)));
        EXTEND(SP, 1);
	Safefree(out);

#endif

#if OPENSSL_VERSION_NUMBER >= 0x30000000L

OSSL_LIB_CTX *
OSSL_LIB_CTX_get0_global_default()


OSSL_PROVIDER *
OSSL_PROVIDER_load(SV *libctx, const char *name)
    PREINIT:
        OSSL_LIB_CTX *ctx = NULL;
    CODE:
        if (libctx != &PL_sv_undef)
	    ctx = INT2PTR(OSSL_LIB_CTX *, SvIV(libctx));
        RETVAL = OSSL_PROVIDER_load(ctx, name);
        if (RETVAL == NULL)
	    XSRETURN_UNDEF;
    OUTPUT:
	  RETVAL

OSSL_PROVIDER *
OSSL_PROVIDER_try_load(SV *libctx, const char *name, int retain_fallbacks)
    PREINIT:
        OSSL_LIB_CTX *ctx = NULL;
    CODE:
        if (libctx != &PL_sv_undef)
	    ctx = INT2PTR(OSSL_LIB_CTX *, SvIV(libctx));
        RETVAL = OSSL_PROVIDER_try_load(ctx, name, retain_fallbacks);
        if (RETVAL == NULL)
	    XSRETURN_UNDEF;
    OUTPUT:
	  RETVAL

int
OSSL_PROVIDER_unload(OSSL_PROVIDER *prov)

int
OSSL_PROVIDER_available(SV *libctx, const char *name)
    PREINIT:
        OSSL_LIB_CTX *ctx = NULL;
    CODE:
        if (libctx != &PL_sv_undef)
	    ctx = INT2PTR(OSSL_LIB_CTX *, SvIV(libctx));
        RETVAL = OSSL_PROVIDER_available(ctx, name);
    OUTPUT:
	  RETVAL

int



( run in 0.580 second using v1.01-cache-2.11-cpan-71847e10f99 )