Blob Blame History Raw
--- api/ssl/src/C/bglssl.c.orig	2015-12-21 05:31:11.000000000 -0700
+++ api/ssl/src/C/bglssl.c	2017-01-26 00:13:39.000000000 -0700
@@ -3,8 +3,8 @@
 /*    -------------------------------------------------------------    */
 /*    Author      :  Manuel Serrano & Stephane Epardaud                */
 /*    Creation    :  Wed Mar 23 16:54:42 2005                          */
-/*    Last change :  Wed Nov 18 05:25:26 2015 (serrano)                */
-/*    Copyright   :  2005-15 Manuel Serrano                            */
+/*    Last change :  Wed Nov 30 07:40:42 2016 (serrano)                */
+/*    Copyright   :  2005-16 Manuel Serrano                            */
 /*    -------------------------------------------------------------    */
 /*    SSL socket client-side support                                   */
 /*=====================================================================*/
@@ -190,21 +190,25 @@ bgl_ssl_init() {
 #if( BGLSSL_HAVE_SSLV23 )
       ctxc[ BGLSSL_SSLV23 ] = SSL_CTX_new( SSLv23_client_method() );
 #endif      
+#if( BGLSSL_HAVE_TLSV1 )
       ctxc[ BGLSSL_TLSV1 ] = SSL_CTX_new( TLSv1_client_method() );
+#else      
+      ctxc[ BGLSSL_TLSV1 ] = SSL_CTX_new( TLS_client_method() );
+#endif      
 #if( BGLSSL_HAVE_TLSV1_1 )
       ctxc[ BGLSSL_TLSV1_1 ] = SSL_CTX_new( TLSv1_1_client_method() );
 #else      
-      ctxc[ BGLSSL_TLSV1_1 ] = SSL_CTX_new( TLSv1_client_method() );
+      ctxc[ BGLSSL_TLSV1_1 ] = ctxc[ BGLSSL_TLSV1 ];
 #endif
 #if( BGLSSL_HAVE_TLSV1_2 )
       ctxc[ BGLSSL_TLSV1_2 ] = SSL_CTX_new( TLSv1_2_client_method() );
 #else      
-      ctxc[ BGLSSL_TLSV1_2 ] = SSL_CTX_new( TLSv1_client_method() );
+      ctxc[ BGLSSL_TLSV1_2 ] = ctxc[ BGLSSL_TLSV1 ];
 #endif
 #if( BGLSSL_HAVE_DTLS )
       ctxc[ BGLSSL_DTLSV1 ] = SSL_CTX_new( DTLSv1_client_method() );
 #else      
-      ctxc[ BGLSSL_DTLSV1 ] = 0;
+      ctxc[ BGLSSL_DTLSV1 ] = SSL_CTX_new( DTLS_client_method() );
 #endif
       
 #if( BGLSSL_HAVE_SSLV2 )
@@ -216,21 +220,25 @@ bgl_ssl_init() {
 #if( BGLSSL_HAVE_SSLV23 )
       ctxs[ BGLSSL_SSLV23 ] = SSL_CTX_new( SSLv23_server_method() );
 #endif      
+#if( BGLSSL_HAVE_TLSV1 )
       ctxs[ BGLSSL_TLSV1 ] = SSL_CTX_new( TLSv1_server_method() );
+#else
+      ctxs[ BGLSSL_TLSV1 ] = SSL_CTX_new( TLS_server_method() );
+#endif      
 #if( BGLSSL_HAVE_TLSV1_1 )
       ctxs[ BGLSSL_TLSV1_1 ] = SSL_CTX_new( TLSv1_1_server_method() );
 #else      
-      ctxs[ BGLSSL_TLSV1_1 ] = SSL_CTX_new( TLSv1_server_method() );
+      ctxs[ BGLSSL_TLSV1_1 ] = ctxs[ BGLSSL_TLSV1 ];
 #endif
 #if( BGLSSL_HAVE_TLSV1_2 )
       ctxs[ BGLSSL_TLSV1_2 ] = SSL_CTX_new( TLSv1_2_server_method() );
 #else      
-      ctxs[ BGLSSL_TLSV1_2 ] = SSL_CTX_new( TLSv1_server_method() );
+      ctxs[ BGLSSL_TLSV1_2 ] = ctxs[ BGLSSL_TLSV1 ];
 #endif
 #if( BGLSSL_HAVE_DTLS )
       ctxs[ BGLSSL_DTLSV1 ] = SSL_CTX_new( DTLSv1_server_method() );
 #else      
-      ctxs[ BGLSSL_DTLSV1 ] = 0;
+      ctxs[ BGLSSL_DTLSV1 ] = SSL_CTX_new( DTLS_server_method() );
 #endif
    }
    
@@ -417,7 +425,7 @@ socket_enable_ssl( obj_t s, char accept,
       /* keep the ca_list away from the GC */
       drag = MAKE_PAIR( ca_list, drag );
 
-      ctx = SSL_CTX_new( ctx->method );
+      ctx = SSL_CTX_new( BGL_SSL_CTX_get_ssl_method( ctx ) );
       if( ctx == NULL )
 	 C_SYSTEM_FAILURE( BGL_IO_ERROR,
 			   "make-client-ssl-socket, cannot create SSL context",
@@ -890,7 +898,7 @@ SSL_CTX_use_certificate_chain( SSL_CTX *
    x = PEM_read_bio_X509_AUX( in, NULL, NULL, NULL );
 
    if( x == NULL ) {
-      SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB );
+      SSLerr( SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB );
       goto end;
    }
 
@@ -908,10 +916,14 @@ SSL_CTX_use_certificate_chain( SSL_CTX *
       int r;
       unsigned long err;
 
-      if( ctx->extra_certs != NULL ) {
-	 sk_X509_pop_free( ctx->extra_certs, X509_free );
-	 ctx->extra_certs = NULL;
-      }
+      // MS 28 Novembre 2016: WARNING !!!
+      // before openssl 1.1, used to be
+      // if( ctx->extra_certs != NULL ) {
+      //   sk_X509_pop_free( ctx->extra_certs, X509_free );
+      //   ctx->extra_certs = NULL;
+      // }
+      // see bglss.h for the definition of BGL_SSL_CTX_clear_extra_chain_certs
+      BGL_SSL_CTX_clear_extra_chain_certs( ctx );
 
       while( (ca = PEM_read_bio_X509( in, NULL, NULL, NULL )) ) {
 	 r = SSL_CTX_add_extra_chain_cert( ctx, ca );
@@ -1732,9 +1744,12 @@ bgl_new_session_callback( SSL *ssl, SSL_
 	 C_SYSTEM_FAILURE( BGL_TYPE_ERROR, "ssl-session",
 			   "wrong callback arity", cb );
       } else {
+	 unsigned int sidlen;
+	 const char *sid = BGL_SSL_SESSION_get_id( sess, sidlen );
+
 	 PROCEDURE_ENTRY( cb )
 	 ( cb,
-	   string_to_bstring_len( sess->session_id, sess->session_id_length ),
+	   string_to_bstring_len( (char *)sid, sidlen ),
 	   serialized,
 	   BEOA );
 	 return 0;
@@ -2206,12 +2221,13 @@ bgl_ssl_connection_get_peer_certificate(
       RSA *rsa = NULL;
       if( NULL != (pkey = X509_get_pubkey( peer_cert ))
 	  && NULL != (rsa = EVP_PKEY_get1_RSA( pkey )) ) {
-	 BN_print( bio, rsa->n );
+	 const BIGNUM *z;
+	 BN_print( bio, BGL_RSA_N( rsa, z ) );
 	 BIO_get_mem_ptr( bio, &mem );
 	 info = MAKE_PAIR( cons( "modulus", mem ), info );
 	 BIO_reset( bio );
 
-	 BN_print( bio, rsa->e );
+	 BN_print( bio, BGL_RSA_E( rsa, z ) );
 	 BIO_get_mem_ptr( bio, &mem );
 	 info = MAKE_PAIR( cons( "exponent", mem ), info );
 	 BIO_reset( bio );
@@ -2260,7 +2276,7 @@ bgl_ssl_connection_get_peer_certificate(
 	    info );
       }
 
-      ASN1_OBJECT *eku =
+      STACK_OF(ASN1_OBJECT) *eku =
 	 (ASN1_OBJECT *)X509_get_ext_d2i( peer_cert, NID_ext_key_usage, NULL, NULL );
       if( eku != NULL ) {
 	 char buf[ 256 ];
@@ -2404,11 +2420,23 @@ bgl_ssl_ctx_init( secure_context sc ) {
       goto unsupported;
 #endif
    } else if( !strcmp( sslmethod, "TLSv1_method" ) ) {
+#if( BGLSSL_HAVE_TLSV1 )      
       sc->BgL_z42nativez42 = SSL_CTX_new( TLSv1_method() );
+#else      
+      sc->BgL_z42nativez42 = SSL_CTX_new( TLS_method() );
+#endif      
    } else if( !strcmp( sslmethod, "TLSv1_server_method" ) ) {
+#if( BGLSSL_HAVE_TLSV1 )      
       sc->BgL_z42nativez42 = SSL_CTX_new( TLSv1_server_method() );
+#else      
+      sc->BgL_z42nativez42 = SSL_CTX_new( TLS_server_method() );
+#endif      
    } else if( !strcmp( sslmethod, "TLSv1_client_method" ) ) {
+#if( BGLSSL_HAVE_TLSV1 )      
       sc->BgL_z42nativez42 = SSL_CTX_new( TLSv1_client_method() );
+#else      
+      sc->BgL_z42nativez42 = SSL_CTX_new( TLS_client_method() );
+#endif      
    } else {
       goto unsupported;
    }
@@ -2513,12 +2541,24 @@ bgl_bn_bin2bn( char *s, int len ) {
 }
 
 /*---------------------------------------------------------------------*/
+/*    BGL_RUNTIME_DEF void                                             */
+/*    bgl_dh_pub_priv_key_set ...                                      */
+/*---------------------------------------------------------------------*/
+BGL_RUNTIME_DEF void
+bgl_dh_pub_priv_key_set( DH *dh, BIGNUM *pub, BIGNUM *priv ) {
+   if( pub != 0 && priv !=0 ) {
+      BGL_DH_SET_PUB_PRIV( dh, pub, priv );
+   }
+}
+
+/*---------------------------------------------------------------------*/
 /*    BIGNUM *                                                         */
 /*    bgl_dh_private_key ...                                           */
 /*---------------------------------------------------------------------*/
 BGL_RUNTIME_DEF BIGNUM *
 bgl_dh_private_key( DH *dh ) {
-   return dh->priv_key;
+   const BIGNUM *priv_key;
+   return (BIGNUM *)BGL_DH_GET_PRIV( dh, priv_key );
 }
 
 /*---------------------------------------------------------------------*/
@@ -2527,7 +2567,7 @@ bgl_dh_private_key( DH *dh ) {
 /*---------------------------------------------------------------------*/
 BGL_RUNTIME_DEF void 
 bgl_dh_private_key_set( DH *dh, BIGNUM *v ) {
-   dh->priv_key = v;
+   BGL_DH_SET_PRIV( dh, v );
 }
 
 /*---------------------------------------------------------------------*/
@@ -2536,7 +2576,8 @@ bgl_dh_private_key_set( DH *dh, BIGNUM *
 /*---------------------------------------------------------------------*/
 BGL_RUNTIME_DEF BIGNUM *
 bgl_dh_public_key( DH *dh ) {
-   return dh->pub_key;
+   const BIGNUM *pub_key;
+   return (BIGNUM *)BGL_DH_GET_PUB( dh, pub_key );
 }
 
 /*---------------------------------------------------------------------*/
@@ -2545,7 +2586,18 @@ bgl_dh_public_key( DH *dh ) {
 /*---------------------------------------------------------------------*/
 BGL_RUNTIME_DEF void 
 bgl_dh_public_key_set( DH *dh, BIGNUM *v ) {
-   dh->pub_key = v;
+   BGL_DH_SET_PUB( dh, v );
+}
+
+/*---------------------------------------------------------------------*/
+/*    void                                                             */
+/*    bgl_dh_pqg_set ...                                               */
+/*---------------------------------------------------------------------*/
+BGL_RUNTIME_DEF void 
+bgl_dh_pqg_set( DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g ) {
+   if( p != 0 && g != 0 ) {
+      BGL_DH_SET_PQG( dh, p, q, g );
+   }
 }
 
 /*---------------------------------------------------------------------*/
@@ -2554,7 +2606,8 @@ bgl_dh_public_key_set( DH *dh, BIGNUM *v
 /*---------------------------------------------------------------------*/
 BGL_RUNTIME_DEF BIGNUM *
 bgl_dh_p( DH *dh ) {
-   return dh->p;
+   const BIGNUM *key;
+   return (BIGNUM *)BGL_DH_GET_P( dh, key );
 }
 
 /*---------------------------------------------------------------------*/
@@ -2563,7 +2616,26 @@ bgl_dh_p( DH *dh ) {
 /*---------------------------------------------------------------------*/
 BGL_RUNTIME_DEF void 
 bgl_dh_p_set( DH *dh, BIGNUM *v ) {
-   dh->p = v;
+   BGL_DH_SET_P( dh, v );
+}
+
+/*---------------------------------------------------------------------*/
+/*    BIGNUM *                                                         */
+/*    bgl_dh_q ...                                                     */
+/*---------------------------------------------------------------------*/
+BGL_RUNTIME_DEF BIGNUM *
+bgl_dh_q( DH *dh ) {
+   const BIGNUM *key;
+   return (BIGNUM *)BGL_DH_GET_Q( dh, key );
+}
+
+/*---------------------------------------------------------------------*/
+/*    void                                                             */
+/*    bgl_dh_q_set ...                                                 */
+/*---------------------------------------------------------------------*/
+BGL_RUNTIME_DEF void 
+bgl_dh_q_set( DH *dh, BIGNUM *v ) {
+   BGL_DH_SET_Q( dh, v );
 }
 
 /*---------------------------------------------------------------------*/
@@ -2572,7 +2644,8 @@ bgl_dh_p_set( DH *dh, BIGNUM *v ) {
 /*---------------------------------------------------------------------*/
 BGL_RUNTIME_DEF BIGNUM *
 bgl_dh_g( DH *dh ) {
-   return dh->g;
+   const BIGNUM *key;
+   return (BIGNUM *)BGL_DH_GET_G( dh, key );
 }
 
 /*---------------------------------------------------------------------*/
@@ -2581,7 +2654,7 @@ bgl_dh_g( DH *dh ) {
 /*---------------------------------------------------------------------*/
 BGL_RUNTIME_DEF void 
 bgl_dh_g_set( DH *dh, BIGNUM *v ) {
-   dh->g = v;
+   BGL_DH_SET_G( dh, v );
 }
 
 /*---------------------------------------------------------------------*/
@@ -2605,8 +2678,12 @@ bgl_ssl_get_ciphers() {
 #else
    bgl_ssl_init();
 #endif
-   
+
+#if( BGLSSL_HAVE_TLSV1 )  
    ctx = SSL_CTX_new( TLSv1_server_method() );
+#else   
+   ctx = SSL_CTX_new( TLS_server_method() );
+#endif   
    if( ctx == NULL ) {
       C_SYSTEM_FAILURE( BGL_IO_ERROR,
 			"ssl-get-ciphers",
@@ -2630,7 +2707,7 @@ bgl_ssl_get_ciphers() {
       res = create_vector( sk_SSL_CIPHER_num( ciphers ) );
       
       for( i = 0; i < sk_SSL_CIPHER_num( ciphers ); ++i ) {
-	 SSL_CIPHER *c = sk_SSL_CIPHER_value( ciphers, i );
+	 const SSL_CIPHER *c = sk_SSL_CIPHER_value( ciphers, i );
 	 VECTOR_SET( res, i, string_to_bstring( (char *)SSL_CIPHER_get_name( c ) ) );
       }
 
@@ -2719,7 +2796,8 @@ bgl_ssl_hash_init( ssl_hash hash ) {
       (void *)EVP_get_digestbyname( (const char *)BSTRING_TO_STRING( hash->BgL_typez00 ) );
    if( !(hash->BgL_z42mdz42) ) return 0;
 
-   hash->BgL_z42mdzd2ctxz90 = GC_MALLOC( sizeof( EVP_MD_CTX ) );
+   hash->BgL_z42mdzd2ctxz90 = BGL_EVP_MD_CTX_new();
+   
    EVP_MD_CTX_init( hash->BgL_z42mdzd2ctxz90 );
    
    EVP_DigestInit_ex( hash->BgL_z42mdzd2ctxz90, hash->BgL_z42mdz42, NULL );
@@ -2755,7 +2833,8 @@ bgl_ssl_hash_digest( ssl_hash hash ) {
       unsigned int md_len;
 
       EVP_DigestFinal_ex( hash->BgL_z42mdzd2ctxz90, md_value, &md_len );
-      EVP_MD_CTX_cleanup( hash->BgL_z42mdzd2ctxz90 );
+      BGL_EVP_MD_CTX_reset( hash->BgL_z42mdzd2ctxz90 );
+      BGL_EVP_MD_CTX_free( hash->BgL_z42mdzd2ctxz90 );
       hash->BgL_z42mdzd2ctxz90 = 0L;
 
       return string_to_bstring_len( md_value, md_len );
@@ -2786,19 +2865,19 @@ bgl_ssl_hmac_init( ssl_hmac hmac, obj_t
       (void *)EVP_get_digestbyname( (const char *)BSTRING_TO_STRING( type ) );
    if( !(hmac->BgL_z42mdz42) ) return BFALSE;
 
-   hmac->BgL_z42mdzd2ctxz90 = GC_MALLOC( sizeof( HMAC_CTX ) );
-   HMAC_CTX_init( hmac->BgL_z42mdzd2ctxz90 );
+   hmac->BgL_z42mdzd2ctxz90 = BGL_HMAC_CTX_new();
+   BGL_HMAC_CTX_init( hmac->BgL_z42mdzd2ctxz90 );
 
    if( !STRINGP( key ) ) {
-      HMAC_Init( hmac->BgL_z42mdzd2ctxz90,
-		 "",
-		 0,
-		 hmac->BgL_z42mdz42 );
+      BGL_HMAC_Init( hmac->BgL_z42mdzd2ctxz90,
+		     "",
+		     0,
+		     hmac->BgL_z42mdz42 );
    } else {
-      HMAC_Init( hmac->BgL_z42mdzd2ctxz90,
-		 BSTRING_TO_STRING( key ),
-		 STRING_LENGTH( key ),
-		 hmac->BgL_z42mdz42 );
+      BGL_HMAC_Init( hmac->BgL_z42mdzd2ctxz90,
+		     BSTRING_TO_STRING( key ),
+		     STRING_LENGTH( key ),
+		     hmac->BgL_z42mdz42 );
    }
    return BTRUE;
 }
@@ -2832,7 +2911,8 @@ bgl_ssl_hmac_digest( ssl_hmac hmac ) {
       unsigned int md_len;
 
       HMAC_Final( hmac->BgL_z42mdzd2ctxz90, md_value, &md_len );
-      HMAC_CTX_cleanup( hmac->BgL_z42mdzd2ctxz90 );
+      BGL_HMAC_CTX_reset( hmac->BgL_z42mdzd2ctxz90 );
+      BGL_HMAC_CTX_free( hmac->BgL_z42mdzd2ctxz90 );
       hmac->BgL_z42mdzd2ctxz90 = 0L;
 
       return string_to_bstring_len( md_value, md_len );
@@ -2858,12 +2938,12 @@ bgl_ssl_sign_init( ssl_sign sign, obj_t
 #else
    bgl_ssl_init();
 #endif
-   
+
    sign->BgL_z42mdz42 =
       (void *)EVP_get_digestbyname( (const char *)BSTRING_TO_STRING( type ) );
    if( !(sign->BgL_z42mdz42) ) return 0;
 
-   sign->BgL_z42mdzd2ctxz90 = GC_MALLOC( sizeof( EVP_MD_CTX ) );
+   sign->BgL_z42mdzd2ctxz90 = BGL_EVP_MD_CTX_new();
    EVP_MD_CTX_init( sign->BgL_z42mdzd2ctxz90 );
    
    EVP_SignInit_ex( sign->BgL_z42mdzd2ctxz90, sign->BgL_z42mdz42, NULL );
@@ -2916,7 +2996,8 @@ bgl_ssl_sign_sign( ssl_sign sign, obj_t
 	 return BFALSE;
       }
 
-      EVP_MD_CTX_cleanup( sign->BgL_z42mdzd2ctxz90 );
+      BGL_EVP_MD_CTX_reset( sign->BgL_z42mdzd2ctxz90 );
+      BGL_EVP_MD_CTX_free( sign->BgL_z42mdzd2ctxz90 );
       sign->BgL_z42mdzd2ctxz90 = 0L;
 
       EVP_PKEY_free( pkey );
@@ -2950,7 +3031,7 @@ bgl_ssl_verify_init( ssl_verify verify,
       (void *)EVP_get_digestbyname( (const char *)BSTRING_TO_STRING( type ) );
    if( !(verify->BgL_z42mdz42) ) return 0;
 
-   verify->BgL_z42mdzd2ctxz90 = GC_MALLOC( sizeof( EVP_MD_CTX ) );
+   verify->BgL_z42mdzd2ctxz90 = BGL_EVP_MD_CTX_new();
    EVP_MD_CTX_init( verify->BgL_z42mdzd2ctxz90 );
    
    EVP_VerifyInit_ex( verify->BgL_z42mdzd2ctxz90, verify->BgL_z42mdz42, NULL );
@@ -3062,7 +3143,8 @@ bgl_ssl_verify_final( ssl_verify verify,
       if( pkey ) EVP_PKEY_free( pkey );
       if( x509 ) X509_free( x509 );
       if( bp ) BIO_free( bp );
-      EVP_MD_CTX_cleanup( verify->BgL_z42mdzd2ctxz90 );
+      BGL_EVP_MD_CTX_reset( verify->BgL_z42mdzd2ctxz90 );
+      BGL_EVP_MD_CTX_free( verify->BgL_z42mdzd2ctxz90 );
       verify->BgL_z42mdzd2ctxz90 = 0;
 
       return r && (r != -1);
@@ -3101,7 +3183,7 @@ bgl_ssl_cipher_init( ssl_cipher cipher,
 				    EVP_md5(), NULL,
 				    &(STRING_REF( keybuf, koffset )), klen,
 				    1, key, iv );
-      EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)GC_MALLOC( sizeof( EVP_CIPHER_CTX ) );
+      EVP_CIPHER_CTX *ctx = BGL_EVP_CIPHER_CTX_new();
       cipher->BgL_z42cipherzd2ctxz90 = ctx;
 
       EVP_CIPHER_CTX_init( ctx );
@@ -3110,7 +3192,8 @@ bgl_ssl_cipher_init( ssl_cipher cipher,
       
       if( !EVP_CIPHER_CTX_set_key_length( ctx, key_len )) {
 	 fprintf( stderr, "node-crypto : Invalid key length %d\n", klen );
-	 EVP_CIPHER_CTX_cleanup( ctx );
+	 BGL_EVP_CIPHER_CTX_reset( ctx );
+	 BGL_EVP_CIPHER_CTX_free( ctx );
 	 return 0;
       }
       EVP_CipherInit_ex( ctx, NULL, NULL,
@@ -3131,7 +3214,7 @@ bgl_ssl_cipher_initiv( ssl_cipher cipher
 		       obj_t iv, long ivoffset, long ivlen, bool_t enc ) {
 #if( SSL_DEBUG )
    BGL_MUTEX_LOCK( bigloo_mutex );
-   
+
    if( !init ) {
       init = 1;
       bgl_ssl_library_init();
@@ -3142,11 +3225,11 @@ bgl_ssl_cipher_initiv( ssl_cipher cipher
 #else
    bgl_ssl_init();
 #endif
-   
+    
    cipher->BgL_z42cipherz42 =
       (void *)EVP_get_cipherbyname( (const char *)BSTRING_TO_STRING( type ) );
 
-   if( !cipher ) {
+   if( !cipher->BgL_z42cipherz42 ) {
       fprintf( stderr, "node-crypto : Unknown cipher %s\n",
 	       (const char *)BSTRING_TO_STRING( type ));
       return 0;
@@ -3160,15 +3243,16 @@ bgl_ssl_cipher_initiv( ssl_cipher cipher
       fprintf( stderr, "node-crypto : Invalid IV length %d\n", ivlen );
       return 0;
    } else {
-      EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)GC_MALLOC( sizeof( EVP_CIPHER_CTX ) );
+      EVP_CIPHER_CTX *ctx = BGL_EVP_CIPHER_CTX_new();
       cipher->BgL_z42cipherzd2ctxz90 = ctx;
-       
+
       EVP_CIPHER_CTX_init( ctx );
-      EVP_CipherInit_ex( ctx, cipher->BgL_z42cipherz42, NULL, NULL, NULL, 1 );
+      EVP_CipherInit_ex( ctx, cipher->BgL_z42cipherz42, NULL, NULL, NULL, enc );
       
       if( !EVP_CIPHER_CTX_set_key_length( ctx, klen ) ) {
 	 fprintf( stderr, "node-crypto : Invalid key length %d\n", klen );
-	 EVP_CIPHER_CTX_cleanup( ctx );
+	 BGL_EVP_CIPHER_CTX_reset( ctx );
+	 BGL_EVP_CIPHER_CTX_free( ctx );
 	 return 0;
       }
       
@@ -3176,6 +3260,7 @@ bgl_ssl_cipher_initiv( ssl_cipher cipher
 			 &(STRING_REF( key, koffset )),
 			 &(STRING_REF( iv, ivoffset )),
 			 enc );
+
       return 1;
    }
 }
@@ -3232,8 +3317,10 @@ bgl_cipher_final( ssl_cipher cipher ) {
       obj_t obj = make_string( size, ' ' );
       int r;
 
-      r = EVP_CipherFinal_ex( ctx, &(STRING_REF( obj, 0 )), &size );
-      EVP_CIPHER_CTX_cleanup( ctx );
+      r = EVP_CipherFinal_ex( ctx, BSTRING_TO_STRING( obj ), &size );
+
+      BGL_EVP_CIPHER_CTX_reset( ctx );
+      BGL_EVP_CIPHER_CTX_free( ctx );
       cipher->BgL_z42cipherzd2ctxz90 = 0L;
 
       if( r ) {
@@ -3269,3 +3356,14 @@ bgl_pkcs5_pbkdf2_hmac_sha1( obj_t pass,
    }
 }
       
+/*---------------------------------------------------------------------*/
+/*    bgl_ssl_error_string                                             */
+/*---------------------------------------------------------------------*/
+obj_t bgl_ssl_error_string() {
+   int err = ERR_get_error();
+   obj_t errmsg = make_string( 128, 0 );
+   
+   ERR_error_string_n(err, BSTRING_TO_STRING( errmsg ), 128 );
+
+   return errmsg;
+}
--- api/ssl/src/C/bglssl.h.in.orig	2015-12-21 05:31:11.000000000 -0700
+++ api/ssl/src/C/bglssl.h.in	2017-02-11 16:43:49.192028737 -0700
@@ -21,6 +21,7 @@
 #define BGLSSL_TLSV1_1 6
 #define BGLSSL_TLSV1_2 7
 
+#define BGLSSL_HAVE_TLSV1 1
 #define BGLSSL_HAVE_TLSV1_1 @HAVETLS1_1@
 #define BGLSSL_HAVE_TLSV1_2 @HAVETLS1_2@
 #define BGLSSL_HAVE_DTLS @HAVEDTLS@
@@ -29,5 +30,111 @@
 #define BGLSSL_HAVE_SSLV23 @HAVEV23@
 #define BGLSSL_HAVE_RAND_STATUS @HAVERANDSTATUS@
 #define BGLSSL_HAVE_RAND_POLL @HAVERANDPOLL@
+#define BGLSSL_HAVE_GETTER 1
   
+#if( !defined( SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE ) )
+#  define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE \
+  SSL_F_SSL_CTX_USE_CERTIFICATE_FILE
+#endif
+
+#if BGLSSL_HAVE_GETTER
+#  define BGL_SSL_CTX_get_ssl_method( ctx ) SSL_CTX_get_ssl_method( ctx )
+#else
+#  define BGL_SSL_CTX_get_ssl_method( ctx ) (ctx->method)
+#endif
+
+#if BGLSSL_HAVE_GETTER
+#  define BGL_SSL_CTX_clear_extra_chain_certs( ctx ) \
+   SSL_CTX_clear_extra_chain_certs( ctx )
+#else
+#  define BGL_SSL_CTX_clear_extra_chain_certs( ctx ) \
+   ((ctx->extra_certs != NULL) ? \
+    (sk_X509_pop_free( ctx->extra_certs, X509_free ), ctx->extra_certs = NULL) \
+    : 0)
+#endif
+
+#if BGLSSL_HAVE_GETTER
+#  define BGL_SSL_SESSION_get_id( sess, len ) \
+  SSL_SESSION_get_id( sess, &len )
+#else
+#  define BGL_SSL_SESSION_get_id( sess, len ) \
+  (len = sess->session_id_length, sess->session_id)
+#endif
+
+#if( !defined( STACK_OF ) )
+#  define STACK_OF( type ) type
+#endif
+
+#if BGLSSL_HAVE_GETTER
+#  define BGL_EVP_MD_CTX_new() EVP_MD_CTX_new()
+#  define BGL_EVP_MD_CTX_free( evp ) EVP_MD_CTX_free( evp )
+#  define BGL_EVP_MD_CTX_reset( evp ) EVP_MD_CTX_reset( evp ) 
+#else
+#  define BGL_EVP_MD_CTX_new() ((EVP_MD_CTX *)GC_MALLOC( sizeof( EVP_MD_CTX ) ))
+#  define BGL_EVP_MD_CTX_free( evp )
+#  define BGL_EVP_MD_CTX_reset( evp ) EVP_MD_CTX_cleanup( evp ) 
+#endif
+
+#if BGLSSL_HAVE_GETTER
+#  define BGL_EVP_CIPHER_CTX_new() EVP_CIPHER_CTX_new()
+#  define BGL_EVP_CIPHER_CTX_free( evp ) EVP_CIPHER_CTX_free( evp )
+#  define BGL_EVP_CIPHER_CTX_reset( evp ) EVP_CIPHER_CTX_reset( evp )
+#else
+#  define BGL_EVP_CIPHER_CTX_new() ((EVP_CIPHER_CTX *)GC_MALLOC( sizeof( EVP_CIPHER_CTX ) ))
+#  define BGL_EVP_CIPHER_CTX_free( evp )
+#  define BGL_EVP_CIPHER_CTX_reset( evp ) EVP_CIPHER_CTX_cleanup( evp )
+#endif
 
+#if BGLSSL_HAVE_GETTER
+#  define BGL_HMAC_CTX_new() HMAC_CTX_new()
+#  define BGL_HMAC_CTX_init( hmac ) 
+#  define BGL_HMAC_CTX_free( hmac ) HMAC_CTX_free( hmac ) 
+#  define BGL_HMAC_CTX_reset( hmac ) HMAC_CTX_reset( hmac )
+#  define BGL_HMAC_Init( c, k, l, m ) HMAC_Init_ex( c, k, l, m, 0 )
+#else
+#  define BGL_HMAC_CTX_new() ((HMAC_CTX *)GC_MALLOC( sizeof( HMAC_CTX ) ))
+#  define BGL_HMAC_CTX_init( hmac ) HMAC_CTX_init( hmac ) 
+#  define BGL_HMAC_CTX_free( hmac) 
+#  define BGL_HMAC_CTX_reset( hmac ) HMAC_CTX_cleanup( hmac )
+#  define BGL_HMAC_Init( c, k, l, m ) HMAC_Init( c, k, l, m )
+#endif
+
+#if BGLSSL_HAVE_GETTER
+#  define BGL_DH_SET_PUB_PRIV( dh, pub, priv ) DH_set0_key( dh, pub, priv )
+#  define BGL_DH_GET_PUB( dh, kres ) (DH_get0_key( dh, &kres, 0 ), kres)
+#  define BGL_DH_GET_PRIV( dh, kres ) (DH_get0_key( dh, 0, &kres ), kres)
+#  define BGL_DH_SET_PUB( dh, key ) DH_set0_key( dh, key, 0 )
+#  define BGL_DH_SET_PRIV( dh, key ) DH_set0_key( dh, 0, key )
+#  define BGL_DH_SET_PQG( dh, p, q, g ) DH_set0_pqg( dh, p, q, g )
+#  define BGL_DH_GET_P( dh, kres ) (DH_get0_pqg( dh, &kres, 0, 0 ), kres)
+#  define BGL_DH_SET_P( dh, key ) DH_set0_pqg( dh, key, 0, 0 )
+#  define BGL_DH_GET_Q( dh, kres ) (DH_get0_pqg( dh, 0, &kres, 0 ), kres)
+#  define BGL_DH_SET_Q( dh, key ) DH_set0_pqg( dh, 0, key, 0 )
+#  define BGL_DH_GET_G( dh, kres ) (DH_get0_pqg( dh, 0, 0, &kres ), kres)
+#  define BGL_DH_SET_G( dh, key ) DH_set0_pqg( dh, 0, 0, key )
+#else
+#  define BGL_DH_SET_PUB_PRIV( dh, pub, priv ) \
+  (BGL_DH_SET_PUB( dh, pub ), BGL_DH_SET_PRIV( dh, priv ))
+#  define BGL_DH_GET_PUB( dh, kres ) dh->pub_key
+#  define BGL_DH_GET_PRIV( dh, kres ) dh->priv_key
+#  define BGL_DH_SET_PUB( dh, key ) dh->pub_key = key
+#  define BGL_DH_SET_PRIV( dh, key ) dh->priv_key = key
+#  define BGL_DH_SET_PQG( dh, p, q, g ) \
+  (BGL_DH_SET_P( dh, p ), BGL_DH_SET_Q( dh, q ), BGL_DH_SET_G( dh, g ))
+#  define BGL_DH_GET_P( dh, kres ) dh->p
+#  define BGL_DH_SET_P( dh, key ) (dh->p = key)
+#  define BGL_DH_GET_Q( dh, kres ) dh->q
+#  define BGL_DH_SET_Q( dh, key ) (dh->q = key)
+#  define BGL_DH_GET_G( dh, kres ) dh->g
+#  define BGL_DH_SET_G( dh, key ) (dh->g = key)
+#endif
+
+#if BGLSSL_HAVE_GETTER
+#  define BGL_RSA_N( rsa, kres ) (RSA_get0_key( rsa, &kres, 0, 0 ), kres)
+#  define BGL_RSA_E( rsa, kres ) (RSA_get0_key( rsa, 0, &kres, 0 ), kres)
+#  define BGL_RSA_D( rsa, kres ) (RSA_get0_key( rsa, 0, 0, &kres ), kres)
+#else
+#  define BGL_RSA_N( rsa, kres ) (kres = rsa->n)
+#  define BGL_RSA_E( rsa, kres ) (kres = rsa->e)
+#  define BGL_RSA_D( rsa, kres ) (kres = rsa->d)
+#endif