From f5a3c980fcae545a7600fc1733d2e8f8916ac652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Tue, 28 Jan 2025 11:34:21 +0100 Subject: [PATCH] 2025-01-28 11:34 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * contrib/hbssl/hbssl.hbx * contrib/hbssl/bio.c ! fixed BIO_set_conn_int_port() to work with OpenSSL >= 1.1 (emulation with BIO_set_conn_port()) ! fixed BIO_get_conn_ip() to work with OpenSSL >= 1.1 (emulation with BIO_get_conn_address() and BIO_ADDR_hostname_string()) + added BIO_get_conn_address(), it returns HB_SOCKET compatible array with address * contrib/hbssl/hbssl.hbx * contrib/hbssl/sslctx.c + added new function SSL_CTX_use_RSAPrivateKey() ! respect OPENSSL_NO_RSA macro in other SSL_CTX_use_RSA*() functions * contrib/hbssl/evp.c ! use EVP_CIPHER_key_length() and EVP_CIPHER_iv_length() in EVP_BytesToKey() to detect the exact key and iv length. * contrib/hbssl/hbssl.h * contrib/hbssl/evppkey.c * contrib/hbssl/rsa.c * removed hb_RSA_par_remove() function, use RSA_up_ref() instead * contrib/hbssl/hbssl.h * contrib/hbssl/x509.c * contrib/hbssl/pem.c * contrib/hbssl/ssl.c * removed 2-nd parameter ( HB_BOOL fRelease ) from hb_X509_ret(), use X509_up_ref() instead * contrib/hbssl/pem.c * respect OPENSSL_NO_DSA, OPENSSL_NO_DH and OPENSSL_NO_RSA macros * contrib/hbssl/ssl_sock.c * added casting to pacify SSL_set_fd() warning and updated link with description of the problem --- ChangeLog.txt | 38 +++++++++++++++++++++++++++++++++++++ contrib/hbssl/bio.c | 41 +++++++++++++++++++++++++++++++++++++--- contrib/hbssl/evp.c | 4 ++-- contrib/hbssl/evppkey.c | 2 +- contrib/hbssl/hbssl.h | 3 +-- contrib/hbssl/hbssl.hbx | 2 ++ contrib/hbssl/pem.c | 29 ++++++++++++++++++++++++---- contrib/hbssl/rsa.c | 8 -------- contrib/hbssl/ssl.c | 10 ++++++++-- contrib/hbssl/ssl_sock.c | 2 +- contrib/hbssl/sslctx.c | 30 +++++++++++++++++++++++++++-- contrib/hbssl/x509.c | 7 ++----- 12 files changed, 146 insertions(+), 30 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 09ec048526..f8af7d4884 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,44 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2025-01-28 11:34 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * contrib/hbssl/hbssl.hbx + * contrib/hbssl/bio.c + ! fixed BIO_set_conn_int_port() to work with OpenSSL >= 1.1 + (emulation with BIO_set_conn_port()) + ! fixed BIO_get_conn_ip() to work with OpenSSL >= 1.1 + (emulation with BIO_get_conn_address() and BIO_ADDR_hostname_string()) + + added BIO_get_conn_address(), it returns HB_SOCKET compatible array + with address + + * contrib/hbssl/hbssl.hbx + * contrib/hbssl/sslctx.c + + added new function SSL_CTX_use_RSAPrivateKey() + ! respect OPENSSL_NO_RSA macro in other SSL_CTX_use_RSA*() functions + + * contrib/hbssl/evp.c + ! use EVP_CIPHER_key_length() and EVP_CIPHER_iv_length() in + EVP_BytesToKey() to detect the exact key and iv length. + + * contrib/hbssl/hbssl.h + * contrib/hbssl/evppkey.c + * contrib/hbssl/rsa.c + * removed hb_RSA_par_remove() function, use RSA_up_ref() instead + + * contrib/hbssl/hbssl.h + * contrib/hbssl/x509.c + * contrib/hbssl/pem.c + * contrib/hbssl/ssl.c + * removed 2-nd parameter ( HB_BOOL fRelease ) from hb_X509_ret(), + use X509_up_ref() instead + + * contrib/hbssl/pem.c + * respect OPENSSL_NO_DSA, OPENSSL_NO_DH and OPENSSL_NO_RSA macros + + * contrib/hbssl/ssl_sock.c + * added casting to pacify SSL_set_fd() warning and updated link with + description of the problem + 2025-01-26 09:57 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * contrib/3rd/sqlite3/sqlite3.hbp * use -Wno-unknown-warning-option also in GCC MacOSX builds diff --git a/contrib/hbssl/bio.c b/contrib/hbssl/bio.c index dc4e40f38e..bee4dc4729 100644 --- a/contrib/hbssl/bio.c +++ b/contrib/hbssl/bio.c @@ -694,7 +694,12 @@ HB_FUNC( BIO_SET_CONN_INT_PORT ) if( bio && HB_ISNUM( 2 ) ) { int port = hb_parni( 2 ); - hb_retnl( BIO_set_conn_port( bio, &port ) ); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + char szPort[ 12 ]; + hb_retnl( BIO_set_conn_port( bio, hb_numToStr( szPort, sizeof( szPort ), port ) ) ); +#else + hb_retnl( BIO_set_conn_int_port( bio, &port ) ); +#endif } else hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); @@ -747,8 +752,12 @@ HB_FUNC( BIO_GET_CONN_IP ) if( bio ) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L - HB_SYMBOL_UNUSED( bio ); /* TODO: reimplement using BIO_get_conn_address() */ - hb_retc_null(); + const BIO_ADDR * ba = BIO_get_conn_address( bio ); + char * pszAddr = ba ? BIO_ADDR_hostname_string( ba, 1 ) : NULL; + + hb_retc( pszAddr ); + if( pszAddr ) + OPENSSL_free( pszAddr ); #elif OPENSSL_VERSION_NUMBER >= 0x00906040L hb_retc( BIO_get_conn_ip( bio ) ); #else @@ -785,6 +794,32 @@ HB_FUNC( BIO_GET_CONN_INT_PORT ) #endif } +HB_FUNC( BIO_GET_CONN_ADDRESS ) +{ + BIO * bio = hb_BIO_par( 1 ); + + if( bio ) + { + const BIO_ADDR * ba = BIO_get_conn_address( bio ); + + if( ba ) + { + int family = BIO_ADDR_family( ba ); + char * pszAddr = BIO_ADDR_hostname_string( ba, 1 ); + + hb_reta( family == HB_SOCKET_AF_LOCAL ? 2 : 3 ); + hb_storvni( family, -1, 1 ); + hb_storvc( pszAddr, -1, 2 ); + if( family != HB_SOCKET_AF_LOCAL ) + hb_storvni( hb_socketNToHS( BIO_ADDR_rawport( ba ) ), -1, 3 ); + if( pszAddr ) + OPENSSL_free( pszAddr ); + } + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + HB_FUNC( BIO_SET_NBIO ) { BIO * bio = hb_BIO_par( 1 ); diff --git a/contrib/hbssl/evp.c b/contrib/hbssl/evp.c index 0e133ba7d3..5c43b924e5 100644 --- a/contrib/hbssl/evp.c +++ b/contrib/hbssl/evp.c @@ -108,8 +108,8 @@ HB_FUNC( EVP_BYTESTOKEY ) key, iv ) ); - hb_storc( ( char * ) key, 6 ); - hb_storc( ( char * ) iv, 7 ); + hb_storclen( ( char * ) key, EVP_CIPHER_key_length( cipher ), 6 ); + hb_storclen( ( char * ) iv, EVP_CIPHER_iv_length( cipher ), 7 ); } else hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); diff --git a/contrib/hbssl/evppkey.c b/contrib/hbssl/evppkey.c index dc35ba5dd4..56977f471f 100644 --- a/contrib/hbssl/evppkey.c +++ b/contrib/hbssl/evppkey.c @@ -238,7 +238,7 @@ HB_FUNC( EVP_PKEY_ASSIGN_RSA ) res = EVP_PKEY_assign_RSA( pkey, key ); if( res != 0 ) - hb_RSA_par_remove( 2 ); + RSA_up_ref( key ); } hb_retni( res ); } diff --git a/contrib/hbssl/hbssl.h b/contrib/hbssl/hbssl.h index 1db3dd2d98..f3b055867b 100644 --- a/contrib/hbssl/hbssl.h +++ b/contrib/hbssl/hbssl.h @@ -215,11 +215,10 @@ extern SSL_SESSION * hb_SSL_SESSION_par( int iParam ); extern HB_BOOL hb_X509_is( int iParam ); extern X509 * hb_X509_par( int iParam ); -extern void hb_X509_ret( X509 * x509, HB_BOOL fRelease ); +extern void hb_X509_ret( X509 * x509 ); extern HB_BOOL hb_RSA_is( int iParam ); extern RSA * hb_RSA_par( int iParam ); -extern void hb_RSA_par_remove( int iParam ); extern void hb_RSA_ret( RSA * rsa ); extern HB_BOOL hb_EVP_MD_is( int iParam ); diff --git a/contrib/hbssl/hbssl.hbx b/contrib/hbssl/hbssl.hbx index e4803fccc4..0c27a70413 100644 --- a/contrib/hbssl/hbssl.hbx +++ b/contrib/hbssl/hbssl.hbx @@ -31,6 +31,7 @@ DYNAMIC BIO_free DYNAMIC BIO_free_all DYNAMIC BIO_gets DYNAMIC BIO_get_close +DYNAMIC BIO_get_conn_address DYNAMIC BIO_get_conn_hostname DYNAMIC BIO_get_conn_int_port DYNAMIC BIO_get_conn_ip @@ -292,6 +293,7 @@ DYNAMIC SSL_CTX_use_certificate_file DYNAMIC SSL_CTX_use_PrivateKey DYNAMIC SSL_CTX_use_PrivateKey_ASN1 DYNAMIC SSL_CTX_use_PrivateKey_file +DYNAMIC SSL_CTX_use_RSAPrivateKey DYNAMIC SSL_CTX_use_RSAPrivateKey_ASN1 DYNAMIC SSL_CTX_use_RSAPrivateKey_file DYNAMIC SSL_do_handshake diff --git a/contrib/hbssl/pem.c b/contrib/hbssl/pem.c index 3396a940b0..a4ea34300c 100644 --- a/contrib/hbssl/pem.c +++ b/contrib/hbssl/pem.c @@ -134,7 +134,7 @@ static void hb_PEM_read_bio( PEM_READ_BIO * func, HB_PEM_TYPES type ) switch( type ) { case hb_PEM_X509: - hb_X509_ret( ( X509 * ) result, HB_TRUE ); + hb_X509_ret( ( X509 * ) result ); break; case hb_PEM_EVP_PKEY: hb_EVP_PKEY_ret( ( EVP_PKEY * ) result ); @@ -157,17 +157,38 @@ static void hb_PEM_read_bio( PEM_READ_BIO * func, HB_PEM_TYPES type ) hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } +#define HB_PEM_ERR_NOFUNC() hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ) + +#ifdef OPENSSL_NO_DSA +HB_FUNC( PEM_READ_BIO_DSAPRIVATEKEY ) { HB_PEM_ERR_NOFUNC(); } +HB_FUNC( PEM_READ_BIO_DSA_PUBKEY ) { HB_PEM_ERR_NOFUNC(); } +HB_FUNC( PEM_READ_BIO_DSAPARAMS ) { HB_PEM_ERR_NOFUNC(); } +#else HB_FUNC( PEM_READ_BIO_DSAPRIVATEKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_DSAPrivateKey, hb_PEM_ANY ); } HB_FUNC( PEM_READ_BIO_DSA_PUBKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_DSA_PUBKEY , hb_PEM_ANY ); } HB_FUNC( PEM_READ_BIO_DSAPARAMS ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_DSAparams , hb_PEM_ANY ); } +#endif + +#ifdef OPENSSL_NO_DH +HB_FUNC( PEM_READ_BIO_DHPARAMS ) { HB_PEM_ERR_NOFUNC(); } +#else HB_FUNC( PEM_READ_BIO_DHPARAMS ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_DHparams , hb_PEM_ANY ); } +#endif + +#ifdef OPENSSL_NO_RSA +HB_FUNC( PEM_READ_BIO_RSAPRIVATEKEY ) { HB_PEM_ERR_NOFUNC(); } +HB_FUNC( PEM_READ_BIO_RSAPUBLICKEY ) { HB_PEM_ERR_NOFUNC(); } +HB_FUNC( PEM_READ_BIO_RSA_PUBKEY ) { HB_PEM_ERR_NOFUNC(); } +#else +HB_FUNC( PEM_READ_BIO_RSAPRIVATEKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_RSAPrivateKey, hb_PEM_RSA ); } +HB_FUNC( PEM_READ_BIO_RSAPUBLICKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_RSAPublicKey , hb_PEM_RSA ); } +HB_FUNC( PEM_READ_BIO_RSA_PUBKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_RSA_PUBKEY , hb_PEM_RSA ); } +#endif + HB_FUNC( PEM_READ_BIO_X509_REQ ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_X509_REQ , hb_PEM_ANY ); } HB_FUNC( PEM_READ_BIO_X509_CRL ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_X509_CRL , hb_PEM_ANY ); } HB_FUNC( PEM_READ_BIO_PKCS7 ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_PKCS7 , hb_PEM_ANY ); } -HB_FUNC( PEM_READ_BIO_RSAPRIVATEKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_RSAPrivateKey, hb_PEM_RSA ); } -HB_FUNC( PEM_READ_BIO_RSAPUBLICKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_RSAPublicKey , hb_PEM_RSA ); } -HB_FUNC( PEM_READ_BIO_RSA_PUBKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_RSA_PUBKEY , hb_PEM_RSA ); } HB_FUNC( PEM_READ_X509 ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_X509 , hb_PEM_X509 ); } HB_FUNC( PEM_READ_X509_AUX ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_X509_AUX , hb_PEM_X509 ); } HB_FUNC( PEM_READ_PRIVATEKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_PrivateKey , hb_PEM_EVP_PKEY ); } diff --git a/contrib/hbssl/rsa.c b/contrib/hbssl/rsa.c index 5160b5c13e..ff60137e47 100644 --- a/contrib/hbssl/rsa.c +++ b/contrib/hbssl/rsa.c @@ -81,14 +81,6 @@ RSA * hb_RSA_par( int iParam ) return ph ? ( RSA * ) *ph : NULL; } -void hb_RSA_par_remove( int iParam ) -{ - void ** ph = ( void ** ) hb_parptrGC( &s_gcRSA_funcs, iParam ); - - if( ph && * ph ) - *ph = NULL; -} - void hb_RSA_ret( RSA * rsa ) { void ** ph = ( void ** ) hb_gcAllocate( sizeof( RSA * ), &s_gcRSA_funcs ); diff --git a/contrib/hbssl/ssl.c b/contrib/hbssl/ssl.c index a78087500e..ef7f0ffa05 100644 --- a/contrib/hbssl/ssl.c +++ b/contrib/hbssl/ssl.c @@ -1429,7 +1429,13 @@ HB_FUNC( SSL_GET_CERTIFICATE ) SSL * ssl = hb_SSL_par( 1 ); if( ssl ) - hb_X509_ret( SSL_get_certificate( ssl ), HB_FALSE ); + { + X509 * x509 = SSL_get_certificate( ssl ); + + if( x509 ) + X509_up_ref( x509 ); + hb_X509_ret( x509 ); + } } else hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); @@ -1442,7 +1448,7 @@ HB_FUNC( SSL_GET_PEER_CERTIFICATE ) SSL * ssl = hb_SSL_par( 1 ); if( ssl ) - hb_X509_ret( SSL_get_peer_certificate( ssl ), HB_TRUE ); + hb_X509_ret( SSL_get_peer_certificate( ssl ) ); } else hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); diff --git a/contrib/hbssl/ssl_sock.c b/contrib/hbssl/ssl_sock.c index 8e7b59a2f1..ae75126974 100644 --- a/contrib/hbssl/ssl_sock.c +++ b/contrib/hbssl/ssl_sock.c @@ -290,7 +290,7 @@ PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer, pStream->blocking = ! pStream->blocking; SSL_set_mode( ssl, HB_SSL_MODE_AUTO_RETRY ); - iResult = SSL_set_fd( ssl, sd ); /* Truncates `sd` on win64. OpenSSL bug: https://rt.openssl.org/Ticket/Display.html?id=1928&user=guest&pass=guest */ + iResult = SSL_set_fd( ssl, ( int ) sd ); /* Truncates `sd` on win64. https://docs.openssl.org/3.0/man3/SSL_set_fd/#notes */ timer = hb_timerInit( timeout ); diff --git a/contrib/hbssl/sslctx.c b/contrib/hbssl/sslctx.c index ccb1316a4c..d409681e7a 100644 --- a/contrib/hbssl/sslctx.c +++ b/contrib/hbssl/sslctx.c @@ -56,9 +56,10 @@ #endif #include "hbssl.h" - #include "hbapiitm.h" +#include + static HB_GARBAGE_FUNC( SSL_CTX_release ) { void ** ph = ( void ** ) Cargo; @@ -697,8 +698,27 @@ HB_FUNC( SSL_CTX_USE_PRIVATEKEY_FILE ) hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } +HB_FUNC( SSL_CTX_USE_RSAPRIVATEKEY ) +{ +#ifndef OPENSSL_NO_RSA + if( hb_SSL_CTX_is( 1 ) && hb_RSA_is( 2 ) ) + { + SSL_CTX * ctx = hb_SSL_CTX_par( 1 ); + RSA * rsa = hb_RSA_par( 2 ); + + if( ctx && rsa ) + hb_retni( SSL_CTX_use_RSAPrivateKey( ctx, rsa ) ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif +} + HB_FUNC( SSL_CTX_USE_RSAPRIVATEKEY_FILE ) { +#ifndef OPENSSL_NO_RSA if( hb_SSL_CTX_is( 1 ) ) { SSL_CTX * ctx = hb_SSL_CTX_par( 1 ); @@ -708,10 +728,14 @@ HB_FUNC( SSL_CTX_USE_RSAPRIVATEKEY_FILE ) } else hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif } HB_FUNC( SSL_CTX_USE_RSAPRIVATEKEY_ASN1 ) { +#ifndef OPENSSL_NO_RSA if( hb_SSL_CTX_is( 1 ) ) { SSL_CTX * ctx = hb_SSL_CTX_par( 1 ); @@ -721,6 +745,9 @@ HB_FUNC( SSL_CTX_USE_RSAPRIVATEKEY_ASN1 ) } else hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif } HB_FUNC( SSL_CTX_USE_PRIVATEKEY_ASN1 ) @@ -808,7 +835,6 @@ HB_FUNC( SSL_CTX_SET_DEFAULT_VERIFY_PATHS ) X509_STORE * SSL_CTX_get_cert_store( const SSL_CTX * ); void SSL_CTX_set_cert_store( SSL_CTX *, X509_STORE * ); void SSL_CTX_set_cert_store( SSL_CTX * ctx, X509_STORE * cs ); -int SSL_CTX_use_RSAPrivateKey( SSL_CTX * ctx, RSA * rsa ); long SSL_CTX_ctrl( SSL_CTX * ctx, int cmd, long larg, char * parg ); void SSL_CTX_set_app_data( SSL_CTX * ctx, void * arg ); diff --git a/contrib/hbssl/x509.c b/contrib/hbssl/x509.c index 365c2083f1..40720b375e 100644 --- a/contrib/hbssl/x509.c +++ b/contrib/hbssl/x509.c @@ -60,7 +60,6 @@ typedef struct { X509 * pX509; - HB_BOOL fRelease; } HB_X509, * PHB_X509; static HB_GARBAGE_FUNC( X509_release ) @@ -71,8 +70,7 @@ static HB_GARBAGE_FUNC( X509_release ) if( ph && ph->pX509 ) { /* Destroy the object */ - if( ph->fRelease ) - X509_free( ( X509 * ) ph->pX509 ); + X509_free( ( X509 * ) ph->pX509 ); /* set pointer to NULL just in case */ ph->pX509 = NULL; @@ -97,12 +95,11 @@ X509 * hb_X509_par( int iParam ) return ph ? ph->pX509 : NULL; } -void hb_X509_ret( X509 * x509, HB_BOOL fRelease ) +void hb_X509_ret( X509 * x509 ) { PHB_X509 ph = ( PHB_X509 ) hb_gcAllocate( sizeof( HB_X509 ), &s_gcX509_funcs ); ph->pX509 = x509; - ph->fRelease = fRelease; hb_retptrGC( ( void * ) ph ); }