[libnet-ssleay-perl] 01/04: Imported Upstream version 1.77

dom at earth.li dom at earth.li
Tue Aug 9 01:07:45 UTC 2016


This is an automated email from the git hooks/post-receive script.

dom pushed a commit to branch master
in repository libnet-ssleay-perl.

commit e669abf0dd8ca93f3d14079cfc398062a96e2315
Author: Dominic Hargreaves <dom at earth.li>
Date:   Mon Aug 8 23:25:32 2016 +0100

    Imported Upstream version 1.77
---
 Changes                                  |  43 +++
 MANIFEST                                 |   2 +
 META.yml                                 |  11 +-
 Makefile.PL                              |   2 +-
 README                                   |  14 +-
 SSLeay.xs                                | 444 ++++++++++++++++++++++++++-----
 inc/Module/Install.pm                    |  22 +-
 inc/Module/Install/Base.pm               |   2 +-
 inc/Module/Install/Can.pm                |   2 +-
 inc/Module/Install/External.pm           |   2 +-
 inc/Module/Install/Fetch.pm              |   2 +-
 inc/Module/Install/Makefile.pm           |   4 +-
 inc/Module/Install/Metadata.pm           |   6 +-
 inc/Module/Install/PRIVATE/Net/SSLeay.pm |   1 -
 inc/Module/Install/Win32.pm              |   2 +-
 inc/Module/Install/WriteAll.pm           |   2 +-
 lib/Net/SSLeay.pm                        |   4 +-
 lib/Net/SSLeay.pod                       | 148 ++++++++++-
 t/local/32_x509_get_cert_info.t          |   2 +-
 t/local/35_ephemeral.t                   |   2 +-
 t/local/63_ec_key_generate_key.t         |  35 +++
 t/local/64_ticket_sharing.t              | 270 +++++++++++++++++++
 22 files changed, 917 insertions(+), 105 deletions(-)

diff --git a/Changes b/Changes
index 7d19fb1..876482e 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,48 @@
 Revision history for Perl extension Net::SSLeay.
 
+1.77	 2016-08-01
+	 Fixed incorrect size to memset in tlsext_ticket_key_cb_invoke.
+
+1.76	 2016-07-31
+	 Replaced bzero with memset. Bzero not present on windows.
+
+1.75  2016-07-31
+     Compatibility with OpenSSL 1.1, tested with openssl-1.1.0-pre5:
+     - Conditionally remove threading locking code, not needed in 1.1
+     - Rewrite code that accesses inside X509_ATTRIBUTE struct.
+     - SSL_CTX_need_tmp_RSA, SSL_CTX_set_tmp_rsa,
+       SSL_CTX_set_tmp_rsa_callback, SSL_set_tmp_rsa_callback support
+       not available in 1.1.
+     - SSL_session_reused is now native
+     - SSL_get_keyblock_size modifed to use new API
+     - OCSP functions modified to use new API under 1.1
+     - SSL_set_state removed with 1.1
+     - SSL_get_state and SSL_state are now equivalent and available in all
+       versions
+     - SSL_CTX_v2_new removed
+     - SESSION_set_master_key removed with 1.1. Code that previously used
+       SESSION_set_master_key must now set $secret in the session_secret
+       callback set with SSL_set_session_secret_cb
+     - With 1.1, $secret in the session_secret
+       callback set with SSL_set_session_secret_cb can be changed to alter
+       the master key (required by EAP-FAST).
+     Added a function EC_KEY_generate_key similar to RSA_generate_key and a
+     function EVP_PKEY_assign_EC_KEY similar to EVP_PKEY_assign_RSA. Using
+     these functions it is easy to create and use EC keys in the same way as
+     RSA keys. Patch provided by Steffen Ullrich. Thanks Steffen.
+     Testing with LibreSSL 2.4.1, with compatibility patch from Steffen
+     Ullrich. Thanks Steffen.
+     Patch from Steffen Ulrich provides  support for cross context (and cross process)
+     session sharing using the stateless TLS session tickets. It uses the
+     SSL_CTX_set_tlsext_ticket_key_cb function to manage the encryption and
+     decryption of the tickets but provides a more simplified
+     interface. Includes new function CTX_set_tlsext_ticket_getkey_cb.
+     To not conflict with the OpenSSL name in case the more complex interface
+     will be implemented ever the current simplified interface is called
+     slightly different: CTX_set_tlsext_ticket_*get*key_cb. 
+     Added documentation about downloading latest version from SVN.
+     Added missing Module/install files to SVN.
+
 1.74 2016-04-12
      README.OSX was missing from the distribution
 
diff --git a/MANIFEST b/MANIFEST
index ae92ebb..5e99e6e 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -113,5 +113,7 @@ t/local/42_info_callback.t
 t/local/50_digest.t
 t/local/61_threads-cb-crash.t
 t/local/62_threads-ctx_new-deadlock.t
+t/local/63_ec_key_generate_key.t
+t/local/64_ticket_sharing.t
 t/local/kwalitee.t
 typemap
diff --git a/META.yml b/META.yml
index 34adafd..413cc48 100644
--- a/META.yml
+++ b/META.yml
@@ -1,5 +1,4 @@
 ---
-name: Net-SSLeay
 abstract: 'Perl extension for using OpenSSL'
 author:
   - 'Maintained by Mike McCauley and Florian Ragwitz since November 2005'
@@ -9,11 +8,12 @@ configure_requires:
   ExtUtils::MakeMaker: 6.36
 distribution_type: module
 dynamic_config: 1
-generated_by: 'Module::Install version 1.06'
+generated_by: 'Module::Install version 1.16'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
   version: 1.4
+name: Net-SSLeay
 no_index:
   directory:
     - examples
@@ -24,8 +24,9 @@ no_index:
 requires:
   MIME::Base64: 0
   Test::More: 0.60_01
-  perl: 5.005
+  perl: '5.005'
 resources:
   bugtracker: https://rt.cpan.org/Public/Dist/Display.html?Name=net-ssleay
-  repository: svn://svn.debian.org/svn/net-ssleay
-version: '1.74'
+  license: http://dev.perl.org/licenses/
+  repository: http://svn.debian.org/wsvn/net-ssleay
+version: '1.77'
diff --git a/Makefile.PL b/Makefile.PL
index bfd98b6..c841cef 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -8,7 +8,7 @@ use Config;
 use File::Spec;
 
 name('Net-SSLeay');
-license        'perl';
+license('perl');
 all_from('lib/Net/SSLeay.pm');
 
 ssleay();
diff --git a/README b/README
index 43e4029..608eb72 100644
--- a/README
+++ b/README
@@ -1,17 +1,23 @@
 README - Net::SSLeay Perl module for using OpenSSL
-$Id: README 461 2016-04-04 03:32:38Z mikem-guest $
+$Id: README 472 2016-07-28 09:14:26Z mikem-guest $
 
 By popular demand...
 --------------------
 
    perl -MNet::SSLeay -e '($p)=Net::SSLeay::get_https("www.openssl.org", 443, "/"); print $p'
 
+for the latest and possibly unstable version from SVN:
+
+   svn co svn://svn.debian.org/svn/net-ssleay
+
+
 Prerequisites
 -------------
 
-perl-5.6.1     though anything starting from perl5.003 probably works.
+perl-5.6.1     though anything starting from perl5.003 probably works. Later
+	       versions are OK.
 
-OpenSSL-0.9.6j through to at least OpenSSL-1.0.2 and probably later
+OpenSSL-0.9.6j through to at least OpenSSL-1.1 and probably later
 	       http://www.openssl.org/ - On Linux, you can either build and
 	       install OpenSSL from scratch (its very portable) or you can
 	       install the appropriate OpenSSL 'devel' package for your Linux
@@ -25,6 +31,8 @@ Note: SSLeay is no longer supported. If you want to use Net::SSLeay with
       in OpenSSL-0.9.2b. OpenSSL-0.9.1c support has also been dropped,
       version 1.03 was the last one to support that.
 
+LibreSSL is also supported.
+
 You should use the same C compiler and options to compile OpenSSL,
 perl, and Net::SSLeay. This is the only supported configuration.
 If you insist on using different compilers (perhaps because you
diff --git a/SSLeay.xs b/SSLeay.xs
index 9d0494c..9b86989 100644
--- a/SSLeay.xs
+++ b/SSLeay.xs
@@ -8,7 +8,7 @@
  *
  * Change data removed. See Changes
  *
- * $Id: SSLeay.xs 458 2015-12-15 21:23:48Z mikem-guest $
+ * $Id: SSLeay.xs 477 2016-07-31 20:24:00Z mikem-guest $
  * 
  * The distribution and use of this module are subject to the conditions
  * listed in LICENSE file at the root of the Net-SSLeay
@@ -237,8 +237,10 @@ START_MY_CXT
 
 #ifdef USE_ITHREADS
 static perl_mutex LIB_init_mutex;
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 static perl_mutex *GLOBAL_openssl_mutex = NULL;
 #endif
+#endif
 static int LIB_initialized;
 
 UV get_my_thread_id(void) /* returns threads->tid() value */
@@ -277,6 +279,8 @@ UV get_my_thread_id(void) /* returns threads->tid() value */
  */
 #if defined(USE_ITHREADS) && defined(OPENSSL_THREADS)
 
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 static void openssl_locking_function(int mode, int type, const char *file, int line)
 {
     PR3("openssl_locking_function %d %d\n", mode, type);
@@ -331,6 +335,7 @@ void openssl_dynlocking_destroy_function (struct CRYPTO_dynlock_value *l, const
     MUTEX_DESTROY(&l->mutex);
     Safefree(l);
 }
+#endif
 
 void openssl_threads_init(void)
 {
@@ -338,6 +343,7 @@ void openssl_threads_init(void)
 
     PR1("STARTED: openssl_threads_init\n");
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
     /* initialize static locking */
     if ( !CRYPTO_get_locking_callback() ) {
 #if OPENSSL_VERSION_NUMBER < 0x10000000L
@@ -371,6 +377,7 @@ void openssl_threads_init(void)
         CRYPTO_set_dynlock_lock_callback(openssl_dynlocking_lock_function);
         CRYPTO_set_dynlock_destroy_callback(openssl_dynlocking_destroy_function);
     }
+#endif 
 }
 
 #endif
@@ -395,7 +402,9 @@ static void handler_list_md_fn(const EVP_MD *m, const char *from, const char *to
   if (!m) return;                                           /* Skip aliases */
   mname = OBJ_nid2ln(EVP_MD_type(m));
   if (strcmp(from, mname)) return;                          /* Skip shortnames */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
   if (EVP_MD_flags(m) & EVP_MD_FLAG_PKEY_DIGEST) return;    /* Skip clones */
+#endif
   if (strchr(mname, ' ')) mname= EVP_MD_name(m);
   av_push(arg, newSVpv(mname,0));
 }
@@ -799,6 +808,7 @@ int ssleay_session_secret_cb_invoke(SSL* s, void* secret, int *secret_len,
     AV *ciphers = newAV();
     SV *pref_cipher = sv_newmortal();
     SV * cb_func, *cb_data;
+    SV * secretsv;
 
     PR1("STARTED: ssleay_session_secret_cb_invoke\n");
     cb_func = cb_data_advanced_get(arg, "ssleay_session_secret_cb!!func");
@@ -811,8 +821,8 @@ int ssleay_session_secret_cb_invoke(SSL* s, void* secret, int *secret_len,
     SAVETMPS;
 
     PUSHMARK(SP);
-
-    XPUSHs( sv_2mortal( newSVpv(secret, *secret_len)) );
+    secretsv = sv_2mortal( newSVpv(secret, *secret_len));
+    XPUSHs(secretsv);
     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)));
@@ -835,6 +845,13 @@ int ssleay_session_secret_cb_invoke(SSL* s, void* secret, int *secret_len,
         /* 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));
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+	/* Use any new master secret set by the callback function in secret */
+	STRLEN newsecretlen;
+	char* newsecretdata = SvPV(secretsv, newsecretlen);
+	memcpy(secret, newsecretdata, newsecretlen);
+#endif
     }
 
     PUTBACK;
@@ -1221,6 +1238,100 @@ void ssleay_ctx_info_cb_invoke(const SSL *ssl, int where, int ret)
     LEAVE;
 }
 
+/* 
+ * Support for tlsext_ticket_key_cb_invoke was already in 0.9.8 but it was
+ * broken in various ways during the various 1.0.0* versions.
+ * Better enable it only starting with 1.0.1.
+*/
+#if defined(SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB) && OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_TLSEXT)
+#define NET_SSLEAY_CAN_TICKET_KEY_CB
+
+int tlsext_ticket_key_cb_invoke(
+    SSL *ssl,
+    unsigned char *key_name,
+    unsigned char *iv,
+    EVP_CIPHER_CTX *ectx,
+    HMAC_CTX *hctx,
+    int enc
+){
+
+    dSP;
+    int count;
+    SV *cb_func, *cb_data;
+    SV *sv_name, *sv_key;
+    STRLEN svlen;
+    unsigned char *key;  /* key[0..15] aes, key[16..32] hmac */
+    unsigned char *name;
+    SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
+
+    PR1("STARTED: tlsext_ticket_key_cb_invoke\n");
+    cb_func = cb_data_advanced_get(ctx, "tlsext_ticket_key_cb!!func");
+    cb_data = cb_data_advanced_get(ctx, "tlsext_ticket_key_cb!!data");
+
+    if (!SvROK(cb_func) || (SvTYPE(SvRV(cb_func)) != SVt_PVCV))
+	croak("callback must be a code reference");
+
+    ENTER;
+    SAVETMPS;
+    PUSHMARK(SP);
+    XPUSHs(sv_2mortal(newSVsv(cb_data)));
+
+    if (!enc) {
+	/* call as getkey(data,this_name) -> (key,current_name) */
+	XPUSHs(sv_2mortal(newSVpv(key_name,16)));
+    } else {
+	/* call as getkey(data) -> (key,current_name) */
+    }
+
+
+    PUTBACK;
+    count = call_sv( cb_func, G_ARRAY );
+
+    SPAGAIN;
+    if (count>0) sv_name = POPs;
+    if (count>1) sv_key = POPs;
+
+    if (!enc && ( !count || !SvOK(sv_key) )) {
+	TRACE(2,"no key returned for ticket");
+	return 0;
+    }
+
+    if (count != 2)
+	croak("key functions needs to return (key,name)");
+    key = SvPV(sv_key,svlen);
+    if (svlen < 32)
+	croak("key must be at least 32 random bytes, got %d",svlen);
+    name = SvPV(sv_name,svlen);
+    if (svlen != 16)
+	croak("name should be exactly 16 characters, got %d",svlen);
+    if (svlen == 0)
+	croak("name should not be empty");
+
+    if (enc) {
+	/* encrypt ticket information with given key */
+	RAND_bytes(iv, 16);
+	EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key, iv);
+	HMAC_Init_ex(hctx,key+16,16,EVP_sha256(),NULL);
+	memset(key_name, 0, 16);
+	memcpy(key_name,name,svlen);
+	return 1;
+    } else {
+	unsigned char new_name[16];
+	memset(new_name, 0, sizeof(new_name));
+	memcpy(new_name,name,svlen);
+
+	HMAC_Init_ex(hctx,key+16,16,EVP_sha256(),NULL);
+	EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key, iv);
+
+	if (memcmp(new_name,key_name,16) == 0)
+	    return 1;  /* current key was used */
+	else 
+	    return 2;  /* different key was used, need to be renewed */
+    }
+}
+
+#endif
+
 
 /* ============= end of callback stuff, begin helper functions ============== */
 
@@ -1404,7 +1515,9 @@ SSL_CTX_new()
      OUTPUT:
      RETVAL
 
-#ifndef OPENSSL_NO_SSL2
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#ifndef OPENSSL_NO_SSL2 
 
 SSL_CTX *
 SSL_CTX_v2_new()
@@ -1414,7 +1527,7 @@ SSL_CTX_v2_new()
      RETVAL
 
 #endif
-
+#endif
 #ifndef OPENSSL_NO_SSL3
 
 SSL_CTX *
@@ -2105,10 +2218,35 @@ int
 SSL_want(s)
      SSL *              s
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+int
+SSL_state(s)
+     SSL *              s
+
+int
+SSL_get_state(ssl)
+     SSL *	ssl
+  CODE:
+  RETVAL = SSL_state(ssl);
+  OUTPUT:
+  RETVAL
+
+
+#else
 int
 SSL_state(s)
      SSL *              s
+     CODE:
+     RETVAL = SSL_get_state(s);
+     OUTPUT:
+     RETVAL
+
+
+int
+SSL_get_state(s)
+     SSL *              s
 
+#endif
 #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
 
 long
@@ -2734,19 +2872,15 @@ P_X509_REQ_get_attr(req,n)
         X509_ATTRIBUTE * att;
         int count, i;
         ASN1_STRING * s;
+	ASN1_TYPE * t;
     PPCODE:
         att = X509_REQ_get_attr(req,n);
-        if (att->single) {
-            s = (att->value.single->value.asn1_string);
+	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))));
-        }
-        else {
-            count = sk_ASN1_TYPE_num(att->value.set);
-            for (i=0; i<count; i++) {
-                s = (sk_ASN1_TYPE_value(att->value.set, i)->value.asn1_string);
-                XPUSHs(sv_2mortal(newSViv(PTR2IV(s))));
-            }
-        }
+	}
 
 #endif
 
@@ -4439,6 +4573,7 @@ SSL_set_session_id_context(ssl,sid_ctx,sid_ctx_len)
      const unsigned char *   sid_ctx
      unsigned int sid_ctx_len
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 void
 SSL_CTX_set_tmp_rsa_callback(ctx, cb)
      SSL_CTX *   ctx
@@ -4449,6 +4584,8 @@ SSL_set_tmp_rsa_callback(ssl, cb)
      SSL *   ssl
      cb_ssl_int_int_ret_RSA *  cb
 
+#endif
+
 void
 SSL_CTX_set_tmp_dh_callback(ctx, dh)
      SSL_CTX *   ctx
@@ -4526,6 +4663,7 @@ SSL_CTX_get_session_cache_mode(ctx)
   OUTPUT:
   RETVAL
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 long
 SSL_CTX_need_tmp_RSA(ctx)
      SSL_CTX *	ctx
@@ -4534,6 +4672,8 @@ SSL_CTX_need_tmp_RSA(ctx)
   OUTPUT:
   RETVAL
 
+#endif
+
 int
 SSL_CTX_set_app_data(ctx,arg)
      SSL_CTX *	ctx
@@ -4575,11 +4715,14 @@ SSL_CTX_set_tmp_dh(ctx,dh)
      SSL_CTX *	ctx
      DH *	dh
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 long
 SSL_CTX_set_tmp_rsa(ctx,rsa)
      SSL_CTX *	ctx
      RSA *	rsa
 
+#endif
+
 #if OPENSSL_VERSION_NUMBER > 0x10000000L && !defined OPENSSL_NO_EC
 
 EC_KEY *
@@ -4591,10 +4734,53 @@ EC_KEY_free(key)
     EC_KEY * key
 
 long
-SSL_CTX_set_tmp_ecdh(ctx,ecdh);
+SSL_CTX_set_tmp_ecdh(ctx,ecdh)
      SSL_CTX *	ctx
      EC_KEY  *	ecdh
 
+int
+EVP_PKEY_assign_EC_KEY(pkey,key)
+    EVP_PKEY *  pkey
+    EC_KEY *    key
+
+
+EC_KEY *
+EC_KEY_generate_key(curve)
+	SV *curve;
+    CODE:
+	EC_GROUP *group = NULL;
+	EC_KEY *eckey = NULL;
+	int nid;
+
+	RETVAL = 0;
+	if (SvIOK(curve)) {
+	    nid = SvIV(curve);
+	} else {
+	    nid = OBJ_sn2nid(SvPV_nolen(curve));
+#if OPENSSL_VERSION_NUMBER > 0x10002000L
+	    if (!nid) nid = EC_curve_nist2nid(SvPV_nolen(curve));
+#endif
+	    if (!nid) croak("unknown curve %s",SvPV_nolen(curve));
+	}
+
+	group = EC_GROUP_new_by_curve_name(nid);
+	if (!group) croak("unknown curve nid=%d",nid);
+	EC_GROUP_set_asn1_flag(group,OPENSSL_EC_NAMED_CURVE);
+
+	eckey = EC_KEY_new();
+	if ( eckey
+	    && EC_KEY_set_group(eckey, group)
+	    && EC_KEY_generate_key(eckey)) {
+	    RETVAL = eckey;
+	} else {
+	    if (eckey) EC_KEY_free(eckey);
+	}
+	if (group) EC_GROUP_free(group);
+
+    OUTPUT:
+	RETVAL
+
+
 #endif
 
 void *
@@ -4622,25 +4808,20 @@ SSL_get_mode(ssl)
   OUTPUT:
   RETVAL
 
-int
-SSL_get_state(ssl)
-     SSL *	ssl
-  CODE:
-  RETVAL = SSL_state(ssl);
-  OUTPUT:
-  RETVAL
-
 void
 SSL_set_state(ssl,state)
      SSL *	ssl
      int        state
   CODE:
-#ifdef OPENSSL_NO_SSL_INTERN
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+      /* not available */
+#elif defined(OPENSSL_NO_SSL_INTERN)
    SSL_set_state(ssl,state);
 #else
   ssl->state = state;
 #endif
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 long
 SSL_need_tmp_RSA(ssl)
      SSL *	ssl
@@ -4649,6 +4830,9 @@ SSL_need_tmp_RSA(ssl)
   OUTPUT:
   RETVAL
 
+
+#endif
+
 long
 SSL_num_renegotiations(ssl)
      SSL *	ssl
@@ -4668,10 +4852,6 @@ SSL_SESSION_get_app_data(ses)
 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)
@@ -4714,6 +4894,7 @@ SSL_set_tmp_dh(ssl,dh)
      SSL *	ssl
      DH *	dh
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 long
 SSL_set_tmp_rsa(ssl,rsa)
      SSL *	ssl
@@ -4723,6 +4904,7 @@ SSL_set_tmp_rsa(ssl,rsa)
   OUTPUT:
   RETVAL
 
+#endif
 
 #ifdef __ANDROID__
 
@@ -4855,6 +5037,22 @@ SSL_total_renegotiations(ssl)
   OUTPUT:
   RETVAL
 
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+void
+SSL_SESSION_get_master_key(s)
+     SSL_SESSION *   s
+     PREINIT:
+     size_t master_key_length;
+     unsigned char* master_key;
+     CODE:
+     ST(0) = sv_newmortal();   /* Undefined to start with */
+     master_key_length = SSL_SESSION_get_master_key(s, 0, 0); /* get the length */
+     New(0, master_key, master_key_length, unsigned char);
+     SSL_SESSION_get_master_key(s, master_key, master_key_length);
+     sv_setpvn(ST(0), (const char*)master_key, master_key_length);
+     Safefree(master_key);
+
+#else
 void
 SSL_SESSION_get_master_key(s)
      SSL_SESSION *   s
@@ -4862,6 +5060,10 @@ SSL_SESSION_get_master_key(s)
      ST(0) = sv_newmortal();   /* Undefined to start with */
      sv_setpvn(ST(0), (const char*)s->master_key, s->master_key_length);
 
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
 void
 SSL_SESSION_set_master_key(s,key)
      SSL_SESSION *   s
@@ -4873,6 +5075,26 @@ SSL_SESSION_set_master_key(s,key)
      memcpy(s->master_key, key, len);
      s->master_key_length = len;
 
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+
+void
+SSL_get_client_random(s)
+     SSL *   s
+     PREINIT:
+     size_t random_length;
+     unsigned char* random_data;
+     CODE:
+     ST(0) = sv_newmortal();   /* Undefined to start with */
+     random_length = SSL_get_client_random(s, 0, 0); /* get the length */
+     New(0, random_data, random_length, unsigned char);
+     SSL_get_client_random(s, random_data, random_length);
+     sv_setpvn(ST(0), (const char*)random_data, random_length);
+     Safefree(random_data);
+
+#else
+
 void
 SSL_get_client_random(s)
      SSL *   s
@@ -4880,6 +5102,26 @@ SSL_get_client_random(s)
      ST(0) = sv_newmortal();   /* Undefined to start with */
      sv_setpvn(ST(0), (const char*)s->s3->client_random, SSL3_RANDOM_SIZE);
 
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+
+void
+SSL_get_server_random(s)
+     SSL *   s
+     PREINIT:
+     size_t random_length;
+     unsigned char* random_data;
+     CODE:
+     ST(0) = sv_newmortal();   /* Undefined to start with */
+     random_length = SSL_get_server_random(s, 0, 0); /* get the length */
+     New(0, random_data, random_length, unsigned char);
+     SSL_get_server_random(s, random_data, random_length);
+     sv_setpvn(ST(0), (const char*)random_data, random_length);
+     Safefree(random_data);
+
+#else
+
 void
 SSL_get_server_random(s)
      SSL *   s
@@ -4887,10 +5129,26 @@ SSL_get_server_random(s)
      ST(0) = sv_newmortal();   /* Undefined to start with */
      sv_setpvn(ST(0), (const char*)s->s3->server_random, SSL3_RANDOM_SIZE);
 
+#endif
+
 int
 SSL_get_keyblock_size(s)
      SSL *   s
      CODE:
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+        const SSL_CIPHER *ssl_cipher;
+	int cipher, digest;
+	const EVP_CIPHER *c;
+	const EVP_MD *h;
+
+	ssl_cipher = SSL_get_current_cipher(s);
+	cipher = SSL_CIPHER_get_cipher_nid(ssl_cipher);
+	digest = SSL_CIPHER_get_digest_nid(ssl_cipher);
+	c = EVP_get_cipherbynid(cipher);
+	h = EVP_get_digestbynid(digest);
+	RETVAL = 2 * (EVP_CIPHER_key_length(c) + EVP_MD_size(h) +
+		    EVP_CIPHER_iv_length(c));
+#else
      if (s == NULL ||
 	 s->enc_read_ctx == NULL ||
 	 s->enc_read_ctx->cipher == NULL ||
@@ -4919,6 +5177,8 @@ SSL_get_keyblock_size(s)
 				       EVP_CIPHER_iv_length(c)))
 			       : -1;
      }
+#endif
+
      OUTPUT:
      RETVAL
 
@@ -4956,13 +5216,34 @@ SSL_set_session_secret_cb(s,callback=&PL_sv_undef,data=&PL_sv_undef)
         else {
             cb_data_advanced_put(s, "ssleay_session_secret_cb!!func", newSVsv(callback));
             cb_data_advanced_put(s, "ssleay_session_secret_cb!!data", newSVsv(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, s);
+            SSL_set_session_secret_cb(s, (tls_session_secret_cb_fn)&ssleay_session_secret_cb_invoke, s);
+        }
+
+#endif
+
+#ifdef NET_SSLEAY_CAN_TICKET_KEY_CB
+
+void
+SSL_CTX_set_tlsext_ticket_getkey_cb(ctx,callback=&PL_sv_undef,data=&PL_sv_undef)
+        SSL_CTX * ctx 
+        SV * callback
+        SV * data
+    CODE:
+        if (callback==NULL || !SvOK(callback)) {
+            SSL_CTX_set_tlsext_ticket_key_cb(ctx, NULL);
+	    cb_data_advanced_put(ctx, "tlsext_ticket_key_cb!!func", NULL);
+	    cb_data_advanced_put(ctx, "tlsext_ticket_key_cb!!data", NULL);
+        }
+        else {
+	    cb_data_advanced_put(ctx, "tlsext_ticket_key_cb!!func", newSVsv(callback));
+	    cb_data_advanced_put(ctx, "tlsext_ticket_key_cb!!data", newSVsv(data));
+            SSL_CTX_set_tlsext_ticket_key_cb(ctx, &tlsext_ticket_key_cb_invoke);
         }
 
+
 #endif
 
+
 #if OPENSSL_VERSION_NUMBER < 0x0090700fL
 #define REM11 "NOTE: before 0.9.7"
 
@@ -5382,15 +5663,28 @@ ASN1_OBJECT *
 P_X509_get_signature_alg(x)
         X509 * x
     CODE:
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+        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
 
@@ -5705,8 +5999,7 @@ SSL_OCSP_response_verify(ssl,rsp,svreq=NULL,flags=0)
 	     * 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++) {
-		if (!bsr->certs) bsr->certs = sk_X509_new_null();
-		sk_X509_push(bsr->certs,X509_dup(sk_X509_value(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);
@@ -5718,7 +6011,7 @@ SSL_OCSP_response_verify(ssl,rsp,svreq=NULL,flags=0)
 		X509 *issuer;
 		X509 *last = sk_X509_value(chain,sk_X509_num(chain)-1);
 		if ( (issuer = find_issuer(last,store,chain))) {
-		    sk_X509_push(bsr->certs,X509_dup(issuer));
+		    OCSP_basic_add1_cert(bsr, X509_dup(issuer));
 		    TRACE(1,"run OCSP_basic_verify with issuer for last chain element");
 		    RETVAL = OCSP_basic_verify(bsr, NULL, store, flags);
 		}
@@ -5736,7 +6029,6 @@ OCSP_response_results(rsp,...)
 	OCSP_BASICRESP *bsr;
 	int i,want_array;
 	time_t nextupd = 0;
-	STACK_OF(OCSP_SINGLERESP) *sks;
 	int getall,sksn;
 
 	bsr = OCSP_response_get1_basic(rsp);
@@ -5744,8 +6036,7 @@ OCSP_response_results(rsp,...)
 
 	want_array = (GIMME == G_ARRAY);
 	getall = (items <= 1);
-	sks = bsr->tbsResponseData->responses;
-	sksn = sk_OCSP_SINGLERESP_num(sks);
+	sksn = OCSP_resp_count(bsr);
 
 	for(i=0; i < (getall ? sksn : items-1); i++) {
 	    const char *error = NULL;
@@ -5754,9 +6045,8 @@ OCSP_response_results(rsp,...)
 	    SV *idsv = NULL;
 
 	    if(getall) {
-		sir = sk_OCSP_SINGLERESP_value(sks,i);
+		sir = OCSP_resp_get0(bsr,i);
 	    } else {
-		int k;
 		STRLEN len;
 		const unsigned char *p;
 
@@ -5767,22 +6057,36 @@ OCSP_response_results(rsp,...)
 		    error = "failed to get OCSP certid from string";
 		    goto end;
 		}
-		for(k=0;k<sksn;k++) {
-		    if (!OCSP_id_cmp(certid,sk_OCSP_SINGLERESP_value(sks,k)->certId)) {
-			sir = sk_OCSP_SINGLERESP_value(sks,k);
-			break;
-		    }
+                int first = OCSP_resp_find(bsr, certid, -1); /* Find the first matching */
+		if (first >= 0)
+		{
+		    sir = OCSP_resp_get0(bsr,first);
+		    break;
 		}
 	    }
 
-	    if (!sir) {
-		error = "cannot find entry for certificate in OCSP response";
-	    } else if (!OCSP_check_validity(sir->thisUpdate,sir->nextUpdate,0,-1)) {
-		error = "response not yet valid or expired";
-	    } else if (sir->certStatus->type == V_OCSP_CERTSTATUS_REVOKED) {
-		error = "certificate status is revoked";
-	    } else if (sir->certStatus->type != V_OCSP_CERTSTATUS_GOOD) {
-		error = "certificate status is unknown";
+	    int status, revocationReason;   
+	    ASN1_GENERALIZEDTIME *revocationTime, *thisupdate, *nextupdate;
+	    if (sir)
+	    {
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+		status = OCSP_single_get0_status(sir, &revocationReason, &revocationTime, &thisupdate, &nextupdate);
+#else
+		status = sir->certStatus->type;
+		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:
@@ -5791,12 +6095,20 @@ OCSP_response_results(rsp,...)
 		if (!idsv) {
 		    /* getall: create new SV with OCSP_CERTID */
 		    unsigned char *pi,*pc;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+		    int len = i2d_OCSP_CERTID(OCSP_SINGLERESP_get0_id(sir),NULL);
+#else
 		    int len = i2d_OCSP_CERTID(sir->certId,NULL);
+#endif
 		    if(!len) continue;
 		    Newx(pc,len,unsigned char);
 		    if (!pc) croak("out of memory");
 		    pi = pc;
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+		    i2d_OCSP_CERTID(OCSP_SINGLERESP_get0_id(sir),&pi);
+#else
 		    i2d_OCSP_CERTID(sir->certId,&pi);
+#endif
 		    idsv = newSVpv((char*)pc,len);
 		    Safefree(pc);
 		} else {
@@ -5809,26 +6121,26 @@ OCSP_response_results(rsp,...)
 		    HV *details = newHV();
 		    av_push(idav,newRV_noinc((SV*)details));
 		    hv_store(details,"statusType",10,
-			newSViv(sir->certStatus->type),0);
-		    if (sir->nextUpdate) hv_store(details,"nextUpdate",10,
-			newSViv(ASN1_TIME_timet(sir->nextUpdate)),0);
-		    if (sir->thisUpdate) hv_store(details,"thisUpdate",10,
-			newSViv(ASN1_TIME_timet(sir->thisUpdate)),0);
-		    if (sir->certStatus->type == V_OCSP_CERTSTATUS_REVOKED) {
+			newSViv(status),0);
+		    if (nextupdate) hv_store(details,"nextUpdate",10,
+			newSViv(ASN1_TIME_timet(nextupdate)),0);
+		    if (thisupdate) hv_store(details,"thisUpdate",10,
+			newSViv(ASN1_TIME_timet(thisupdate)),0);
+		    if (status == V_OCSP_CERTSTATUS_REVOKED) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
 			OCSP_REVOKEDINFO *rev = sir->certStatus->value.revoked;
-			hv_store(details,"revocationTime",14,newSViv(
-			    ASN1_TIME_timet(rev->revocationTime)),0);
-			hv_store(details,"revocationReason",16,newSViv(
-			    ASN1_ENUMERATED_get(rev->revocationReason)),0);
+			revocationReason = ASN1_ENUMERATED_get(rev->revocationReason);
+#endif
+			hv_store(details,"revocationTime",14,newSViv(ASN1_TIME_timet(revocationTime)),0);
+			hv_store(details,"revocationReason",16,newSViv(revocationReason),0);
 			hv_store(details,"revocationReason_str",20,newSVpv(
-			    OCSP_crl_reason_str(ASN1_ENUMERATED_get(
-			    rev->revocationReason)),0),0);
+		            OCSP_crl_reason_str(revocationReason),0),0);
 		    }
 		}
 		XPUSHs(sv_2mortal(newRV_noinc((SV*)idav)));
 	    } else if (!error) {
 		/* compute lowest nextUpdate */
-		time_t nu = ASN1_TIME_timet(sir->nextUpdate);
+		time_t nu = ASN1_TIME_timet(nextupdate);
 		if (!nextupd || nextupd>nu) nextupd = nu;
 	    }
 
diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm
index 4ecf46b..f44ab4d 100644
--- a/inc/Module/Install.pm
+++ b/inc/Module/Install.pm
@@ -17,7 +17,7 @@ package Module::Install;
 #     3. The ./inc/ version of Module::Install loads
 # }
 
-use 5.005;
+use 5.006;
 use strict 'vars';
 use Cwd        ();
 use File::Find ();
@@ -31,7 +31,7 @@ BEGIN {
 	# This is not enforced yet, but will be some time in the next few
 	# releases once we can make sure it won't clash with custom
 	# Module::Install extensions.
-	$VERSION = '1.06';
+	$VERSION = '1.16';
 
 	# Storage for the pseudo-singleton
 	$MAIN    = undef;
@@ -156,10 +156,10 @@ END_DIE
 sub autoload {
 	my $self = shift;
 	my $who  = $self->_caller;
-	my $cwd  = Cwd::cwd();
+	my $cwd  = Cwd::getcwd();
 	my $sym  = "${who}::AUTOLOAD";
 	$sym->{$cwd} = sub {
-		my $pwd = Cwd::cwd();
+		my $pwd = Cwd::getcwd();
 		if ( my $code = $sym->{$pwd} ) {
 			# Delegate back to parent dirs
 			goto &$code unless $cwd eq $pwd;
@@ -239,7 +239,7 @@ sub new {
 
 	# ignore the prefix on extension modules built from top level.
 	my $base_path = Cwd::abs_path($FindBin::Bin);
-	unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
+	unless ( Cwd::abs_path(Cwd::getcwd()) eq $base_path ) {
 		delete $args{prefix};
 	}
 	return $args{_self} if $args{_self};
@@ -338,7 +338,7 @@ sub find_extensions {
 		if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
 			my $content = Module::Install::_read($subpath . '.pm');
 			my $in_pod  = 0;
-			foreach ( split //, $content ) {
+			foreach ( split /\n/, $content ) {
 				$in_pod = 1 if /^=\w/;
 				$in_pod = 0 if /^=cut/;
 				next if ($in_pod || /^=cut/);  # skip pod text
@@ -378,6 +378,7 @@ eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
 sub _read {
 	local *FH;
 	open( FH, '<', $_[0] ) or die "open($_[0]): $!";
+	binmode FH;
 	my $string = do { local $/; <FH> };
 	close FH or die "close($_[0]): $!";
 	return $string;
@@ -386,6 +387,7 @@ END_NEW
 sub _read {
 	local *FH;
 	open( FH, "< $_[0]"  ) or die "open($_[0]): $!";
+	binmode FH;
 	my $string = do { local $/; <FH> };
 	close FH or die "close($_[0]): $!";
 	return $string;
@@ -416,6 +418,7 @@ eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
 sub _write {
 	local *FH;
 	open( FH, '>', $_[0] ) or die "open($_[0]): $!";
+	binmode FH;
 	foreach ( 1 .. $#_ ) {
 		print FH $_[$_] or die "print($_[0]): $!";
 	}
@@ -425,6 +428,7 @@ END_NEW
 sub _write {
 	local *FH;
 	open( FH, "> $_[0]"  ) or die "open($_[0]): $!";
+	binmode FH;
 	foreach ( 1 .. $#_ ) {
 		print FH $_[$_] or die "print($_[0]): $!";
 	}
@@ -434,7 +438,7 @@ END_OLD
 
 # _version is for processing module versions (eg, 1.03_05) not
 # Perl versions (eg, 5.8.1).
-sub _version ($) {
+sub _version {
 	my $s = shift || 0;
 	my $d =()= $s =~ /(\.)/g;
 	if ( $d >= 2 ) {
@@ -450,12 +454,12 @@ sub _version ($) {
 	return $l + 0;
 }
 
-sub _cmp ($$) {
+sub _cmp {
 	_version($_[1]) <=> _version($_[2]);
 }
 
 # Cloned from Params::Util::_CLASS
-sub _CLASS ($) {
+sub _CLASS {
 	(
 		defined $_[0]
 		and
diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm
index 802844a..5762a74 100644
--- a/inc/Module/Install/Base.pm
+++ b/inc/Module/Install/Base.pm
@@ -4,7 +4,7 @@ package Module::Install::Base;
 use strict 'vars';
 use vars qw{$VERSION};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.16';
 }
 
 # Suspend handler for "redefined" warnings
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
index 22167b8..d859276 100644
--- a/inc/Module/Install/Can.pm
+++ b/inc/Module/Install/Can.pm
@@ -8,7 +8,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.16';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/External.pm b/inc/Module/Install/External.pm
index 53522d6..88ed718 100644
--- a/inc/Module/Install/External.pm
+++ b/inc/Module/Install/External.pm
@@ -8,7 +8,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION $ISCORE @ISA};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.16';
 	$ISCORE  = 1;
 	@ISA     = qw{Module::Install::Base};
 }
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
index bee0c4f..41d3517 100644
--- a/inc/Module/Install/Fetch.pm
+++ b/inc/Module/Install/Fetch.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.16';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm
index 7052f36..e9918d2 100644
--- a/inc/Module/Install/Makefile.pm
+++ b/inc/Module/Install/Makefile.pm
@@ -8,7 +8,7 @@ use Fcntl qw/:flock :seek/;
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.16';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -133,7 +133,7 @@ sub makemaker_args {
 	return $args;
 }
 
-# For mm args that take multiple space-seperated args,
+# For mm args that take multiple space-separated args,
 # append an argument to the current list.
 sub makemaker_append {
 	my $self = shift;
diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm
index 58430f3..9792685 100644
--- a/inc/Module/Install/Metadata.pm
+++ b/inc/Module/Install/Metadata.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.16';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -347,7 +347,7 @@ sub name_from {
 		^ \s*
 		package \s*
 		([\w:]+)
-		\s* ;
+		[\s|;]*
 		/ixms
 	) {
 		my ($name, $module_name) = ($1, $1);
@@ -705,7 +705,7 @@ sub _write_mymeta_data {
 	my @yaml = Parse::CPAN::Meta::LoadFile('META.yml');
 	my $meta = $yaml[0];
 
-	# Overwrite the non-configure dependency hashs
+	# Overwrite the non-configure dependency hashes
 	delete $meta->{requires};
 	delete $meta->{build_requires};
 	delete $meta->{recommends};
diff --git a/inc/Module/Install/PRIVATE/Net/SSLeay.pm b/inc/Module/Install/PRIVATE/Net/SSLeay.pm
index 8f73647..d6fbdf6 100644
--- a/inc/Module/Install/PRIVATE/Net/SSLeay.pm
+++ b/inc/Module/Install/PRIVATE/Net/SSLeay.pm
@@ -1,5 +1,4 @@
 #line 1
-#line 1
 package Module::Install::PRIVATE::Net::SSLeay;
 
 use strict;
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
index eeaa3fe..218a66b 100644
--- a/inc/Module/Install/Win32.pm
+++ b/inc/Module/Install/Win32.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.16';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
index 85d8018..530749b 100644
--- a/inc/Module/Install/WriteAll.pm
+++ b/inc/Module/Install/WriteAll.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.16';
 	@ISA     = qw{Module::Install::Base};
 	$ISCORE  = 1;
 }
diff --git a/lib/Net/SSLeay.pm b/lib/Net/SSLeay.pm
index 4968e15..88886ee 100644
--- a/lib/Net/SSLeay.pm
+++ b/lib/Net/SSLeay.pm
@@ -4,7 +4,7 @@
 # Copyright (C) 2005 Florian Ragwitz <rafl at debian.org>, All Rights Reserved.
 # Copyright (C) 2005 Mike McCauley <mikem at airspayce.com>, All Rights Reserved.
 #
-# $Id: SSLeay.pm 464 2016-04-11 00:16:31Z mikem-guest $
+# $Id: SSLeay.pm 477 2016-07-31 20:24:00Z mikem-guest $
 #
 # Change data removed from here. See Changes
 # The distribution and use of this module are subject to the conditions
@@ -63,7 +63,7 @@ $Net::SSLeay::slowly = 0;
 $Net::SSLeay::random_device = '/dev/urandom';
 $Net::SSLeay::how_random = 512;
 
-$VERSION = '1.74'; # Dont forget to set version in META.yml too
+$VERSION = '1.77'; # Dont forget to set version in META.yml too
 @ISA = qw(Exporter);
 
 #BEWARE:
diff --git a/lib/Net/SSLeay.pod b/lib/Net/SSLeay.pod
index e494541..efb8243 100644
--- a/lib/Net/SSLeay.pod
+++ b/lib/Net/SSLeay.pod
@@ -44,6 +44,8 @@ B<COMPATIBILITY NOTE:> L<Net::SSLeay> cannot be built with pre-0.9.3 openssl. It
 to use at least 0.9.7 (as older versions are not tested during development). Some low level API functions
 may be available with certain openssl versions.
 
+It is compatible with OpenSSL 1.0 and 1.1. Some functions are not available under OpenSSL 1.1.
+
 L<Net::SSLeay> module basically comprise of:
 
 =over
@@ -1393,8 +1395,8 @@ B<COMPATIBILITY:> not available in Net-SSLeay-1.45 and before
 
 Set the key referenced by $pkey to $key
 
-B<NOTE:> In accordance with the OpenSSL naming convention the $key assigned
-to the $pkey using the "1" functions must be freed as well as $pkey.
+B<NOTE:> No reference counter will be increased, i.e. $key will be freed if
+$pkey is freed.
 
  my $rv = Net::SSLeay::EVP_PKEY_assign_RSA($pkey, $key);
  # $pkey - value corresponding to openssl's EVP_PKEY structure
@@ -1402,7 +1404,24 @@ to the $pkey using the "1" functions must be freed as well as $pkey.
  #
  # returns: 1 on success, 0 on failure
 
-Check openssl doc L<http://www.openssl.org/docs/crypto/EVP_PKEY_set1_RSA.html|http://www.openssl.org/docs/crypto/EVP_PKEY_set1_RSA.html>
+Check openssl doc L<http://www.openssl.org/docs/crypto/EVP_PKEY_assign_RSA.html|http://www.openssl.org/docs/crypto/EVP_PKEY_assign_RSA.html>
+ 
+=item * EVP_PKEY_assign_EC_KEY
+
+B<COMPATIBILITY:> not available in Net-SSLeay-1.74 and before
+
+Set the key referenced by $pkey to $key
+
+B<NOTE:> No reference counter will be increased, i.e. $key will be freed if
+$pkey is freed.
+
+ my $rv = Net::SSLeay::EVP_PKEY_assign_EC_KEY($pkey, $key);
+ # $pkey - value corresponding to openssl's EVP_PKEY structure
+ # $key - value corresponding to openssl's EC_KEY structure
+ #
+ # returns: 1 on success, 0 on failure
+
+Check openssl doc L<http://www.openssl.org/docs/crypto/EVP_PKEY_assign_EC_KEY.html|http://www.openssl.org/docs/crypto/EVP_PKEY_assign_EC_KEY.html>
 
 =item * EVP_PKEY_bits
 
@@ -1844,6 +1863,11 @@ Sets 'master_key' value for SSL_SESSION structure $s
  #
  # returns: no return value
 
+Not available with OpenSSL 1.1 and later.
+Code that previously used
+       SESSION_set_master_key must now set $secret in the session_secret
+       callback set with SSL_set_session_secret_cb.
+
 =item * SESSION_get_time
 
 Returns the time at which the session s was established.
@@ -2447,6 +2471,8 @@ Return the result of C<SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL)>
  #
  # returns: result of SSL_CTRL_NEED_TMP_RSA command
 
+Not available with OpenSSL 1.1 and later.
+
 =item * CTX_new
 
 The same as L</CTX_v23_new>
@@ -2457,6 +2483,8 @@ The same as L</CTX_v23_new>
 
 Check openssl doc L<http://www.openssl.org/docs/ssl/SSL_CTX_new.html|http://www.openssl.org/docs/ssl/SSL_CTX_new.html>
 
+Not available with OpenSSL 1.1 and later.
+
 =item * CTX_v2_new
 
 Creates a new SSL_CTX object - based on SSLv2_method() - as framework to establish TLS/SSL enabled connections.
@@ -2906,6 +2934,8 @@ Sets the temporary/ephemeral RSA key to be used to be $rsa.
 
 Check openssl doc L<http://www.openssl.org/docs/ssl/SSL_CTX_set_tmp_rsa_callback.html|http://www.openssl.org/docs/ssl/SSL_CTX_set_tmp_rsa_callback.html>
 
+Not available with OpenSSL 1.1 and later.
+
 =item * CTX_set_tmp_rsa_callback
 
 Sets the callback function for ctx to be used when a temporary/ephemeral RSA key is required to $tmp_rsa_callback.
@@ -2920,6 +2950,8 @@ Sets the callback function for ctx to be used when a temporary/ephemeral RSA key
 
 Check openssl doc L<http://www.openssl.org/docs/ssl/SSL_CTX_set_tmp_rsa_callback.html|http://www.openssl.org/docs/ssl/SSL_CTX_set_tmp_rsa_callback.html>
 
+Not available with OpenSSL 1.1 and later.
+
 =item * CTX_set_trust
 
  my $rv = Net::SSLeay::CTX_set_trust($s, $trust);
@@ -3436,9 +3468,9 @@ Obtains the latest 'Finished' message expected from the peer.
 
 =item * get_keyblock_size
 
-B<NOTE:> Does not exactly correspond to any low level API function.
+Gets the length of the TLS keyblock.
 
-??? (more info needed)
+B<NOTE:> Does not exactly correspond to any low level API function.
 
  my $rv = Net::SSLeay::get_keyblock_size($ssl);
  # $ssl - value corresponding to openssl's SSL structure
@@ -3680,6 +3712,8 @@ Sets the SSL connection state.
 
  Net::SSLeay::set_state($ssl,Net::SSLeay::SSL_ST_ACCEPT());
 
+Not available with OpenSSL 1.1 and later.
+
 =item * get_verify_depth
 
 Returns the verification depth limit currently set in $ssl.
@@ -3829,6 +3863,8 @@ Executes SSL_CTRL_NEED_TMP_RSA command on $ssl.
  #
  # returns: command result
 
+Not available with OpenSSL 1.1 and later.
+
 =item * num_renegotiations
 
 Executes SSL_CTRL_GET_NUM_RENEGOTIATIONS command on $ssl.
@@ -4131,6 +4167,91 @@ Setup pre-shared secret session resumption function.
  #
  # returns: no return value
 
+The callback function will be called like:
+callback_function($secret, $ciphers, $pref_cipher, $data);
+
+# $secret is the current master session key, usually all 0s at the beginning of a session
+# $ciphers is ref to an array of peer cipher names
+# $pref_cipher is a ref to an index into the list of cipher names of 
+#  the preferred cipher. Set it if you want to specify a preferred cipher
+# $data is the data passed to set_session_secret_cb
+
+The callback function should return 1 if it likes the suggested cipher (or has selected an alternative 
+by setting pref_cipher), else it should return 0 (in which case OpenSSL will select its own preferred cipher).
+
+With OpenSSL 1.1 and later, callback_function can change the master key for the session by 
+altering $secret and returning 1.
+
+=item * CTX_set_tlsext_ticket_getkey_cb
+
+Setup encryption for TLS session tickets (stateless session reuse).
+
+ Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb($ctx, $func, $data);
+ # $ctx  - value corresponding to openssl's SSL_CTX structure
+ # $func - perl reference to callback function
+ # $data - [optional] data that will be passed to callback function when invoked
+ #
+ # returns: no return value
+
+The callback function will be called like:
+getkey($data,[$key_name]) -> ($key,$current_key_name)
+
+# $data is the data passed to set_session_secret_cb
+# $key_name is the name of the key OpenSSL has extracted from the session ticket
+# $key is the requested key for ticket encryption + HMAC
+# $current_key_name is the name for the currently valid key
+
+OpenSSL will call the function without a key name if it generates a new ticket.
+It then needs the callback to return the encryption+HMAC key and an identifier
+(key name) for this key.
+
+When OpenSSL gets a session ticket from the client it extracts the key name and
+calls the callback with this name as argument. It then expects the callback to
+return the encryption+HMAC key matching the requested key name and and also the
+key name which should be used at the moment. If the requested key name and the
+returned key name differ it means that this session ticket was created with an
+expired key and need to be renewed. In this case OpenSSL will call the callback
+again with no key name to create a new session ticket based on the old one.
+
+The key must be at least 32 byte of random data which can be created with
+RAND_bytes. Internally the first 16 byte are used as key in AES-128 encryption
+while the next 16 byte are used for the SHA-256 HMAC.
+The key name are binary data and must be exactly 16 byte long. 
+
+Example:
+
+    Net::SSLeay::RAND_bytes(my $oldkey,32);
+    Net::SSLeay::RAND_bytes(my $newkey,32);
+    my $oldkey_name = pack("a16",'oldsecret');
+    my $newkey_name = pack("a16",'newsecret');
+
+    my @keys = (
+	[ $newkey_name, $newkey ], # current active key
+	[ $oldkey_name, $oldkey ], # already expired
+    );
+
+    Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb($server2->_ctx, sub {
+	my ($mykeys,$name) = @_;
+
+	# return (current_key, current_key_name) if no name given
+	return ($mykeys->[0][1],$mykeys->[0][0]) if ! $name;
+
+	# return (matching_key, current_key_name) if we find a key matching
+	# the given name
+	for(my $i = 0; $i<@$mykeys; $i++) {
+	    next if $name ne $mykeys->[$i][0];
+	    return ($mykeys->[$i][1],$mykeys->[0][0]);
+	}
+
+	# no matching key found
+	return;
+    },\@keys);
+
+
+This function is based on the OpenSSL function SSL_CTX_set_tlsext_ticket_key_cb
+but provides a simpler to use interface. For more information see
+L<http://www.openssl.org/docs/ssl/SSL_CTX_set_tlsext_ticket_key_cb.html|http://www.openssl.org/docs/ssl/SSL_CTX_set_tlsext_ticket_key_cb.html>
+
 =item * set_shutdown
 
 Sets the shutdown state of $ssl to $mode.
@@ -7961,6 +8082,23 @@ TBA
 
 TBA
 
+=item * EC_KEY_generate_key
+
+Generates a EC key and returns it in a newly allocated EC_KEY structure.
+The EC key then can be used to create a PKEY which can be used in calls
+like X509_set_pubkey.
+
+ my $key = Net::SSLeay::EVP_PKEY_new();
+ my $ec  = Net::SSLeay::EC_KEY_generate_key($curve);
+ Net::SSLeay::EVP_PKEY_assign_EC_KEY($key,$ec);
+
+ # $curve - curve name like 'secp521r1' or the matching Id (integer) of the curve
+ #
+ # returns: value corresponding to openssl's EC_KEY structure (0 on failure)
+
+This function has no equivalent in OpenSSL but combines multiple OpenSSL
+functions for an easier interface.
+
 =back
 
 
diff --git a/t/local/32_x509_get_cert_info.t b/t/local/32_x509_get_cert_info.t
index d7079f9..80bf9d3 100755
--- a/t/local/32_x509_get_cert_info.t
+++ b/t/local/32_x509_get_cert_info.t
@@ -175,7 +175,7 @@ for my $f (keys (%$dump)) {
   }
     
   SKIP: {
-    skip('crl_distribution_points requires 0.9.7+', scalar(@{$dump->{$f}->{cdp}})+1) unless Net::SSLeay::SSLeay >= 0x0090700f;
+    skip('crl_distribution_points requires 0.9.7+', int(@{$dump->{$f}->{cdp}})+1) unless Net::SSLeay::SSLeay >= 0x0090700f;
     my @cdp = Net::SSLeay::P_X509_get_crl_distribution_points($x509);
     is(scalar(@cdp), scalar(@{$dump->{$f}->{cdp}}), "cdp size\t$f");
     for my $i (0..$#cdp) {
diff --git a/t/local/35_ephemeral.t b/t/local/35_ephemeral.t
index ce4b3dc..86e1d78 100644
--- a/t/local/35_ephemeral.t
+++ b/t/local/35_ephemeral.t
@@ -6,7 +6,7 @@ use Test::More;
 use Net::SSLeay;
 
 BEGIN {
-  plan skip_all => "libressl removed support for ephemeral/temporary RSA private keys" if Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER");
+  plan skip_all => "libressl and OpenSSL 1.1 removed support for ephemeral/temporary RSA private keys" if Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER") || Net::SSLeay::constant("OPENSSL_VERSION_NUMBER") >= 0x10100000;
 }
 
 plan tests => 3;
diff --git a/t/local/63_ec_key_generate_key.t b/t/local/63_ec_key_generate_key.t
new file mode 100644
index 0000000..8c8375b
--- /dev/null
+++ b/t/local/63_ec_key_generate_key.t
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More;
+use Net::SSLeay;
+
+if (!defined &Net::SSLeay::EC_KEY_generate_key) {
+    plan skip_all => "no suport for ECC in your OpenSSL";
+    exit(0);
+}
+
+plan tests => 4;
+
+Net::SSLeay::randomize();
+Net::SSLeay::load_error_strings();
+Net::SSLeay::ERR_load_crypto_strings();
+Net::SSLeay::SSLeay_add_ssl_algorithms();
+
+my $ec = Net::SSLeay::EC_KEY_generate_key('prime256v1');
+ok($ec,'EC key created');
+
+if ($ec) {
+    my $key = Net::SSLeay::EVP_PKEY_new();
+    my $rv = Net::SSLeay::EVP_PKEY_assign_EC_KEY($key,$ec);
+    ok($rv,'EC key assigned to PKEY');
+
+    my $pem = Net::SSLeay::PEM_get_string_PrivateKey($key);
+    ok( $pem =~m{^---.* PRIVATE KEY}m, "output key as PEM");
+
+    my $bio = Net::SSLeay::BIO_new( Net::SSLeay::BIO_s_mem());
+    Net::SSLeay::BIO_write($bio,$pem);
+    my $newkey = Net::SSLeay::PEM_read_bio_PrivateKey($bio);
+    ok($newkey,"read key again from PEM");
+}
diff --git a/t/local/64_ticket_sharing.t b/t/local/64_ticket_sharing.t
new file mode 100644
index 0000000..2db2077
--- /dev/null
+++ b/t/local/64_ticket_sharing.t
@@ -0,0 +1,270 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More;
+use Socket;
+use File::Spec;
+use Net::SSLeay;
+use Config;
+
+# for debugging only
+my $DEBUG = 0;
+my $PCAP = 0;
+require Net::PcapWriter if $PCAP;
+
+plan skip_all => "no support for tlsext_ticket_key_cb"
+    if ! defined &Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb;
+plan tests => 15;
+
+Net::SSLeay::randomize();
+Net::SSLeay::load_error_strings();
+Net::SSLeay::ERR_load_crypto_strings();
+Net::SSLeay::SSLeay_add_ssl_algorithms();
+
+my $SSL_ERROR; # set in _minSSL
+my %TRANSFER;  # set in _handshake
+
+my $client = _minSSL->new();
+my $server = _minSSL->new( cert => [
+    File::Spec->catfile('t','data','cert.pem'),
+    File::Spec->catfile('t','data','key.pem')
+]);
+
+
+# initial tests without reuse
+# ----------------------------------------------
+is( _handshake($client,$server), 'full', "initial handshake is full");
+is( _handshake($client,$server), 'full', "another full handshake");
+
+# explicitly reuse session in client to check that server accepts it
+# ----------------------------------------------
+my $sess = Net::SSLeay::get1_session($client->_ssl);
+my $reuse = sub { Net::SSLeay::set_session($client->_ssl,$sess) };
+is( _handshake($client,$server,$reuse),'reuse',"handshake with reuse");
+is( _handshake($client,$server,$reuse),'reuse',"handshake again with reuse");
+
+# create another server and connect client with session from old server
+# should not be reused
+# ----------------------------------------------
+my $server2 = _minSSL->new( cert => [
+    File::Spec->catfile('t','data','cert.pem'),
+    File::Spec->catfile('t','data','key.pem')
+]);
+is( _handshake($client,$server2,$reuse),'full',"handshake with server2 is full");
+
+# now attach the same ticket key callback to both servers
+# ----------------------------------------------
+Net::SSLeay::RAND_bytes(my $key,32);
+my $key_name = pack("a16",'secret');
+my $keycb = sub {
+    my ($mykey,$name) = @_;
+    return ($mykey,$key_name) if ! $name or $key_name eq $name;
+    return; # unknown key
+};
+Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb($server->_ctx, $keycb,$key);
+Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb($server2->_ctx,$keycb,$key);
+is( _handshake($client,$server),'full',"initial full handshake with server1");
+$sess = Net::SSLeay::get1_session($client->_ssl);
+is( _handshake($client,$server,$reuse), 'reuse',"reuse session with server1");
+is( _handshake($client,$server2,$reuse),'reuse',"reuse session with server2");
+
+# simulate rotation for $key: the callback returns now the right key, but
+# has a different current_name. It is expected that the callback is called again
+# for encryption with the new key and that a new session ticket gets sent to
+# the client
+# ----------------------------------------------
+Net::SSLeay::RAND_bytes(my $newkey,32);
+my $newkey_name = pack("a16",'newsecret');
+my @keys = (
+    [ $newkey_name, $newkey ], # current default key
+    [ $key_name, $key ],       # already expired
+);
+my @was_called_with;
+my %old_transfer = %TRANSFER;
+Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb($server2->_ctx, sub {
+    my (undef,$name) = @_;
+    push @was_called_with,$name || '<undef>';
+    return ($keys[0][1],$keys[0][0]) if ! $name;
+    for(my $i = 0; $i<@keys; $i++) {
+	return ($keys[$i][1],$keys[0][0]) if $name eq $keys[$i][0];
+    }
+    return;
+});
+
+my $expect_reuse = _handshake($client,$server2,$reuse);
+if ($expect_reuse eq '> < > <') {
+    # broken handshake seen with openssl 1.0.0 when a ticket was used where
+    # the key is still known but expired. It will do
+    # Encrypted Handshake Message, Change Cipher Spec, Encrypted Handshake Message
+    # in the last packet from server to client
+    is($expect_reuse,'> < > <',"(slightly broken) reuse session with old key with server2");
+    ok( @was_called_with >= 2,'callback was called at least 2 times');
+} else {
+    is($expect_reuse,'reuse',"reuse session with old key with server2");
+    is( 0+ at was_called_with,2,'callback was called 2 times');
+}
+
+is( $was_called_with[0],$key_name, 'first with the old key name');
+is( $was_called_with[1],"<undef>", 'then with undef to get the current key');
+ok( $TRANSFER{client} == $old_transfer{client}, 'no more data from client to server');
+ok( $TRANSFER{server} > $old_transfer{server}, 'but more data from server (new ticket)');
+
+# finally try to reuse the session created with new key against server1
+# this should result in a full handshake since server1 does not know newkey
+# ----------------------------------------------
+$sess = Net::SSLeay::get1_session($client->_ssl);
+is( _handshake($client,$server,$reuse),'full',"full handshake with new ticker on server1");
+
+
+
+my $i;
+sub _handshake {
+    my ($client,$server,$after_init) = @_;
+    $client->state_connect;
+    $server->state_accept;
+    &$after_init if $after_init;
+
+    my $pcap = $PCAP && do {
+	my $fname = 'test'.(++$i).'.pcap';
+	open(my $fh,'>',$fname);
+	diag("pcap in $fname");
+	$fh->autoflush;
+	Net::PcapWriter->new($fh)->tcp_conn('1.1.1.1',1000,'2.2.2.2',443);
+    };
+
+    my ($client_done,$server_done, at hs);
+    %TRANSFER = ();
+    for(my $tries = 0; $tries < 10 and !$client_done || !$server_done; $tries++ ) {
+	$client_done ||= $client->handshake || 0;
+	$server_done ||= $server->handshake  || 0;
+
+	my $transfer = 0;
+	if (defined(my $data = $client->bio_read())) {
+	    $pcap && $pcap->write(0,$data);
+	    $DEBUG && warn "client -> server: ".length($data)." bytes\n";
+	    $server->bio_write($data);
+	    push @hs,'>';
+	    $TRANSFER{client} += length($data);
+	    $transfer++;
+	}
+	if (defined(my $data = $server->bio_read())) {
+	    $pcap && $pcap->write(1,$data);
+	    $DEBUG && warn "server -> client: ".length($data)." bytes\n";
+	    $client->bio_write($data);
+	    # assume certificate was sent if length>700
+	    push @hs, length($data) > 700 ? '<[C]':'<';
+	    $TRANSFER{server} += length($data);
+	    $transfer++;
+	}
+	if (!$transfer) {
+	    # no more data to transfer - assume we are done
+	    $client_done = $server_done = 1;
+	}
+    }
+
+    return
+	!$client_done || !$server_done ? 'failed' :
+	"@hs" eq '> <[C] > <' ? 'full' :
+	"@hs" eq '> < >'   ? 'reuse' :
+	"@hs";
+}
+
+
+{
+    package _minSSL;
+    sub new {
+	my ($class,%args) = @_;
+	my $ctx = Net::SSLeay::CTX_tlsv1_new();
+	Net::SSLeay::CTX_set_options($ctx,Net::SSLeay::OP_ALL());
+	Net::SSLeay::CTX_set_cipher_list($ctx,'AES128-SHA');
+	my $id = 'client';
+	if ($args{cert}) {
+	    my ($cert,$key) = @{ delete $args{cert} };
+	    Net::SSLeay::set_cert_and_key($ctx, $cert, $key)
+		|| die "failed to use cert file $cert,$key";
+	    $id = 'server';
+	}
+
+	my $self = bless { id => $id, ctx => $ctx }, $class;
+	return $self;
+    }
+
+    sub state_accept {
+	my $self = shift;
+	_reset($self);
+	Net::SSLeay::set_accept_state($self->{ssl});
+    }
+
+    sub state_connect {
+	my $self = shift;
+	_reset($self);
+	Net::SSLeay::set_connect_state($self->{ssl});
+    }
+
+    sub handshake {
+	my $self = shift;
+	my $rv = Net::SSLeay::do_handshake($self->{ssl});
+	$rv = _error($self,$rv);
+	return $rv;
+    }
+
+    sub ssl_read {
+	my ($self) = @_;
+	my ($data,$rv) = Net::SSLeay::read($self->{ssl});
+	return _error($self,$rv || -1) if !$rv || $rv<0;
+	return $data;
+    }
+
+    sub bio_write {
+	my ($self,$data) = @_;
+	defined $data and $data ne '' or return;
+	Net::SSLeay::BIO_write($self->{rbio},$data);
+    }
+
+    sub ssl_write {
+	my ($self,$data) = @_;
+	my $rv = Net::SSLeay::write($self->{ssl},$data);
+	return _error($self,$rv || -1) if !$rv || $rv<0;
+	return $rv;
+    }
+
+    sub bio_read {
+	my ($self) = @_;
+	return Net::SSLeay::BIO_read($self->{wbio});
+    }
+
+    sub _ssl { shift->{ssl} }
+    sub _ctx { shift->{ctx} }
+
+    sub _reset {
+	my $self = shift;
+	my $ssl = Net::SSLeay::new($self->{ctx});
+	my @bio = (
+	    Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem()),
+	    Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem()),
+	);
+	Net::SSLeay::set_bio($ssl,$bio[0],$bio[1]);
+	$self->{ssl} = $ssl;
+	$self->{rbio} = $bio[0];
+	$self->{wbio} = $bio[1];
+    }
+
+    sub _error {
+	my ($self,$rv) = @_;
+	if ($rv>0) {
+	    $SSL_ERROR = undef;
+	    return $rv;
+	}
+	my $err = Net::SSLeay::get_error($self->{ssl},$rv);
+	if ($err == Net::SSLeay::ERROR_WANT_READ()
+	    || $err == Net::SSLeay::ERROR_WANT_WRITE()) {
+	    $SSL_ERROR = $err;
+	    $DEBUG && warn "[$self->{id}] rw:$err\n";
+	    return;
+	}
+	$DEBUG && warn "[$self->{id}] ".Net::SSLeay::ERR_error_string($err)."\n";
+	return;
+    }
+
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libnet-ssleay-perl.git



More information about the Pkg-perl-cvs-commits mailing list