From 74322e702c6040c69df328db62da04b8f7b39ed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Wed, 22 Nov 2023 09:06:29 +0100 Subject: [PATCH] 2023-11-22 09:06 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * contrib/hbssl/hbssl.hbm * contrib/hbssl/hbssl.hbx * contrib/hbssl/hbssl.h + contrib/hbssl/rsa.c + added PRG functions for RSA encryption/decryption: RSA_size( ) -> RSA_public_encrypt( , , @ ; [, = HB_RSA_PKCS1_PADDING ] ) ; -> > 0 | <= 0 RSA_private_decrypt( , , @ ; [, = HB_RSA_PKCS1_PADDING ] ) ; -> > 0 | <= 0 RSA_private_encrypt( , , @ ; [, = HB_RSA_PKCS1_PADDING ] ) ; -> > 0 | <= 0 RSA_public_decrypt( , , @ ; [, = HB_RSA_PKCS1_PADDING ] ) ; -> > 0 | <= 0 + added C functions for manipulating RSA keys inside HB_ITEMs: HB_BOOL hb_RSA_is( int iParam ); RSA * hb_RSA_par( int iParam ); void hb_RSA_ret( RSA * rsa ); * contrib/hbssl/pem.c + added support for RSA keys. Now the following PRG functions return RSA key which can be passed to RSA_* functions: PEM_READ_BIO_RSAPRIVATEKEY() PEM_READ_BIO_RSAPUBLICKEY() PEM_READ_BIO_RSA_PUBKEY() * contrib/hbssl/evppkey.c + added functions for EVP_PKEY encryption/decryption: EVP_PKEY_base_id( ) -> EVP_PKEY_CTX_new( ) -> EVP_PKEY_encrypt_init( ) -> (1 - OK, <=0 - Error) EVP_PKEY_encrypt( , @, ) ; -> > 0 | <= 0 EVP_PKEY_decrypt_init( ) -> (1 - OK, <=0 - Error) EVP_PKEY_decrypt( , @, ) ; -> > 0 | <= 0 Above functions can be used with keys loaded by: PEM_READ_PRIVATEKEY() PEM_READ_PUBKEY() In OpenSSL 3.0 typed functions like *RSA*, *DSA*, *DH*, ... are depreciated and common for different methods EVP ones should be used instead. + added support for RSA encryption/decryption in above functions in OpenSSL libraries prior 1.0.0 which do not have EVP_PKEY_CTX. RSA support is emulated by direct calls to RSA_* functions so now for RSA it's possible to use new functions with old OpenSSL libraries. * contrib/hbssl/hbssl.ch + added constants for RSA padding: HB_RSA_*_PADDING + added constants for EVP PKEY types: HB_EVP_PKEY_* * contrib/hbssl/hbssl.hbx + added new functions --- ChangeLog.txt | 60 +++++++++ contrib/hbssl/evppkey.c | 276 ++++++++++++++++++++++++++++++++++++++-- contrib/hbssl/hbssl.ch | 32 +++++ contrib/hbssl/hbssl.h | 4 + contrib/hbssl/hbssl.hbm | 1 + contrib/hbssl/hbssl.hbx | 11 ++ contrib/hbssl/pem.c | 10 +- contrib/hbssl/rsa.c | 231 +++++++++++++++++++++++++++++++++ 8 files changed, 612 insertions(+), 13 deletions(-) create mode 100644 contrib/hbssl/rsa.c diff --git a/ChangeLog.txt b/ChangeLog.txt index 99237045fe..ad6a6d9165 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,66 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2023-11-22 09:06 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * contrib/hbssl/hbssl.hbm + * contrib/hbssl/hbssl.hbx + * contrib/hbssl/hbssl.h + + contrib/hbssl/rsa.c + + added PRG functions for RSA encryption/decryption: + RSA_size( ) -> + RSA_public_encrypt( , , @ ; + [, = HB_RSA_PKCS1_PADDING ] ) ; + -> > 0 | <= 0 + RSA_private_decrypt( , , @ ; + [, = HB_RSA_PKCS1_PADDING ] ) ; + -> > 0 | <= 0 + RSA_private_encrypt( , , @ ; + [, = HB_RSA_PKCS1_PADDING ] ) ; + -> > 0 | <= 0 + RSA_public_decrypt( , , @ ; + [, = HB_RSA_PKCS1_PADDING ] ) ; + -> > 0 | <= 0 + + added C functions for manipulating RSA keys inside HB_ITEMs: + HB_BOOL hb_RSA_is( int iParam ); + RSA * hb_RSA_par( int iParam ); + void hb_RSA_ret( RSA * rsa ); + + * contrib/hbssl/pem.c + + added support for RSA keys. + Now the following PRG functions return RSA key which can be passed to + RSA_* functions: + PEM_READ_BIO_RSAPRIVATEKEY() + PEM_READ_BIO_RSAPUBLICKEY() + PEM_READ_BIO_RSA_PUBKEY() + + * contrib/hbssl/evppkey.c + + added functions for EVP_PKEY encryption/decryption: + EVP_PKEY_base_id( ) -> + EVP_PKEY_CTX_new( ) -> + EVP_PKEY_encrypt_init( ) -> (1 - OK, <=0 - Error) + EVP_PKEY_encrypt( , @, ) ; + -> > 0 | <= 0 + EVP_PKEY_decrypt_init( ) -> (1 - OK, <=0 - Error) + EVP_PKEY_decrypt( , @, ) ; + -> > 0 | <= 0 + Above functions can be used with keys loaded by: + PEM_READ_PRIVATEKEY() + PEM_READ_PUBKEY() + In OpenSSL 3.0 typed functions like *RSA*, *DSA*, *DH*, ... are + depreciated and common for different methods EVP ones should be + used instead. + + added support for RSA encryption/decryption in above functions in + OpenSSL libraries prior 1.0.0 which do not have EVP_PKEY_CTX. RSA + support is emulated by direct calls to RSA_* functions so now for + RSA it's possible to use new functions with old OpenSSL libraries. + + * contrib/hbssl/hbssl.ch + + added constants for RSA padding: HB_RSA_*_PADDING + + added constants for EVP PKEY types: HB_EVP_PKEY_* + + * contrib/hbssl/hbssl.hbx + + added new functions + 2023-11-15 15:57 UTC+0100 Phil Krylov (phil a t krylov.eu) * contrib/hbsqlit3/tests/backup.prg + Simple change in test to provoke access to dangling pointer saved diff --git a/contrib/hbssl/evppkey.c b/contrib/hbssl/evppkey.c index d2c66066eb..6579c395cf 100644 --- a/contrib/hbssl/evppkey.c +++ b/contrib/hbssl/evppkey.c @@ -49,6 +49,7 @@ #include "hbapiitm.h" #include +#include static HB_GARBAGE_FUNC( EVP_PKEY_release ) { @@ -92,6 +93,52 @@ void hb_EVP_PKEY_ret( EVP_PKEY * pkey ) hb_retptrGC( ph ); } +static HB_GARBAGE_FUNC( EVP_PKEY_CTX_release ) +{ + void ** ph = ( void ** ) Cargo; + + /* Check if pointer is not NULL to avoid multiple freeing */ + if( ph && *ph ) + { +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY_CTX_free( ( EVP_PKEY_CTX * ) *ph ); +#endif + /* set pointer to NULL just in case */ + *ph = NULL; + } +} + +static const HB_GC_FUNCS s_gcEVP_PKEY_CTX_funcs = +{ + EVP_PKEY_CTX_release, + hb_gcDummyMark +}; + +#if 0 +static HB_BOOL hb_EVP_PKEY_CTX_is( int iParam ) +{ + return hb_parptrGC( &s_gcEVP_PKEY_CTX_funcs, iParam ) != NULL; +} +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +static EVP_PKEY_CTX * hb_EVP_PKEY_CTX_par( int iParam ) +{ + void ** ph = ( void ** ) hb_parptrGC( &s_gcEVP_PKEY_CTX_funcs, iParam ); + + return ph ? ( EVP_PKEY_CTX * ) *ph : NULL; +} + +static void hb_EVP_PKEY_CTX_ret( EVP_PKEY_CTX * pkey ) +{ + void ** ph = ( void ** ) hb_gcAllocate( sizeof( EVP_PKEY_CTX * ), &s_gcEVP_PKEY_CTX_funcs ); + + *ph = pkey; + + hb_retptrGC( ph ); +} +#endif + HB_FUNC( EVP_PKEY_NEW ) { hb_EVP_PKEY_ret( EVP_PKEY_new() ); @@ -102,6 +149,23 @@ HB_FUNC( EVP_PKEY_TYPE ) hb_retni( EVP_PKEY_type( hb_parni( 1 ) ) ); } +HB_FUNC( EVP_PKEY_BASE_ID ) +{ + if( hb_EVP_PKEY_is( 1 ) ) + { + EVP_PKEY * pkey = hb_EVP_PKEY_par( 1 ); + + if( pkey ) +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + hb_retni( EVP_PKEY_base_id( pkey ) ); +#else + hb_retni( EVP_PKEY_type( hb_parni( 1 ) ) ); +#endif + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + HB_FUNC( EVP_PKEY_SIZE ) { if( hb_EVP_PKEY_is( 1 ) ) @@ -196,6 +260,208 @@ HB_FUNC( EVP_PKEY_ASSIGN_DH ) #endif } +HB_FUNC( EVP_PKEY_CTX_NEW ) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY * pkey = hb_EVP_PKEY_par( 1 ); + + if( pkey ) + { + hb_EVP_PKEY_CTX_ret( EVP_PKEY_CTX_new( pkey, ( ENGINE * ) hb_parptr( 2 ) ) ); + } +#else + if( hb_RSA_is( 1 ) ) + { + hb_itemReturn( hb_param( 1, HB_IT_POINTER ) ); + } +#endif + else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( EVP_PKEY_ENCRYPT_INIT ) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY_CTX * ctx = hb_EVP_PKEY_CTX_par( 1 ); + + if( ctx ) + { + hb_retni( EVP_PKEY_encrypt_init( ctx ) ); + } +#else + if( hb_RSA_is( 1 ) ) + { + hb_retni( 1 ); + } +#endif + else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + #define HB_RSA_KEY_ISPRIVATE( rsa ) ( RSA_get0_d( rsa ) != NULL ) +#else + #define HB_RSA_KEY_ISPRIVATE( rsa ) ( ( rsa )->d != NULL ) +#endif + + +HB_FUNC( EVP_PKEY_ENCRYPT ) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY_CTX * ctx = hb_EVP_PKEY_CTX_par( 1 ); + + if( ctx ) + { + const unsigned char * in = ( const unsigned char * ) hb_parcx( 3 ); + size_t inlen = ( size_t ) hb_parclen( 3 ), outlen = 0; + unsigned char * buffer = NULL; + int ret; + + ret = EVP_PKEY_encrypt( ctx, NULL, &outlen, in, inlen ); + if( ret > 0 ) + { + buffer = ( unsigned char * ) hb_xgrab( outlen + 1 ); + + ret = EVP_PKEY_encrypt( ctx, buffer, &outlen, in, inlen ); + if( ret > 0 ) + { + if( ! hb_storclen_buffer( ( char * ) buffer, outlen, 2 ) ) + ret = 0; + } + } + if( ret <= 0 ) + { + if( buffer ) + hb_xfree( buffer ); + hb_storc( NULL, 2 ); + } + hb_retni( ret ); + } +#else + if( hb_RSA_is( 1 ) ) + { + RSA * rsa = hb_RSA_par( 1 ); + const unsigned char * from = ( const unsigned char * ) hb_parcx( 3 ); + int flen = ( int ) hb_parclen( 3 ); + unsigned char * buffer; + int ret; + + buffer = ( unsigned char * ) hb_xgrab( RSA_size( rsa ) + 1 ); + + if( HB_RSA_KEY_ISPRIVATE( rsa ) ) + /* private key */ + ret = RSA_private_encrypt( flen, HB_UNCONST( from ), buffer, rsa, RSA_PKCS1_PADDING ); + else + /* public key */ + ret = RSA_public_encrypt( flen, HB_UNCONST( from ), buffer, rsa, RSA_PKCS1_PADDING ); + + if( ret > 0 ) + { + if( ! hb_storclen_buffer( ( char * ) buffer, ret, 2 ) ) + ret = 0; + } + if( ret <= 0 ) + { + if( buffer ) + hb_xfree( buffer ); + hb_storc( NULL, 2 ); + } + hb_retni( ret ); + } +#endif + else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( EVP_PKEY_DECRYPT_INIT ) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY_CTX * ctx = hb_EVP_PKEY_CTX_par( 1 ); + + if( ctx ) + { + hb_retni( EVP_PKEY_decrypt_init( ctx ) ); + } +#else + if( hb_RSA_is( 1 ) ) + { + hb_retni( 1 ); + } +#endif + else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( EVP_PKEY_DECRYPT ) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY_CTX * ctx = hb_EVP_PKEY_CTX_par( 1 ); + + if( ctx ) + { + const unsigned char * in = ( const unsigned char * ) hb_parcx( 3 ); + size_t inlen = ( size_t ) hb_parclen( 3 ), outlen = 0; + unsigned char * buffer = NULL; + int ret; + + ret = EVP_PKEY_decrypt( ctx, NULL, &outlen, in, inlen ); + if( ret > 0 ) + { + buffer = ( unsigned char * ) hb_xgrab( outlen + 1 ); + + ret = EVP_PKEY_decrypt( ctx, buffer, &outlen, in, inlen ); + if( ret > 0 ) + { + if( ! hb_storclen_buffer( ( char * ) buffer, outlen, 2 ) ) + ret = 0; + } + } + if( ret <= 0 ) + { + if( buffer ) + hb_xfree( buffer ); + hb_storc( NULL, 2 ); + } + hb_retni( ret ); + } +#else + if( hb_RSA_is( 1 ) ) + { + RSA * rsa = hb_RSA_par( 1 ); + const unsigned char * from = ( const unsigned char * ) hb_parcx( 3 ); + int flen = ( int ) hb_parclen( 3 ); + unsigned char * buffer; + int ret; + + buffer = ( unsigned char * ) hb_xgrab( RSA_size( rsa ) + 1 ); + + if( HB_RSA_KEY_ISPRIVATE( rsa ) ) + /* private key */ + ret = RSA_private_decrypt( flen, HB_UNCONST( from ), buffer, rsa, RSA_PKCS1_PADDING ); + else + /* public key */ + ret = RSA_public_decrypt( flen, HB_UNCONST( from ), buffer, rsa, RSA_PKCS1_PADDING ); + + if( ret > 0 ) + { + buffer = ( unsigned char * ) hb_xrealloc( buffer, ret + 1 ); + if( ! hb_storclen_buffer( ( char * ) buffer, ret, 2 ) ) + ret = 0; + } + if( ret <= 0 ) + { + if( buffer ) + hb_xfree( buffer ); + hb_storc( NULL, 2 ); + } + hb_retni( ret ); + } +#endif + else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + + #if 0 int EVP_PKEY_set1_RSA( EVP_PKEY * pkey, RSA * key ); @@ -228,14 +494,4 @@ int EVP_PKEY_verify_recover( EVP_PKEY_CTX * ctx, unsigned char * rout, size_t * routlen, const unsigned char * sig, size_t siglen ); -int EVP_PKEY_encrypt_init( EVP_PKEY_CTX * ctx ); -int EVP_PKEY_encrypt( EVP_PKEY_CTX * ctx, - unsigned char * out, size_t * outlen, - const unsigned char * in, size_t inlen ); - -int EVP_PKEY_decrypt_init( EVP_PKEY_CTX * ctx ); -int EVP_PKEY_decrypt( EVP_PKEY_CTX * ctx, - unsigned char * out, size_t * outlen, - const unsigned char * in, size_t inlen ); - #endif diff --git a/contrib/hbssl/hbssl.ch b/contrib/hbssl/hbssl.ch index 25c5f6480a..5abe473f28 100644 --- a/contrib/hbssl/hbssl.ch +++ b/contrib/hbssl/hbssl.ch @@ -181,6 +181,13 @@ #define HB_X509_V_ERR_UNNESTED_RESOURCE 44 #define HB_X509_V_ERR_APPLICATION_VERIFICATION 50 +#define HB_RSA_PKCS1_PADDING 1 +#define HB_RSA_SSLV23_PADDING 2 +#define HB_RSA_NO_PADDING 3 +#define HB_RSA_PKCS1_OAEP_PADDING 4 +#define HB_RSA_X931_PADDING 5 +#define HB_RSA_PKCS1_PSS_PADDING 6 + #define HB_EVP_MD_UNSUPPORTED ( -1 ) #define HB_EVP_MD_MD_NULL 0 #define HB_EVP_MD_MD2 1 @@ -302,6 +309,31 @@ #define HB_EVP_CIPHER_SEED_CFB 97 #define HB_EVP_CIPHER_SEED_OFB 98 +#define HB_EVP_PKEY_NONE 0 +#define HB_EVP_PKEY_RSA 6 +#define HB_EVP_PKEY_RSA2 19 +#define HB_EVP_PKEY_RSA_PSS 912 +#define HB_EVP_PKEY_DSA 116 +#define HB_EVP_PKEY_DSA1 67 +#define HB_EVP_PKEY_DSA2 66 +#define HB_EVP_PKEY_DSA3 113 +#define HB_EVP_PKEY_DSA4 70 +#define HB_EVP_PKEY_DH 28 +#define HB_EVP_PKEY_DHX 920 +#define HB_EVP_PKEY_EC 408 +#define HB_EVP_PKEY_SM2 1172 +#define HB_EVP_PKEY_HMAC 855 +#define HB_EVP_PKEY_CMAC 894 +#define HB_EVP_PKEY_SCRYPT 973 +#define HB_EVP_PKEY_TLS1_PRF 1021 +#define HB_EVP_PKEY_HKDF 1036 +#define HB_EVP_PKEY_POLY1305 1061 +#define HB_EVP_PKEY_SIPHASH 1062 +#define HB_EVP_PKEY_X25519 1034 +#define HB_EVP_PKEY_ED25519 1087 +#define HB_EVP_PKEY_X448 1035 +#define HB_EVP_PKEY_ED448 1088 + #define HB_BIO_METHOD_UNSUPPORTED ( -1 ) #define HB_BIO_METHOD_S_NULL 0 #define HB_BIO_METHOD_S_FILE 1 diff --git a/contrib/hbssl/hbssl.h b/contrib/hbssl/hbssl.h index ae9b32cc37..1ea030dd7f 100644 --- a/contrib/hbssl/hbssl.h +++ b/contrib/hbssl/hbssl.h @@ -210,6 +210,10 @@ 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 HB_BOOL hb_RSA_is( int iParam ); +extern RSA * hb_RSA_par( int iParam ); +extern void hb_RSA_ret( RSA * rsa ); + extern HB_BOOL hb_EVP_MD_is( int iParam ); extern const EVP_MD * hb_EVP_MD_par( int iParam ); diff --git a/contrib/hbssl/hbssl.hbm b/contrib/hbssl/hbssl.hbm index ef4c79955e..4149eb7449 100644 --- a/contrib/hbssl/hbssl.hbm +++ b/contrib/hbssl/hbssl.hbm @@ -54,6 +54,7 @@ evpmd.c evppkey.c pem.c rand.c +rsa.c ssl.c sslciph.c sslctx.c diff --git a/contrib/hbssl/hbssl.hbx b/contrib/hbssl/hbssl.hbx index eac9189247..e4803fccc4 100644 --- a/contrib/hbssl/hbssl.hbx +++ b/contrib/hbssl/hbssl.hbx @@ -159,7 +159,13 @@ DYNAMIC EVP_PKEY_assign DYNAMIC EVP_PKEY_assign_DH DYNAMIC EVP_PKEY_assign_DSA DYNAMIC EVP_PKEY_assign_RSA +DYNAMIC EVP_PKEY_base_id DYNAMIC EVP_PKEY_bits +DYNAMIC EVP_PKEY_CTX_new +DYNAMIC EVP_PKEY_decrypt +DYNAMIC EVP_PKEY_decrypt_init +DYNAMIC EVP_PKEY_encrypt +DYNAMIC EVP_PKEY_encrypt_init DYNAMIC EVP_PKEY_free DYNAMIC EVP_PKEY_new DYNAMIC EVP_PKEY_size @@ -218,6 +224,11 @@ DYNAMIC RAND_poll DYNAMIC RAND_screen DYNAMIC RAND_seed DYNAMIC RAND_status +DYNAMIC RSA_private_decrypt +DYNAMIC RSA_private_encrypt +DYNAMIC RSA_public_decrypt +DYNAMIC RSA_public_encrypt +DYNAMIC RSA_size DYNAMIC SSLeay DYNAMIC SSLEAY_VERSION DYNAMIC SSL_accept diff --git a/contrib/hbssl/pem.c b/contrib/hbssl/pem.c index 7aee1991fa..685ffb2248 100644 --- a/contrib/hbssl/pem.c +++ b/contrib/hbssl/pem.c @@ -54,6 +54,7 @@ typedef enum { hb_PEM_X509, hb_PEM_EVP_PKEY, + hb_PEM_RSA, hb_PEM_ANY } HB_PEM_TYPES; @@ -138,6 +139,9 @@ static void hb_PEM_read_bio( PEM_READ_BIO * func, HB_PEM_TYPES type ) case hb_PEM_EVP_PKEY: hb_EVP_PKEY_ret( ( EVP_PKEY * ) result ); break; + case hb_PEM_RSA: + hb_RSA_ret( ( RSA * ) result ); + break; case hb_PEM_ANY: hb_retptr( NULL ); break; @@ -155,9 +159,6 @@ static void hb_PEM_read_bio( PEM_READ_BIO * func, HB_PEM_TYPES type ) HB_FUNC( PEM_READ_BIO_PRIVATEKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_PrivateKey , hb_PEM_ANY ); } HB_FUNC( PEM_READ_BIO_PUBKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_PUBKEY , hb_PEM_ANY ); } -HB_FUNC( PEM_READ_BIO_RSAPRIVATEKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_RSAPrivateKey, hb_PEM_ANY ); } -HB_FUNC( PEM_READ_BIO_RSAPUBLICKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_RSAPublicKey , hb_PEM_ANY ); } -HB_FUNC( PEM_READ_BIO_RSA_PUBKEY ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_read_bio_RSA_PUBKEY , hb_PEM_ANY ); } 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 ); } @@ -168,6 +169,9 @@ HB_FUNC( PEM_READ_BIO_X509_REQ ) { hb_PEM_read_bio( ( PEM_READ_BIO * ) PEM_ 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 new file mode 100644 index 0000000000..039c9e5636 --- /dev/null +++ b/contrib/hbssl/rsa.c @@ -0,0 +1,231 @@ +/* + * OpenSSL API (RSA) - Harbour interface. + * + * Copyright 2016 Przemyslaw Czerpak + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file LICENSE.txt. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#include "hbssl.h" + +#include + +static HB_GARBAGE_FUNC( s_RSA_release ) +{ + void ** ph = ( void ** ) Cargo; + + /* Check if pointer is not NULL to avoid multiple freeing */ + if( ph && *ph ) + { + /* Destroy the object */ + RSA_free( ( RSA * ) *ph ); + + /* set pointer to NULL just in case */ + *ph = NULL; + } +} + +static const HB_GC_FUNCS s_gcRSA_funcs = +{ + s_RSA_release, + hb_gcDummyMark +}; + +HB_BOOL hb_RSA_is( int iParam ) +{ + return hb_parptrGC( &s_gcRSA_funcs, iParam ) != NULL; +} + +RSA * hb_RSA_par( int iParam ) +{ + void ** ph = ( void ** ) hb_parptrGC( &s_gcRSA_funcs, iParam ); + + return ph ? ( RSA * ) *ph : NULL; +} + +void hb_RSA_ret( RSA * rsa ) +{ + void ** ph = ( void ** ) hb_gcAllocate( sizeof( RSA * ), &s_gcRSA_funcs ); + + *ph = rsa; + + hb_retptrGC( ph ); +} + +HB_FUNC( RSA_SIZE ) +{ + RSA * rsa = hb_RSA_par( 1 ); + + if( rsa ) + hb_retni( RSA_size( rsa ) ); + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( RSA_PUBLIC_ENCRYPT ) +{ + RSA * rsa = hb_RSA_par( 1 ); + + if( rsa ) + { + const unsigned char * from = ( const unsigned char * ) hb_parcx( 2 ); + int flen = ( int ) hb_parclen( 2 ), + padding = hb_parnidef( 4, RSA_PKCS1_PADDING ); + unsigned char * buffer; + int ret; + + buffer = ( unsigned char * ) hb_xgrab( RSA_size( rsa ) + 1 ); + + ret = RSA_public_encrypt( flen, HB_UNCONST( from ), buffer, rsa, padding ); + if( ret > 0 ) + { + if( ! hb_storclen_buffer( ( char * ) buffer, ret, 3 ) ) + ret = 0; + } + if( ret <= 0 ) + { + if( buffer ) + hb_xfree( buffer ); + hb_storc( NULL, 3 ); + } + hb_retni( ret ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( RSA_PRIVATE_DECRYPT ) +{ + RSA * rsa = hb_RSA_par( 1 ); + + if( rsa ) + { + const unsigned char * from = ( const unsigned char * ) hb_parcx( 2 ); + int flen = ( int ) hb_parclen( 2 ), + padding = hb_parnidef( 4, RSA_PKCS1_PADDING ); + unsigned char * buffer; + int ret; + + buffer = ( unsigned char * ) hb_xgrab( RSA_size( rsa ) + 1 ); + + ret = RSA_private_decrypt( flen, HB_UNCONST( from ), buffer, rsa, padding ); + if( ret > 0 ) + { + buffer = ( unsigned char * ) hb_xrealloc( buffer, ret + 1 ); + if( ! hb_storclen_buffer( ( char * ) buffer, ret, 3 ) ) + ret = 0; + } + if( ret <= 0 ) + { + if( buffer ) + hb_xfree( buffer ); + hb_storc( NULL, 3 ); + } + hb_retni( ret ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( RSA_PRIVATE_ENCRYPT ) +{ + RSA * rsa = hb_RSA_par( 1 ); + + if( rsa ) + { + const unsigned char * from = ( const unsigned char * ) hb_parcx( 2 ); + int flen = ( int ) hb_parclen( 2 ), + padding = hb_parnidef( 4, RSA_PKCS1_PADDING ); + unsigned char * buffer; + int ret; + + buffer = ( unsigned char * ) hb_xgrab( RSA_size( rsa ) + 1 ); + + ret = RSA_private_encrypt( flen, HB_UNCONST( from ), buffer, rsa, padding ); + if( ret > 0 ) + { + if( ! hb_storclen_buffer( ( char * ) buffer, ret, 3 ) ) + ret = 0; + } + if( ret <= 0 ) + { + if( buffer ) + hb_xfree( buffer ); + hb_storc( NULL, 3 ); + } + hb_retni( ret ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( RSA_PUBLIC_DECRYPT ) +{ + RSA * rsa = hb_RSA_par( 1 ); + + if( rsa ) + { + const unsigned char * from = ( const unsigned char * ) hb_parcx( 2 ); + int flen = ( int ) hb_parclen( 2 ), + padding = hb_parnidef( 4, RSA_PKCS1_PADDING ); + unsigned char * buffer; + int ret; + + buffer = ( unsigned char * ) hb_xgrab( RSA_size( rsa ) + 1 ); + + ret = RSA_public_decrypt( flen, HB_UNCONST( from ), buffer, rsa, padding ); + if( ret > 0 ) + { + buffer = ( unsigned char * ) hb_xrealloc( buffer, ret + 1 ); + if( ! hb_storclen_buffer( ( char * ) buffer, ret, 3 ) ) + ret = 0; + } + if( ret <= 0 ) + { + if( buffer ) + hb_xfree( buffer ); + hb_storc( NULL, 3 ); + } + hb_retni( ret ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +}