Net-SSLeay
view release on metacpan or search on metacpan
#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
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)
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);
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;
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:
/* 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:
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
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
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
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
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();
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 )