--- /dev/null
+/* SSLeay.xs - Perl module for using Eric Young's implementation of SSL
+ *
+ * Copyright (c) 1996-2002 Sampo Kellomaki <sampo@iki.fi>
+ * Copyright (C) 2005 Florian Ragwitz <rafl@debian.org>
+ * Copyright (C) 2005 Mike McCauley <mikem@open.com.au>
+ *
+ * All Rights Reserved.
+ *
+ * 19.6.1998, Maintenance release to sync with SSLeay-0.9.0, --Sampo
+ * 24.6.1998, added write_partial to support ssl_write_all in more
+ * memory efficient way. --Sampo
+ * 8.7.1998, Added SSL_(CTX)?_set_options and associated constants.
+ * 31.3.1999, Tracking OpenSSL-0.9.2b changes, dropping support for
+ * earlier versions
+ * 30.7.1999, Tracking OpenSSL-0.9.3a changes, --Sampo
+ * 7.4.2001, OpenSSL-0.9.6a update, --Sampo
+ * 18.4.2001, added TLSv1 support by Stephen C. Koehler
+ * <koehler@securecomputing.com>, version 1.07, --Sampo
+ * 25.4.2001, applied 64 bit fixes by Marko Asplund <aspa@kronodoc.fi> --Sampo
+ * 16.7.2001, applied Win filehandle patch from aspa, added
+ * SSL_*_methods --Sampo
+ * 25.9.2001, added a big pile of methods by automatically grepping and diffing
+ * openssl headers and my module --Sampo
+ * 17.4.2002, applied patch to fix CTX_set_default_passwd_cb() contributed
+ * by Timo Kujala <timo.kujala@@intellitel_.com>, --Sampo
+ * 17.5.2002, Added BIO_s_mem, BIO_new, BIO_free, BIO_write, BIO_read ,
+ * BIO_eof, BIO_pending, BIO_wpending, X509_NAME_get_text_by_NID,
+ * RSA_generate_key, BIO_new_file
+ * Fixed problem with return value from verify callback being
+ * ignored.
+ * Fixed a problem with CTX_set_tmp_rsa and CTX_set_tmp_dh
+ * args incorrect
+ * --mikem@open.com_.au
+ * 10.8.2002, Added SSL_peek patch to ssl_read_until from
+ * Peter Behroozi <peter@@fhpwireless_.com> --Sampo
+ * 21.8.2002, Added SESSION_get_master_key, SSL_get_client_random, SSL_get_server_random
+ * --mikem@open.com_.au
+ * 2.9.2002, Added SSL_CTX_get_cert_store, X509_STORE_add_cert, X509_STORE_add_crl
+ * X509_STORE_set_flags, X509_load_cert_file, X509_load_crl_file
+ * X509_load_cert_crl_file, PEM_read_bio_X509_CRL
+ * constants for X509_V_FLAG_*
+ * --mikem@open.com_.au
+ * 6.9.2002, applied Mike's patch and fixed X509_STORE_* to X509_STORE_CTX_*
+ * --Sampo
+ * 18.2.2003, RAND patch from Toni Andjelkovic <toni@soth._at>
+ * 13.6.2003, applied SSL_X509_LOOKUP patch by Marian Jancar <mjancar@suse._cz>
+ * 18.8.2003, fixed some const char pointer warnings --Sampo
+ * 01.12.2005 fixed a thread safety problem with SvSetSV that could cause crashes
+ * if SSL_CTX_set_default_passwd_cb and friends were called multiple
+ * times in different threads.
+ * Reintroduced X509_STORE_set_flags, also added
+ * X509_STORE_set_purpose and X509_STORE_set_trust
+ * Added X509_get_subjectAltNames and a number of other openssl
+ * X509 functions: X509_get_ext_by_NID X509_get_ext
+ * X509V3_EXT_d2i
+ * X509_verify_cert_error_string
+ * --mikem@open.com_.au
+ * 13.12.2005 Reinstated the thread safety fix from 01.12.2005 due memory leaks
+ * It is better to reset the callback with undef after use to prevent
+ * leaks and thread safety problems.
+ * 28.7.2006 Use New and Safefree insted of malloc/free. Use OPENSSL_free
+ * instead of free to release memory allocated by X509_NAME_oneline.
+ * These changes to deal with thread safety issues.
+ * 01.08.2006 set_*fd nw woork with filehandles as well as filenos on Windows
+ *
+ * $Id$
+ *
+ * The distribution and use of this module are subject to the conditions
+ * listed in LICENSE file at the root of OpenSSL-0.9.6b
+ * distribution (i.e. free, but mandatory attribution and NO WARRANTY).
+ */
+
+/* Prevent warnings about strncpy from Windows compilers */
+#define _CRT_SECURE_NO_DEPRECATE
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include "ppport.h"
+#ifdef __cplusplus
+}
+#endif
+
+/* OpenSSL-0.9.3a has some strange warning about this in
+ * openssl/des.h
+ */
+#undef _
+
+#include <openssl/err.h>
+#include <openssl/lhash.h>
+#include <openssl/rand.h>
+#include <openssl/buffer.h>
+#include <openssl/ssl.h>
+#include <openssl/comp.h> /* openssl-0.9.6a forgets to include this */
+#include <openssl/md2.h>
+#include <openssl/md4.h>
+#include <openssl/md5.h> /* openssl-SNAP-20020227 does not automatically include this */
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/engine.h>
+
+/* Debugging output */
+
+#if 0
+#define PR(s) printf(s);
+#define PRN(s,n) printf("'%s' (%d)\n",s,n);
+#define SEX_DEBUG 1
+#else
+#define PR(s)
+#define PRN(s,n)
+#undef SEX_DEBUG
+#endif
+
+#include "constants.c"
+
+/* ============= typedefs to agument TYPEMAP ============== */
+
+typedef void callback_no_ret(void);
+typedef void cb_ssl_int_int_ret_void(const SSL *ssl,int,int);
+typedef RSA * cb_ssl_int_int_ret_RSA(SSL * ssl,int is_export, int keylength);
+typedef DH * cb_ssl_int_int_ret_DH(SSL * ssl,int is_export, int keylength);
+
+typedef STACK_OF(X509_NAME) X509_NAME_STACK;
+
+typedef int perl_filehandle_t;
+
+/* ============= callback stuff ============== */
+
+static HV* ssleay_ctx_verify_callbacks = (HV*)NULL;
+
+static int
+ssleay_verify_callback_invoke (int ok, X509_STORE_CTX* x509_store) {
+ SSL* ssl;
+ SV* key;
+ char* key_str;
+ STRLEN key_len;
+ SV** callback;
+ int count, res;
+ dSP;
+
+ ssl = X509_STORE_CTX_get_ex_data( x509_store, SSL_get_ex_data_X509_STORE_CTX_idx() );
+ key = sv_2mortal(newSViv( (IV)ssl ));
+ key_str = SvPV(key, key_len);
+
+ callback = hv_fetch( ssleay_ctx_verify_callbacks, key_str, key_len, 0 );
+
+ if (callback == NULL) {
+ SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl);
+ key = sv_2mortal(newSViv( (IV)ssl_ctx ));
+ key_str = SvPV(key, key_len);
+
+ callback = hv_fetch( ssleay_ctx_verify_callbacks, key_str, key_len, 0 );
+
+ if (callback == NULL) {
+ croak ("Net::SSLeay: verify_callback called, but not "
+ "set to point to any perl function.\n");
+ }
+ }
+
+
+ ENTER;
+ SAVETMPS;
+
+ PRN("verify callback glue", ok);
+
+ PUSHMARK(sp);
+ EXTEND( sp, 2 );
+ PUSHs( sv_2mortal(newSViv(ok)) );
+ PUSHs( sv_2mortal(newSViv((unsigned long int)x509_store)) );
+ PUTBACK;
+
+ PR("About to call verify callback.\n");
+ count = call_sv(*callback, G_SCALAR);
+ PR("Returned from verify callback.\n");
+
+ SPAGAIN;
+
+ if (count != 1) {
+ croak ( "Net::SSLeay: verify_callback "
+ "perl function did not return a scalar.\n");
+ }
+
+ res = POPi;
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return res;
+}
+
+static HV* ssleay_ctx_passwd_cbs = (HV*)NULL;
+
+struct _ssleay_cb_t {
+ SV* func;
+ SV* data;
+};
+typedef struct _ssleay_cb_t ssleay_ctx_passwd_cb_t;
+typedef struct _ssleay_cb_t ssleay_ctx_cert_verify_cb_t;
+typedef struct _ssleay_cb_t ssleay_session_secret_cb_t;
+typedef struct _ssleay_cb_t ssleay_RSA_generate_key_cb_t;
+
+ssleay_ctx_passwd_cb_t*
+ssleay_ctx_passwd_cb_new(SSL_CTX* ctx) {
+ ssleay_ctx_passwd_cb_t* cb;
+ SV* hash_value;
+ SV* key;
+ char* key_str;
+ STRLEN key_len;
+
+ New(0, cb, 1, ssleay_ctx_passwd_cb_t);
+ cb->func = NULL;
+ cb->data = NULL;
+
+ if (ctx == NULL)
+ croak( "Net::SSLeay: ctx == NULL in ssleay_ctx_passwd_cb_new" );
+
+ hash_value = sv_2mortal(newSViv( (IV)cb ));
+
+ key = sv_2mortal(newSViv( (IV)ctx ));
+ key_str = SvPV(key, key_len);
+
+ if (ssleay_ctx_passwd_cbs == (HV*)NULL)
+ ssleay_ctx_passwd_cbs = newHV();
+
+ SvREFCNT_inc(hash_value);
+ hv_store( ssleay_ctx_passwd_cbs, key_str, key_len, hash_value, 0 );
+
+ return cb;
+}
+
+ssleay_ctx_passwd_cb_t*
+ssleay_ctx_passwd_cb_get(SSL_CTX* ctx) {
+ SV* key;
+ char* key_str;
+ STRLEN key_len;
+ SV** hash_value;
+ ssleay_ctx_passwd_cb_t* cb;
+
+ key = sv_2mortal(newSViv( (IV)ctx ));
+ key_str = SvPV(key, key_len);
+
+ hash_value = hv_fetch( ssleay_ctx_passwd_cbs, key_str, key_len, 0 );
+
+ if (hash_value == NULL || *hash_value == NULL) {
+ cb = ssleay_ctx_passwd_cb_new(ctx);
+ } else {
+ cb = (ssleay_ctx_passwd_cb_t*)SvIV( *hash_value );
+ }
+
+ return cb;
+}
+
+void
+ssleay_ctx_passwd_cb_func_set(SSL_CTX* ctx, SV* func) {
+ ssleay_ctx_passwd_cb_t* cb;
+
+ cb = ssleay_ctx_passwd_cb_get(ctx);
+
+ if (cb->func)
+ SvREFCNT_dec(cb->func);
+
+ SvREFCNT_inc(func);
+ cb->func = func;
+}
+
+void
+ssleay_ctx_passwd_cb_userdata_set(SSL_CTX* ctx, SV* data) {
+ ssleay_ctx_passwd_cb_t* cb;
+
+ cb = ssleay_ctx_passwd_cb_get(ctx);
+
+ if (cb->data)
+ SvREFCNT_dec(cb->data);
+
+ SvREFCNT_inc(data);
+ cb->data = data;
+}
+
+void
+ssleay_ctx_passwd_cb_free_func(SSL_CTX* ctx) {
+ ssleay_ctx_passwd_cb_t* cb;
+
+ cb = ssleay_ctx_passwd_cb_get(ctx);
+
+ if (cb && cb->func) {
+ SvREFCNT_dec(cb->func);
+ cb->func = NULL;
+ }
+}
+
+void
+ssleay_ctx_passwd_cb_free_userdata(SSL_CTX* ctx) {
+ ssleay_ctx_passwd_cb_t* cb;
+
+ cb = ssleay_ctx_passwd_cb_get(ctx);
+
+ if (cb && cb->data) {
+ SvREFCNT_dec(cb->data);
+ cb->data = NULL;
+ }
+}
+
+/* pem_password_cb function */
+
+static int
+ssleay_ctx_passwd_cb_invoke(char *buf, int size, int rwflag, void *userdata) {
+ dSP;
+
+ int count;
+ char *res;
+ ssleay_ctx_passwd_cb_t* cb = (ssleay_ctx_passwd_cb_t*)userdata;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(sp);
+ XPUSHs( sv_2mortal( newSViv(rwflag)) );
+ if (cb->data)
+ XPUSHs( cb->data );
+ PUTBACK;
+
+ if (cb->func == NULL)
+ croak ("Net::SSLeay: ssleay_ctx_passwd_cb_invoke called, but not "
+ "set to point to any perl function.\n");
+
+ count = call_sv( cb->func, G_SCALAR );
+
+ SPAGAIN;
+
+ if (count != 1)
+ croak ("Net::SSLeay: ssleay_ctx_passwd_cb_invoke "
+ "perl function did not return a scalar.\n");
+
+ res = POPp;
+
+ if (res == NULL) {
+ *buf = '\0';
+ } else {
+ strncpy(buf, res, size);
+ buf[size - 1] = '\0';
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return strlen(buf);
+}
+
+static HV* ssleay_ctx_cert_verify_cbs = (HV*)NULL;
+
+ssleay_ctx_cert_verify_cb_t*
+ssleay_ctx_cert_verify_cb_new(SSL_CTX* ctx, SV* func, SV* data) {
+ ssleay_ctx_cert_verify_cb_t* cb;
+ SV* hash_value;
+ SV* key;
+ char* key_str;
+ STRLEN key_len;
+
+ cb = New(0, cb, 1, ssleay_ctx_cert_verify_cb_t);
+
+ SvREFCNT_inc(func);
+ SvREFCNT_inc(data);
+ cb->func = func;
+ cb->data = data;
+
+ if (ctx == NULL) {
+ croak( "Net::SSLeay: ctx == NULL in ssleay_ctx_cert_verify_cb_new" );
+ }
+
+ hash_value = sv_2mortal(newSViv( (IV)cb ));
+
+ key = sv_2mortal(newSViv( (IV)ctx ));
+ key_str = SvPV(key, key_len);
+
+ if (ssleay_ctx_cert_verify_cbs == (HV*)NULL)
+ ssleay_ctx_cert_verify_cbs = newHV();
+
+ SvREFCNT_inc(hash_value);
+ hv_store( ssleay_ctx_cert_verify_cbs, key_str, key_len, hash_value, 0 );
+
+ return cb;
+}
+
+ssleay_ctx_cert_verify_cb_t*
+ssleay_ctx_cert_verify_cb_get(SSL_CTX* ctx) {
+ SV* key;
+ char* key_str;
+ STRLEN key_len;
+ SV** hash_value;
+ ssleay_ctx_cert_verify_cb_t* cb;
+
+ key = sv_2mortal(newSViv( (IV)ctx ));
+ key_str = SvPV(key, key_len);
+
+ hash_value = hv_fetch( ssleay_ctx_cert_verify_cbs, key_str, key_len, 0 );
+
+ if (hash_value == NULL || *hash_value == NULL) {
+ cb = NULL;
+ } else {
+ cb = (ssleay_ctx_cert_verify_cb_t*)SvIV( *hash_value );
+ }
+
+ return cb;
+}
+
+void
+ssleay_ctx_cert_verify_cb_free(SSL_CTX* ctx) {
+ ssleay_ctx_passwd_cb_t* cb;
+
+ cb = ssleay_ctx_cert_verify_cb_get(ctx);
+
+ if (cb) {
+ if (cb->func) {
+ SvREFCNT_dec(cb->func);
+ cb->func = NULL;
+ }
+
+ if (cb->data) {
+ SvREFCNT_dec(cb->data);
+ cb->data = NULL;
+ }
+ }
+
+ Safefree(cb);
+}
+
+int
+ssleay_ctx_cert_verify_cb_invoke(X509_STORE_CTX* x509_store_ctx, void* data) {
+ dSP;
+
+ int count;
+ int res;
+ ssleay_ctx_cert_verify_cb_t* cb = (ssleay_ctx_cert_verify_cb_t*)data;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(newSViv( (IV)x509_store_ctx )));
+ if (cb->data) {
+ XPUSHs( cb->data );
+ }
+ PUTBACK;
+
+ if (cb->func == NULL) {
+ croak ("Net::SSLeay: ssleay_ctx_cert_verify_cb_invoke called, but not "
+ "set to point to any perl function.\n");
+ }
+
+ count = call_sv( cb->func, G_SCALAR );
+
+ SPAGAIN;
+
+ if (count != 1) {
+ croak ("Net::SSLeay: ssleay_ctx_cert_verify_cb_invoke "
+ "perl function did not return a scalar.\n");
+ }
+
+ res = POPi;
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return res;
+}
+
+#ifdef SSL_F_SSL_SET_HELLO_EXTENSION
+static HV* ssleay_session_secret_cbs = (HV*)NULL;
+
+ssleay_session_secret_cb_t*
+ssleay_session_secret_cb_new(SSL* s, SV* func, SV* data) {
+ ssleay_session_secret_cb_t* cb;
+ SV* hash_value;
+ SV* key;
+ char* key_str;
+ STRLEN key_len;
+
+ cb = New(0, cb, 1, ssleay_session_secret_cb_t);
+
+ SvREFCNT_inc(func);
+ SvREFCNT_inc(data);
+ cb->func = func;
+ cb->data = data;
+
+ if (s == NULL) {
+ croak( "Net::SSLeay: s == NULL in ssleay_session_secret_cb_new" );
+ }
+
+ hash_value = sv_2mortal(newSViv( (IV)cb ));
+
+ key = sv_2mortal(newSViv( (IV)s ));
+ key_str = SvPV(key, key_len);
+
+ if (ssleay_session_secret_cbs == (HV*)NULL)
+ ssleay_session_secret_cbs = newHV();
+
+ SvREFCNT_inc(hash_value);
+ hv_store( ssleay_session_secret_cbs, key_str, key_len, hash_value, 0 );
+
+ return cb;
+}
+
+ssleay_session_secret_cb_t*
+ssleay_session_secret_cb_get(SSL* s) {
+ SV* key;
+ char* key_str;
+ STRLEN key_len;
+ SV** hash_value;
+ ssleay_session_secret_cb_t* cb;
+
+ key = sv_2mortal(newSViv( (IV)s ));
+ key_str = SvPV(key, key_len);
+
+ hash_value = hv_fetch( ssleay_session_secret_cbs, key_str, key_len, 0 );
+
+ if (hash_value == NULL || *hash_value == NULL) {
+ cb = NULL;
+ } else {
+ cb = (ssleay_session_secret_cb_t*)SvIV( *hash_value );
+ }
+
+ return cb;
+}
+
+void
+ssleay_session_secret_cb_free(SSL* s) {
+ ssleay_session_secret_cb_t* cb;
+
+ cb = ssleay_session_secret_cb_get(s);
+
+ if (cb) {
+ if (cb->func) {
+ SvREFCNT_dec(cb->func);
+ cb->func = NULL;
+ }
+
+ if (cb->data) {
+ SvREFCNT_dec(cb->data);
+ cb->data = NULL;
+ }
+ }
+
+ Safefree(cb);
+}
+
+int
+ssleay_session_secret_cb_invoke(SSL* s, void* secret, int *secret_len,
+ STACK_OF(SSL_CIPHER) *peer_ciphers,
+ SSL_CIPHER **cipher, void *arg)
+{
+ dSP;
+
+ int count;
+ int res;
+ int i;
+ AV *ciphers = newAV();
+ SV *pref_cipher = sv_newmortal();
+ ssleay_session_secret_cb_t* cb = (ssleay_session_secret_cb_t*)arg;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(SP);
+ XPUSHs( sv_2mortal( newSVpv(secret, *secret_len)) );
+ for (i=0; i<sk_SSL_CIPHER_num(peer_ciphers); i++)
+ {
+ SSL_CIPHER *c = sk_SSL_CIPHER_value(peer_ciphers,i);
+ av_store(ciphers, i, sv_2mortal(newSVpv(SSL_CIPHER_get_name(c), 0)));
+ }
+ XPUSHs(sv_2mortal(newRV((SV*)ciphers)));
+ XPUSHs(sv_2mortal(newRV(pref_cipher)));
+ if (cb->data) {
+ XPUSHs( cb->data );
+ }
+ PUTBACK;
+
+ if (cb->func == NULL) {
+ croak ("Net::SSLeay: ssleay_session_secret_cb_invoke called, but not "
+ "set to point to any perl function.\n");
+ }
+
+ count = call_sv( cb->func, G_SCALAR );
+
+ SPAGAIN;
+
+ if (count != 1) {
+ croak ("Net::SSLeay: ssleay_session_secret_cb_invoke "
+ "perl function did not return a scalar.\n");
+ }
+
+ res = POPi;
+ if (res)
+ {
+ /* See if there is a preferred cipher selected, if so
+ it is an index into the stack */
+ if (SvIOK(pref_cipher))
+ {
+ *cipher = sk_SSL_CIPHER_value(peer_ciphers, SvIV(pref_cipher));
+ }
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return res;
+}
+
+#endif
+
+ssleay_RSA_generate_key_cb_t*
+ssleay_RSA_generate_key_cb_new(SV* func, SV* data) {
+ ssleay_RSA_generate_key_cb_t* cb;
+
+ New(0, cb, 1, ssleay_RSA_generate_key_cb_t);
+ cb->func = NULL;
+ cb->data = NULL;
+
+ if (func) {
+ SvREFCNT_inc(func);
+ cb->func = func;
+ }
+
+ if (data) {
+ SvREFCNT_inc(data);
+ cb->data = data;
+ }
+
+ return cb;
+}
+
+void
+ssleay_RSA_generate_key_cb_free(ssleay_RSA_generate_key_cb_t* cb) {
+ if (cb) {
+ if (cb->func) {
+ SvREFCNT_dec(cb->func);
+ cb->func = NULL;
+ }
+
+ if (cb->data) {
+ SvREFCNT_dec(cb->data);
+ cb->data = NULL;
+ }
+ }
+
+ Safefree(cb);
+}
+
+void
+ssleay_RSA_generate_key_cb_invoke(int i, int n, void* data) {
+ dSP;
+
+ ssleay_RSA_generate_key_cb_t* cb = (ssleay_RSA_generate_key_cb_t*)data;
+
+ if (cb->func) {
+ int count;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(sp);
+
+ XPUSHs(sv_2mortal( newSViv(i) ));
+ XPUSHs(sv_2mortal( newSViv(n) ));
+
+ if (cb->data)
+ XPUSHs( cb->data );
+
+ PUTBACK;
+
+ count = call_sv( cb->func, G_VOID|G_DISCARD );
+
+ if (count != 0)
+ croak ("Net::SSLeay: ssleay_RSA_generate_key_cb_invoke "
+ "perl function did return something in void context.\n");
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ }
+}
+
+
+MODULE = Net::SSLeay PACKAGE = Net::SSLeay PREFIX = SSL_
+
+PROTOTYPES: ENABLE
+
+double
+constant(name)
+ char * name
+
+int
+hello()
+ CODE:
+ PR("\tSSLeay Hello World!\n");
+ RETVAL = 1;
+ OUTPUT:
+ RETVAL
+
+#define REM1 "============= SSL CONTEXT functions =============="
+
+SSL_CTX *
+SSL_CTX_new()
+ CODE:
+ RETVAL = SSL_CTX_new (SSLv23_method());
+ OUTPUT:
+ RETVAL
+
+SSL_CTX *
+SSL_CTX_v2_new()
+ CODE:
+ RETVAL = SSL_CTX_new (SSLv2_method());
+ OUTPUT:
+ RETVAL
+
+SSL_CTX *
+SSL_CTX_v3_new()
+ CODE:
+ RETVAL = SSL_CTX_new (SSLv3_method());
+ OUTPUT:
+ RETVAL
+
+SSL_CTX *
+SSL_CTX_v23_new()
+ CODE:
+ RETVAL = SSL_CTX_new (SSLv23_method());
+ OUTPUT:
+ RETVAL
+
+SSL_CTX *
+SSL_CTX_tlsv1_new()
+ CODE:
+ RETVAL = SSL_CTX_new (TLSv1_method());
+ OUTPUT:
+ RETVAL
+
+SSL_CTX *
+SSL_CTX_new_with_method(meth)
+ CODE:
+ RETVAL = SSL_CTX_new (SSLv23_method());
+ OUTPUT:
+ RETVAL
+
+void
+SSL_CTX_free(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_add_session(ctx,ses)
+ SSL_CTX * ctx
+ SSL_SESSION * ses
+
+int
+SSL_CTX_remove_session(ctx,ses)
+ SSL_CTX * ctx
+ SSL_SESSION * ses
+
+void
+SSL_CTX_flush_sessions(ctx,tm)
+ SSL_CTX * ctx
+ long tm
+
+int
+SSL_CTX_set_default_verify_paths(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_load_verify_locations(ctx,CAfile,CApath)
+ SSL_CTX * ctx
+ char * CAfile
+ char * CApath
+ CODE:
+ RETVAL = SSL_CTX_load_verify_locations (ctx,
+ CAfile?(*CAfile?CAfile:NULL):NULL,
+ CApath?(*CApath?CApath:NULL):NULL
+ );
+ OUTPUT:
+ RETVAL
+
+void
+SSL_CTX_set_verify(ctx,mode,callback=NULL)
+ SSL_CTX * ctx
+ int mode
+ SV * callback
+ PREINIT:
+ SV* key;
+ char* key_str;
+ STRLEN key_len;
+ CODE:
+
+ if (ssleay_ctx_verify_callbacks == (HV*)NULL)
+ ssleay_ctx_verify_callbacks = newHV();
+
+ key = sv_2mortal(newSViv( (IV)ctx ));
+ key_str = SvPV(key, key_len);
+
+ /* Former versions of SSLeay checked if the callback was a true boolean value
+ * and didn't call it if it was false. Therefor some people set the callback
+ * to '0' if they don't want to use it (IO::Socket::SSL for example). Therefor
+ * we don't execute the callback if it's value isn't something true to retain
+ * backwards compatibility.
+ */
+
+ if (callback == NULL || !SvTRUE(callback)) {
+ hv_delete( ssleay_ctx_verify_callbacks, key_str, key_len, G_DISCARD );
+ SSL_CTX_set_verify( ctx, mode, NULL );
+ } else {
+ hv_store( ssleay_ctx_verify_callbacks, key_str, key_len, newSVsv(callback), 0 );
+ SSL_CTX_set_verify( ctx, mode, &ssleay_verify_callback_invoke );
+ }
+
+int
+SSL_get_error(s,ret)
+ SSL * s
+ int ret
+
+#define REM10 "============= SSL functions =============="
+
+SSL *
+SSL_new(ctx)
+ SSL_CTX * ctx
+
+void
+SSL_free(s)
+ SSL * s
+
+#if 0 /* this seems to be gone in 0.9.0 */
+void
+SSL_debug(file)
+ char * file
+
+#endif
+
+int
+SSL_accept(s)
+ SSL * s
+
+void
+SSL_clear(s)
+ SSL * s
+
+int
+SSL_connect(s)
+ SSL * s
+
+
+#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;
+ CODE:
+ New(0, buf, max, char);
+ ST(0) = sv_newmortal(); /* Undefined to start with */
+ if ((got = SSL_read(s, buf, max)) >= 0)
+ sv_setpvn( ST(0), buf, got);
+ Safefree(buf);
+
+void
+SSL_peek(s,max=32768)
+ SSL * s
+ int max
+ PREINIT:
+ char *buf;
+ int got;
+ CODE:
+ New(0, buf, max, char);
+ ST(0) = sv_newmortal(); /* Undefined to start with */
+ if ((got = SSL_peek(s, buf, max)) >= 0)
+ sv_setpvn( ST(0), buf, got);
+ Safefree(buf);
+
+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 len;
+ INPUT:
+ char * buf = SvPV( ST(3), len);
+ CODE:
+ /*
+ if (SvROK( ST(3) )) {
+ SV* t = SvRV( ST(3) );
+ buf = SvPV( t, len);
+ } else
+ buf = SvPV( ST(3), len);
+ */
+ PRN("write_partial from",from);
+ PRN(&buf[from],len);
+ PRN("write_partial count",count);
+ len -= from;
+ if (len < 0) {
+ croak("from beyound end of buffer");
+ RETVAL = -1;
+ } else
+ RETVAL = SSL_write (s, &(buf[from]), ((STRLEN)count<=len)?count:len);
+ OUTPUT:
+ RETVAL
+
+int
+SSL_use_RSAPrivateKey(s,rsa)
+ SSL * s
+ RSA * rsa
+
+int
+SSL_use_RSAPrivateKey_ASN1(s,d,len)
+ SSL * s
+ unsigned char * d
+ long len
+
+int
+SSL_use_RSAPrivateKey_file(s,file,type)
+ SSL * s
+ char * file
+ int type
+
+int
+SSL_CTX_use_RSAPrivateKey_file(ctx,file,type)
+ SSL_CTX * ctx
+ char * file
+ int type
+
+int
+SSL_use_PrivateKey(s,pkey)
+ SSL * s
+ EVP_PKEY * pkey
+
+int
+SSL_use_PrivateKey_ASN1(pk,s,d,len)
+ int pk
+ SSL * s
+ unsigned char * d
+ long len
+
+int
+SSL_use_PrivateKey_file(s,file,type)
+ SSL * s
+ char * file
+ int type
+
+int
+SSL_CTX_use_PrivateKey_file(ctx,file,type)
+ SSL_CTX * ctx
+ char * file
+ int type
+
+int
+SSL_use_certificate(s,x)
+ SSL * s
+ X509 * x
+
+int
+SSL_use_certificate_ASN1(s,d,len)
+ SSL * s
+ unsigned char * d
+ long len
+
+int
+SSL_use_certificate_file(s,file,type)
+ SSL * s
+ char * file
+ int type
+
+int
+SSL_CTX_use_certificate_file(ctx,file,type)
+ SSL_CTX * ctx
+ char * file
+ int type
+
+const char *
+SSL_state_string(s)
+ SSL * s
+
+const char *
+SSL_rstate_string(s)
+ SSL * s
+
+const char *
+SSL_state_string_long(s)
+ SSL * s
+
+const char *
+SSL_rstate_string_long(s)
+ SSL * s
+
+
+long
+SSL_get_time(ses)
+ SSL_SESSION * ses
+
+long
+SSL_set_time(ses,t)
+ SSL_SESSION * ses
+ long t
+
+long
+SSL_get_timeout(ses)
+ SSL_SESSION * ses
+
+long
+SSL_set_timeout(ses,t)
+ SSL_SESSION * ses
+ long t
+
+void
+SSL_copy_session_id(to,from)
+ SSL * to
+ SSL * from
+
+void
+SSL_set_read_ahead(s,yes=1)
+ SSL * s
+ int yes
+
+int
+SSL_get_read_ahead(s)
+ SSL * s
+
+int
+SSL_pending(s)
+ SSL * s
+
+int
+SSL_CTX_set_cipher_list(s,str)
+ SSL_CTX * s
+ char * str
+
+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
+
+char *
+SSL_get_shared_ciphers(s,buf,len)
+ SSL * s
+ char * buf
+ int len
+
+X509 *
+SSL_get_peer_certificate(s)
+ SSL * s
+
+void
+SSL_set_verify(s,mode,callback)
+ SSL * s
+ int mode
+ SV * callback
+ PREINIT:
+ SV* key;
+ char* key_str;
+ STRLEN key_len;
+ CODE:
+
+ if (ssleay_ctx_verify_callbacks == (HV*)NULL)
+ ssleay_ctx_verify_callbacks = newHV();
+
+ key = sv_2mortal(newSViv( (IV)s ));
+ key_str = SvPV(key, key_len);
+
+ if (callback == NULL) {
+ hv_delete( ssleay_ctx_verify_callbacks, key_str, key_len, G_DISCARD );
+ SSL_set_verify( s, mode, NULL );
+ } else {
+ hv_store( ssleay_ctx_verify_callbacks, key_str, key_len, newSVsv(callback), 0 );
+ 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
+
+int
+i2d_SSL_SESSION(in,pp)
+ SSL_SESSION * in
+ unsigned char * &pp
+
+int
+SSL_set_session(to,ses)
+ SSL * to
+ SSL_SESSION * ses
+
+SSL_SESSION *
+d2i_SSL_SESSION(a,pp,length)
+ SSL_SESSION * &a
+ const unsigned char * &pp
+ long length
+
+#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
+
+long
+SSL_ctrl(ssl,cmd,larg,parg)
+ SSL * ssl
+ int cmd
+ long larg
+ char * parg
+
+long
+SSL_CTX_ctrl(ctx,cmd,larg,parg)
+ SSL_CTX * ctx
+ int cmd
+ long larg
+ char * parg
+
+long
+SSL_get_options(ssl)
+ SSL * ssl
+
+void
+SSL_set_options(ssl,op)
+ SSL * ssl
+ long op
+
+long
+SSL_CTX_get_options(ctx)
+ SSL_CTX * ctx
+
+void
+SSL_CTX_set_options(ctx,op)
+ SSL_CTX * ctx
+ long op
+
+LHASH *
+SSL_CTX_sessions(ctx)
+ SSL_CTX * ctx
+ CODE:
+ /* NOTE: This should be deprecated. Corresponding macro was removed from ssl.h as of 0.9.2 */
+ if (ctx == NULL) croak("NULL SSL context passed as argument.");
+ RETVAL = ctx -> sessions;
+ OUTPUT:
+ RETVAL
+
+unsigned long
+SSL_CTX_sess_number(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_connect(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_connect_good(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_connect_renegotiate(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_accept(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_accept_renegotiate(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_accept_good(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_hits(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_cb_hits(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_misses(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_timeouts(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_cache_full(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_sess_get_cache_size(ctx)
+ SSL_CTX * ctx
+
+void
+SSL_CTX_sess_set_cache_size(ctx,size)
+ SSL_CTX * ctx
+ int size
+
+int
+SSL_want(s)
+ SSL * s
+
+int
+SSL_state(s)
+ SSL * s
+
+BIO_METHOD *
+BIO_f_ssl()
+
+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_library_init()
+ ALIAS:
+ SSLeay_add_ssl_algorithms = 1
+ OpenSSL_add_ssl_algorithms = 2
+ add_ssl_algorithms = 3
+
+void
+ENGINE_load_builtin_engines()
+
+void
+ENGINE_register_all_complete()
+
+ENGINE*
+ENGINE_by_id(id)
+ char * id
+
+int
+ENGINE_set_default(e, flags)
+ ENGINE * e
+ int flags
+
+void
+ERR_load_SSL_strings()
+
+void
+ERR_load_RAND_strings()
+
+int
+RAND_bytes(buf, num)
+ SV *buf
+ int num
+ PREINIT:
+ int rc;
+ unsigned char *random;
+ CODE:
+ New(0, random, num, unsigned char);
+ rc = RAND_bytes(random, num);
+ sv_setpvn(buf, (const char*)random, num);
+ Safefree(random);
+ RETVAL = rc;
+ OUTPUT:
+ RETVAL
+
+int
+RAND_pseudo_bytes(buf, num)
+ SV *buf
+ int num
+ PREINIT:
+ int rc;
+ unsigned char *random;
+ CODE:
+ New(0, random, num, unsigned char);
+ rc = RAND_pseudo_bytes(random, num);
+ sv_setpvn(buf, (const char*)random, num);
+ Safefree(random);
+ RETVAL = rc;
+ OUTPUT:
+ RETVAL
+
+void
+RAND_add(buf, num, entropy)
+ SV *buf
+ int num
+ double entropy
+ PREINIT:
+ STRLEN len;
+ CODE:
+ RAND_add((const void *)SvPV(buf, len), num, entropy);
+
+int
+RAND_poll()
+
+int
+RAND_status()
+
+int
+RAND_egd_bytes(path, bytes)
+ const char *path
+ int bytes
+
+SV *
+RAND_file_name(num)
+ size_t num
+ PREINIT:
+ char *buf;
+ CODE:
+ New(0, buf, num, char);
+ if (!RAND_file_name(buf, num)) {
+ Safefree(buf);
+ XSRETURN_UNDEF;
+ }
+ RETVAL = newSVpv(buf, 0);
+ Safefree(buf);
+ OUTPUT:
+ RETVAL
+
+void
+RAND_seed(buf)
+ PREINIT:
+ STRLEN len;
+ INPUT:
+ char * buf = SvPV( ST(1), len);
+ CODE:
+ RAND_seed (buf, (int)len);
+
+void
+RAND_cleanup()
+
+int
+RAND_load_file(file_name, how_much)
+ char * file_name
+ int how_much
+
+int
+RAND_write_file(file_name)
+ char * file_name
+
+int
+RAND_egd(path)
+ char * path
+
+#define REM40 "Minimal X509 stuff..., this is a bit ugly and should be put in its own modules Net::SSLeay::X509.pm"
+
+X509_NAME*
+X509_get_issuer_name(cert)
+ X509 * cert
+
+X509_NAME*
+X509_get_subject_name(cert)
+ X509 * cert
+
+void
+X509_NAME_oneline(name)
+ X509_NAME * name
+ PREINIT:
+ char * buf;
+ CODE:
+ ST(0) = sv_newmortal(); /* Undefined to start with */
+ if (buf = X509_NAME_oneline(name, NULL, 0))
+ sv_setpvn( ST(0), buf, strlen(buf));
+ OPENSSL_free(buf); /* mem was allocated by openssl */
+
+# WTF is the point of this function?
+# The NID_* constants aren't bound anyway and no one can remember
+# those undocumented numbers anyway.
+void
+X509_NAME_get_text_by_NID(name,nid)
+ X509_NAME * name
+ int nid
+ PREINIT:
+ char* buf;
+ int length;
+ CODE:
+ ST(0) = sv_newmortal(); /* Undefined to start with */
+ length = X509_NAME_get_text_by_NID(name, nid, NULL, 0);
+
+ New(0, buf, length+1, char);
+ if (X509_NAME_get_text_by_NID(name, nid, buf, length + 1))
+ sv_setpvn( ST(0), buf, length + 1);
+ Safefree(buf);
+
+X509 *
+X509_STORE_CTX_get_current_cert(x509_store_ctx)
+ X509_STORE_CTX * x509_store_ctx
+
+void *
+X509_STORE_CTX_get_ex_data(x509_store_ctx,idx)
+ X509_STORE_CTX * x509_store_ctx
+ int idx
+
+void
+X509_get_subjectAltNames(cert)
+ X509 * cert
+ PPCODE:
+ int i, j, count = 0;
+ X509_EXTENSION *subjAltNameExt = NULL;
+ STACK_OF(GENERAL_NAME) *subjAltNameDNs = NULL;
+ GENERAL_NAME *subjAltNameDN = NULL;
+ int num_gnames;
+ if ( (i = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)) >= 0
+ && (subjAltNameExt = X509_get_ext(cert, i))
+ && (subjAltNameDNs = 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)));
+ PUSHs(sv_2mortal(newSVpv((const char*)ASN1_STRING_data(subjAltNameDN->d.otherName->value->value.utf8string), ASN1_STRING_length(subjAltNameDN->d.otherName->value->value.utf8string))));
+ break;
+
+ case GEN_EMAIL:
+ case GEN_DNS:
+ case GEN_URI:
+ EXTEND(SP, 2);
+ count++;
+ PUSHs(sv_2mortal(newSViv(subjAltNameDN->type)));
+ PUSHs(sv_2mortal(newSVpv((const char*)ASN1_STRING_data(subjAltNameDN->d.ia5), ASN1_STRING_length(subjAltNameDN->d.ia5))));
+ 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_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;
+
+ }
+ }
+ }
+ XSRETURN(count * 2);
+
+int
+X509_get_ext_by_NID(x,nid,loc)
+ X509* x
+ int nid
+ int loc
+
+X509_EXTENSION *
+X509_get_ext(x,loc)
+ X509* x
+ int loc
+
+void *
+X509V3_EXT_d2i(ext)
+ X509_EXTENSION *ext
+
+int
+X509_STORE_CTX_get_error(x509_store_ctx)
+ X509_STORE_CTX * x509_store_ctx
+
+int
+X509_STORE_CTX_get_error_depth(x509_store_ctx)
+ X509_STORE_CTX * x509_store_ctx
+
+int
+X509_STORE_CTX_set_ex_data(x509_store_ctx,idx,data)
+ X509_STORE_CTX * x509_store_ctx
+ int idx
+ void * data
+
+void
+X509_STORE_CTX_set_error(x509_store_ctx,s)
+ X509_STORE_CTX * x509_store_ctx
+ int s
+
+void
+X509_STORE_CTX_set_cert(x509_store_ctx,x)
+ X509_STORE_CTX * x509_store_ctx
+ X509 * x
+
+int
+X509_STORE_add_cert(ctx, x)
+ X509_STORE *ctx
+ X509 *x
+
+int
+X509_STORE_add_crl(ctx, x)
+ X509_STORE *ctx
+ X509_CRL *x
+
+void
+X509_STORE_CTX_set_flags(ctx, flags)
+ X509_STORE_CTX *ctx
+ long flags
+
+#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
+
+void
+X509_STORE_set_flags(ctx, flags)
+ X509_STORE *ctx
+ long flags
+
+void
+X509_STORE_set_purpose(ctx, purpose)
+ X509_STORE *ctx
+ int purpose
+
+void
+X509_STORE_set_trust(ctx, trust)
+ X509_STORE *ctx
+ int trust
+
+#endif
+
+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_UTCTIME *
+X509_get_notBefore(cert)
+ X509 * cert
+
+ASN1_UTCTIME *
+X509_get_notAfter(cert)
+ X509 * cert
+
+void
+P_ASN1_UTCTIME_put2string(tm)
+ ASN1_UTCTIME * tm
+ PREINIT:
+ BIO *bp;
+ int i;
+ char buffer[256];
+ CODE:
+ bp = BIO_new(BIO_s_mem());
+ ASN1_UTCTIME_print(bp,tm);
+ i = BIO_read(bp,buffer,255);
+ buffer[i] = '\0';
+ ST(0) = sv_newmortal(); /* Undefined to start with */
+ if ( i > 0 )
+ sv_setpvn( ST(0), buffer, i );
+ BIO_free(bp);
+
+int
+EVP_PKEY_copy_parameters(to,from)
+ EVP_PKEY * to
+ EVP_PKEY * from
+
+void
+PEM_get_string_X509(x509)
+ X509 * x509
+ PREINIT:
+ BIO *bp;
+ int i;
+ char buffer[8196];
+ CODE:
+ bp = BIO_new(BIO_s_mem());
+ PEM_write_bio_X509(bp,x509);
+ i = BIO_read(bp,buffer,8195);
+ buffer[i] = '\0';
+ ST(0) = sv_newmortal(); /* Undefined to start with */
+ if ( i > 0 )
+ sv_setpvn( ST(0), buffer, i );
+ BIO_free(bp);
+
+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;
+ }
+
+void
+MD4(data)
+ PREINIT:
+ STRLEN len;
+ unsigned char md[MD4_DIGEST_LENGTH];
+ unsigned char * ret;
+ INPUT:
+ unsigned char* data = (unsigned char *) SvPV( ST(0), len );
+ CODE:
+ ret = MD4(data,len,md);
+ if (ret!=NULL) {
+ XSRETURN_PVN((char *) md, MD4_DIGEST_LENGTH);
+ } else {
+ XSRETURN_UNDEF;
+ }
+
+void
+MD5(data)
+ PREINIT:
+ STRLEN len;
+ unsigned char md[MD5_DIGEST_LENGTH];
+ unsigned char * ret;
+ INPUT:
+ unsigned char * data = (unsigned char *) SvPV( ST(0), len);
+ CODE:
+ ret = MD5(data,len,md);
+ if (ret!=NULL) {
+ XSRETURN_PVN((char *) md, MD5_DIGEST_LENGTH);
+ } else {
+ XSRETURN_UNDEF;
+ }
+
+SSL_METHOD *
+SSLv2_method()
+
+SSL_METHOD *
+SSLv3_method()
+
+SSL_METHOD *
+TLSv1_method()
+
+int
+SSL_set_ssl_method(ssl, method)
+ SSL * ssl
+ SSL_METHOD * method
+
+SSL_METHOD *
+SSL_get_ssl_method(ssl)
+ SSL * ssl
+
+#define REM_AUTOMATICALLY_GENERATED_1_09
+
+BIO *
+BIO_new_buffer_ssl_connect(ctx)
+ SSL_CTX * ctx
+
+BIO *
+BIO_new_file(filename,mode)
+ char * filename
+ char * mode
+
+BIO *
+BIO_new_ssl(ctx,client)
+ SSL_CTX * ctx
+ int client
+
+BIO *
+BIO_new_ssl_connect(ctx)
+ SSL_CTX * ctx
+
+BIO *
+BIO_new(type)
+ BIO_METHOD * type;
+
+int
+BIO_free(bio)
+ BIO * bio;
+
+void
+BIO_read(s,max=32768)
+ BIO * s
+ int max
+ PREINIT:
+ char *buf = NULL;
+ int got;
+ CODE:
+ New(0, buf, max, char);
+ ST(0) = sv_newmortal(); /* Undefined to start with */
+ if ((got = BIO_read(s, buf, max)) >= 0)
+ sv_setpvn( ST(0), buf, got);
+ Safefree(buf);
+
+int
+BIO_write(s,buf)
+ BIO * s
+ PREINIT:
+ STRLEN len;
+ INPUT:
+ char * buf = SvPV( ST(1), len);
+ CODE:
+ RETVAL = BIO_write (s, buf, (int)len);
+ OUTPUT:
+ RETVAL
+
+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
+
+char *
+SSL_CIPHER_description(cipher,buf,size)
+ SSL_CIPHER * cipher
+ char * buf
+ int size
+
+int
+SSL_CIPHER_get_bits(c,alg_bits)
+ SSL_CIPHER * c
+ int * alg_bits
+
+int
+SSL_COMP_add_compression_method(id,cm)
+ int id
+ COMP_METHOD * cm
+
+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
+
+void *
+SSL_CTX_get_ex_data(ssl,idx)
+ SSL_CTX * ssl
+ int idx
+
+int
+SSL_CTX_get_quiet_shutdown(ctx)
+ SSL_CTX * ctx
+
+long
+SSL_CTX_get_timeout(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_get_verify_depth(ctx)
+ SSL_CTX * ctx
+
+int
+SSL_CTX_get_verify_mode(ctx)
+ SSL_CTX * ctx
+
+void
+SSL_CTX_set_cert_store(ctx,store)
+ SSL_CTX * ctx
+ X509_STORE * store
+
+X509_STORE *
+SSL_CTX_get_cert_store(ctx)
+ SSL_CTX * ctx
+
+void
+SSL_CTX_set_cert_verify_callback(ctx,func,data=NULL)
+ SSL_CTX* ctx
+ SV* func
+ SV* data
+ PREINIT:
+ ssleay_ctx_cert_verify_cb_t* cb;
+ CODE:
+ if (func == NULL || func == &PL_sv_undef) {
+ ssleay_ctx_cert_verify_cb_free(ctx);
+ SSL_CTX_set_cert_verify_callback(ctx, NULL, NULL);
+ } else {
+ cb = ssleay_ctx_cert_verify_cb_new(ctx, func, data);
+ SSL_CTX_set_cert_verify_callback(ctx, ssleay_ctx_cert_verify_cb_invoke, cb);
+ }
+
+void
+SSL_CTX_set_client_CA_list(ctx,list)
+ SSL_CTX * ctx
+ X509_NAME_STACK * list
+
+void
+SSL_CTX_set_default_passwd_cb(ctx,func=NULL)
+ SSL_CTX * ctx
+ SV * func
+ PREINIT:
+ ssleay_ctx_passwd_cb_t* cb;
+ CODE:
+ if (func == NULL || func == &PL_sv_undef) {
+ ssleay_ctx_passwd_cb_free_func(ctx);
+ SSL_CTX_set_default_passwd_cb(ctx, NULL);
+ } else {
+ cb = ssleay_ctx_passwd_cb_get(ctx);
+ ssleay_ctx_passwd_cb_func_set(ctx, func);
+ SSL_CTX_set_default_passwd_cb(ctx, &ssleay_ctx_passwd_cb_invoke);
+ SSL_CTX_set_default_passwd_cb_userdata(ctx, (void*)cb);
+ }
+
+void
+SSL_CTX_set_default_passwd_cb_userdata(ctx,u=NULL)
+ SSL_CTX * ctx
+ SV* u
+ CODE:
+ if (u == NULL) {
+ ssleay_ctx_passwd_cb_free_userdata(ctx);
+ } else {
+ ssleay_ctx_passwd_cb_userdata_set(ctx, u);
+ }
+
+int
+SSL_CTX_set_ex_data(ssl,idx,data)
+ SSL_CTX * ssl
+ int idx
+ void * data
+
+int
+SSL_CTX_set_purpose(s,purpose)
+ SSL_CTX * s
+ int purpose
+
+void
+SSL_CTX_set_quiet_shutdown(ctx,mode)
+ SSL_CTX * ctx
+ int mode
+
+int
+SSL_CTX_set_ssl_version(ctx,meth)
+ SSL_CTX * ctx
+ SSL_METHOD * meth
+
+long
+SSL_CTX_set_timeout(ctx,t)
+ SSL_CTX * ctx
+ long t
+
+int
+SSL_CTX_set_trust(s,trust)
+ SSL_CTX * s
+ int trust
+
+void
+SSL_CTX_set_verify_depth(ctx,depth)
+ SSL_CTX * ctx
+ int depth
+
+int
+SSL_CTX_use_certificate(ctx,x)
+ SSL_CTX * ctx
+ X509 * x
+
+int
+SSL_CTX_use_certificate_chain_file(ctx,file)
+ SSL_CTX * ctx
+ const char * file
+
+int
+SSL_CTX_use_PrivateKey(ctx,pkey)
+ SSL_CTX * ctx
+ EVP_PKEY * pkey
+
+int
+SSL_CTX_use_RSAPrivateKey(ctx,rsa)
+ SSL_CTX * ctx
+ RSA * rsa
+
+int
+SSL_do_handshake(s)
+ SSL * s
+
+SSL *
+SSL_dup(ssl)
+ SSL * ssl
+
+SSL_CIPHER *
+SSL_get_current_cipher(s)
+ SSL * s
+
+long
+SSL_get_default_timeout(s)
+ SSL * s
+
+void *
+SSL_get_ex_data(ssl,idx)
+ SSL * ssl
+ int idx
+
+size_t
+SSL_get_finished(s,buf,count)
+ SSL * s
+ void * buf
+ size_t count
+
+size_t
+SSL_get_peer_finished(s,buf,count)
+ SSL * s
+ void * buf
+ size_t count
+
+int
+SSL_get_quiet_shutdown(ssl)
+ SSL * ssl
+
+int
+SSL_get_shutdown(ssl)
+ SSL * ssl
+
+int
+SSL_get_verify_depth(s)
+ SSL * s
+
+int
+SSL_get_verify_mode(s)
+ SSL * s
+
+long
+SSL_get_verify_result(ssl)
+ SSL * ssl
+
+int
+SSL_renegotiate(s)
+ SSL * s
+
+int
+SSL_SESSION_cmp(a,b)
+ SSL_SESSION * a
+ SSL_SESSION * b
+
+void *
+SSL_SESSION_get_ex_data(ss,idx)
+ SSL_SESSION * ss
+ int idx
+
+long
+SSL_SESSION_get_time(s)
+ SSL_SESSION * s
+
+long
+SSL_SESSION_get_timeout(s)
+ SSL_SESSION * s
+
+int
+SSL_SESSION_print_fp(fp,ses)
+ FILE * fp
+ SSL_SESSION * ses
+
+int
+SSL_SESSION_set_ex_data(ss,idx,data)
+ SSL_SESSION * ss
+ int idx
+ void * data
+
+long
+SSL_SESSION_set_time(s,t)
+ SSL_SESSION * s
+ long t
+
+long
+SSL_SESSION_set_timeout(s,t)
+ SSL_SESSION * s
+ long t
+
+void
+SSL_set_accept_state(s)
+ SSL * s
+
+void
+SSL_set_client_CA_list(s,list)
+ SSL * s
+ X509_NAME_STACK * list
+
+void
+SSL_set_connect_state(s)
+ SSL * s
+
+int
+SSL_set_ex_data(ssl,idx,data)
+ SSL * ssl
+ int idx
+ void * data
+
+void
+SSL_set_info_callback(ssl,cb)
+ SSL * ssl
+ cb_ssl_int_int_ret_void * cb
+
+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
+SSL_set_verify_result(ssl,v)
+ SSL * ssl
+ long v
+
+int
+SSL_shutdown(s)
+ SSL * s
+
+int
+SSL_version(ssl)
+ SSL * ssl
+
+#define REM_MANUALLY_ADDED_1_09
+
+X509_NAME_STACK *
+SSL_load_client_CA_file(file)
+ const char * file
+
+int
+SSL_add_file_cert_subjects_to_stack(stackCAs,file)
+ X509_NAME_STACK * stackCAs
+ const char * file
+
+#ifndef WIN32
+#ifndef VMS
+#ifndef MAC_OS_pre_X
+
+int
+SSL_add_dir_cert_subjects_to_stack(stackCAs,dir)
+ X509_NAME_STACK * stackCAs
+ const char * dir
+
+#endif
+#endif
+#endif
+
+int
+SSL_CTX_get_ex_new_index(argl,argp,new_func,dup_func,free_func)
+ long argl
+ void * argp
+ CRYPTO_EX_new * new_func
+ CRYPTO_EX_dup * dup_func
+ CRYPTO_EX_free * free_func
+
+int
+SSL_CTX_set_session_id_context(ctx,sid_ctx,sid_ctx_len)
+ SSL_CTX * ctx
+ const unsigned char * sid_ctx
+ unsigned int sid_ctx_len
+
+int
+SSL_set_session_id_context(ssl,sid_ctx,sid_ctx_len)
+ SSL * ssl
+ const unsigned char * sid_ctx
+ unsigned int sid_ctx_len
+
+void
+SSL_CTX_set_tmp_rsa_callback(ctx, cb)
+ SSL_CTX * ctx
+ cb_ssl_int_int_ret_RSA * cb
+
+void
+SSL_set_tmp_rsa_callback(ssl, cb)
+ SSL * ssl
+ cb_ssl_int_int_ret_RSA * cb
+
+void
+SSL_CTX_set_tmp_dh_callback(ctx, dh)
+ SSL_CTX * ctx
+ cb_ssl_int_int_ret_DH * dh
+
+void
+SSL_set_tmp_dh_callback(ssl,dh)
+ SSL * ssl
+ cb_ssl_int_int_ret_DH * dh
+
+int
+SSL_get_ex_new_index(argl, argp, new_func, dup_func, free_func)
+ long argl
+ void * argp
+ CRYPTO_EX_new * new_func
+ CRYPTO_EX_dup * dup_func
+ CRYPTO_EX_free * free_func
+
+int
+SSL_SESSION_get_ex_new_index(argl, argp, new_func, dup_func, free_func)
+ long argl
+ void * argp
+ CRYPTO_EX_new * new_func
+ CRYPTO_EX_dup * dup_func
+ CRYPTO_EX_free * free_func
+
+#define REM_SEMIAUTOMATIC_MACRO_GEN_1_09
+
+long
+SSL_clear_num_renegotiations(ssl)
+ SSL * ssl
+ CODE:
+ RETVAL = SSL_ctrl(ssl,SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_CTX_add_extra_chain_cert(ctx,x509)
+ SSL_CTX * ctx
+ X509 * x509
+ CODE:
+ RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char*)x509);
+ OUTPUT:
+ RETVAL
+
+void *
+SSL_CTX_get_app_data(ctx)
+ SSL_CTX * ctx
+ CODE:
+ RETVAL = SSL_CTX_get_ex_data(ctx,0);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_CTX_get_mode(ctx)
+ SSL_CTX * ctx
+ CODE:
+ RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_MODE,0,NULL);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_CTX_get_read_ahead(ctx)
+ SSL_CTX * ctx
+ CODE:
+ RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_CTX_get_session_cache_mode(ctx)
+ SSL_CTX * ctx
+ CODE:
+ RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_CTX_need_tmp_RSA(ctx)
+ SSL_CTX * ctx
+ CODE:
+ RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL);
+ OUTPUT:
+ RETVAL
+
+int
+SSL_CTX_set_app_data(ctx,arg)
+ SSL_CTX * ctx
+ char * arg
+ CODE:
+ RETVAL = SSL_CTX_set_ex_data(ctx,0,arg);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_CTX_set_mode(ctx,op)
+ SSL_CTX * ctx
+ long op
+ CODE:
+ RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_MODE,op,NULL);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_CTX_set_read_ahead(ctx,m)
+ SSL_CTX * ctx
+ long m
+ CODE:
+ RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_CTX_set_session_cache_mode(ctx,m)
+ SSL_CTX * ctx
+ long m
+ CODE:
+ RETVAL = SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_CTX_set_tmp_dh(ctx,dh)
+ SSL_CTX * ctx
+ DH * dh
+
+long
+SSL_CTX_set_tmp_rsa(ctx,rsa)
+ SSL_CTX * ctx
+ RSA * rsa
+
+void *
+SSL_get_app_data(s)
+ SSL * s
+ CODE:
+ RETVAL = SSL_get_ex_data(s,0);
+ OUTPUT:
+ RETVAL
+
+int
+SSL_get_cipher_bits(s,np)
+ SSL * s
+ int * np
+ CODE:
+ RETVAL = SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_get_mode(ssl)
+ SSL * ssl
+ CODE:
+ RETVAL = SSL_ctrl(ssl,SSL_CTRL_MODE,0,NULL);
+ OUTPUT:
+ RETVAL
+
+int
+SSL_get_state(ssl)
+ SSL * ssl
+ CODE:
+ RETVAL = SSL_state(ssl);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_need_tmp_RSA(ssl)
+ SSL * ssl
+ CODE:
+ RETVAL = SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_num_renegotiations(ssl)
+ SSL * ssl
+ CODE:
+ RETVAL = SSL_ctrl(ssl,SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL);
+ OUTPUT:
+ RETVAL
+
+void *
+SSL_SESSION_get_app_data(ses)
+ SSL_SESSION * ses
+ CODE:
+ RETVAL = SSL_SESSION_get_ex_data(ses,0);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_session_reused(ssl)
+ SSL * ssl
+ CODE:
+ RETVAL = SSL_ctrl(ssl,SSL_CTRL_GET_SESSION_REUSED,0,NULL);
+ OUTPUT:
+ RETVAL
+
+int
+SSL_SESSION_set_app_data(s,a)
+ SSL_SESSION * s
+ void * a
+ CODE:
+ RETVAL = SSL_SESSION_set_ex_data(s,0,(char *)a);
+ OUTPUT:
+ RETVAL
+
+int
+SSL_set_app_data(s,arg)
+ SSL * s
+ void * arg
+ CODE:
+ RETVAL = SSL_set_ex_data(s,0,(char *)arg);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_set_mode(ssl,op)
+ SSL * ssl
+ long op
+ CODE:
+ RETVAL = SSL_ctrl(ssl,SSL_CTRL_MODE,op,NULL);
+ OUTPUT:
+ RETVAL
+
+int
+SSL_set_pref_cipher(s,n)
+ SSL * s
+ const char * n
+ CODE:
+ RETVAL = SSL_set_cipher_list(s,n);
+ OUTPUT:
+ RETVAL
+
+long
+SSL_set_tmp_dh(ssl,dh)
+ SSL * ssl
+ DH * dh
+
+long
+SSL_set_tmp_rsa(ssl,rsa)
+ SSL * ssl
+ char * rsa
+ CODE:
+ RETVAL = SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa);
+ OUTPUT:
+ RETVAL
+
+RSA *
+RSA_generate_key(bits,e,perl_cb=NULL,perl_cb_arg=NULL)
+ int bits
+ unsigned long e
+ SV* perl_cb
+ SV* perl_cb_arg
+ PREINIT:
+ ssleay_RSA_generate_key_cb_t* cb = NULL;
+ CODE:
+ cb = ssleay_RSA_generate_key_cb_new(perl_cb, perl_cb_arg);
+ RETVAL = RSA_generate_key(bits, e, ssleay_RSA_generate_key_cb_invoke, cb);
+ ssleay_RSA_generate_key_cb_free(cb);
+ OUTPUT:
+ RETVAL
+
+void
+RSA_free(r)
+ RSA * r
+
+void
+X509_free(a)
+ X509 * a
+
+DH *
+PEM_read_bio_DHparams(bio,x=NULL,cb=NULL,u=NULL)
+ BIO * bio
+ void * x
+ pem_password_cb * cb
+ void * u
+
+X509_CRL *
+PEM_read_bio_X509_CRL(bio,x=NULL,cb=NULL,u=NULL)
+ BIO * bio
+ void * x
+ pem_password_cb * cb
+ void * u
+
+void
+DH_free(dh)
+ DH * dh
+
+long
+SSL_total_renegotiations(ssl)
+ SSL * ssl
+ CODE:
+ RETVAL = SSL_ctrl(ssl,SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL);
+ OUTPUT:
+ RETVAL
+
+void
+SSL_SESSION_get_master_key(s)
+ SSL_SESSION * s
+ CODE:
+ ST(0) = sv_newmortal(); /* Undefined to start with */
+ sv_setpvn(ST(0), (const char*)s->master_key, s->master_key_length);
+
+void
+SSL_SESSION_set_master_key(s,key)
+ SSL_SESSION * s
+ PREINIT:
+ STRLEN len;
+ INPUT:
+ char * key = SvPV(ST(1), len);
+ CODE:
+ memcpy(s->master_key, key, len);
+ s->master_key_length = len;
+
+void
+SSL_get_client_random(s)
+ SSL * s
+ CODE:
+ ST(0) = sv_newmortal(); /* Undefined to start with */
+ sv_setpvn(ST(0), (const char*)s->s3->client_random, SSL3_RANDOM_SIZE);
+
+void
+SSL_get_server_random(s)
+ SSL * s
+ CODE:
+ ST(0) = sv_newmortal(); /* Undefined to start with */
+ sv_setpvn(ST(0), (const char*)s->s3->server_random, SSL3_RANDOM_SIZE);
+
+int
+SSL_get_keyblock_size(s)
+ SSL * s
+ CODE:
+ if (s == NULL ||
+ s->enc_read_ctx == NULL ||
+ s->enc_read_ctx->cipher == NULL ||
+ s->read_hash == NULL)
+ {
+ RETVAL = -1;
+ }
+ else
+ {
+ const EVP_CIPHER *c;
+ const EVP_MD *h;
+ c = s->enc_read_ctx->cipher;
+#if OPENSSL_VERSION_NUMBER >= 0x00909000L
+ h = EVP_MD_CTX_md(s->read_hash);
+#else
+ h = s->read_hash;
+#endif
+
+ RETVAL = 2 * (EVP_CIPHER_key_length(c) +
+ EVP_MD_size(h) +
+ EVP_CIPHER_iv_length(c));
+ }
+ OUTPUT:
+ RETVAL
+
+
+
+#ifdef SSL_F_SSL_SET_HELLO_EXTENSION
+int
+SSL_set_hello_extension(s, type, data)
+ SSL * s
+ int type
+ PREINIT:
+ STRLEN len;
+ INPUT:
+ char * data = SvPV( ST(2), len);
+ CODE:
+ RETVAL = SSL_set_hello_extension(s, type, data, len);
+ OUTPUT:
+ RETVAL
+
+void
+SSL_set_session_secret_cb(s,func,data=NULL)
+ SSL * s
+ SV* func
+ SV* data
+ PREINIT:
+ ssleay_session_secret_cb_t* cb;
+ CODE:
+ if (func == NULL || func == &PL_sv_undef) {
+ ssleay_session_secret_cb_free(s);
+ SSL_set_session_secret_cb(s, NULL, NULL);
+ } else {
+ cb = ssleay_session_secret_cb_new(s, func, data);
+ SSL_set_session_secret_cb(s, (int (*)(SSL *s, void *secret, int *secret_len,
+ STACK_OF(SSL_CIPHER) *peer_ciphers,
+ SSL_CIPHER **cipher, void *arg))&ssleay_session_secret_cb_invoke, cb);
+ }
+
+#endif
+
+#define REM_EOF "/* EOF - SSLeay.xs */"