From: Santino Mazza mazzasantino1206@gmail.com
Signed-off-by: Santino Mazza mazzasantino1206@gmail.com --- dlls/bcrypt/bcrypt_internal.h | 11 +++++++++++ dlls/bcrypt/bcrypt_main.c | 33 ++++++++++++++++++++++++--------- dlls/bcrypt/gnutls.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 9 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h index d57819f2ec6..02461336a57 100644 --- a/dlls/bcrypt/bcrypt_internal.h +++ b/dlls/bcrypt/bcrypt_internal.h @@ -237,6 +237,16 @@ struct key_asymmetric_decrypt_params ULONG *ret_len; };
+struct key_asymmetric_encrypt_params +{ + struct key *key; + UCHAR *input; + unsigned input_len; + UCHAR *output; + ULONG output_len; + ULONG *ret_len; +}; + struct key_asymmetric_duplicate_params { struct key *key_orig; @@ -298,6 +308,7 @@ enum key_funcs unix_key_symmetric_destroy, unix_key_asymmetric_generate, unix_key_asymmetric_decrypt, + unix_key_asymmetric_encrypt, unix_key_asymmetric_duplicate, unix_key_asymmetric_sign, unix_key_asymmetric_verify, diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 2c0d2f8f965..0869fe810a3 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -1880,26 +1880,41 @@ NTSTATUS WINAPI BCryptEncrypt( BCRYPT_KEY_HANDLE handle, UCHAR *input, ULONG inp ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags ) { struct key *key = handle; + struct key_asymmetric_encrypt_params asymmetric_params; NTSTATUS ret;
TRACE( "%p, %p, %lu, %p, %p, %lu, %p, %lu, %p, %#lx\n", handle, input, input_len, padding, iv, iv_len, output, output_len, ret_len, flags );
if (!key || key->hdr.magic != MAGIC_KEY) return STATUS_INVALID_HANDLE; - if (!key_is_symmetric( key )) + + if (key_is_symmetric( key )) { - FIXME( "encryption with asymmetric keys not yet supported\n" ); - return STATUS_NOT_IMPLEMENTED; + if (flags & ~BCRYPT_BLOCK_PADDING) + { + FIXME( "flags %#lx not implemented\n", flags ); + return STATUS_NOT_IMPLEMENTED; + } + EnterCriticalSection( &key->u.s.cs ); + ret = key_symmetric_encrypt( key, input, input_len, padding, iv, iv_len, output, output_len, ret_len, flags ); + LeaveCriticalSection( &key->u.s.cs ); } - if (flags & ~BCRYPT_BLOCK_PADDING) + else { - FIXME( "flags %#lx not implemented\n", flags ); - return STATUS_NOT_IMPLEMENTED; + if (flags & BCRYPT_PAD_NONE || flags & BCRYPT_PAD_OAEP) + { + FIXME( "flags %#lx not implemented\n", flags ); + return STATUS_NOT_IMPLEMENTED; + } + asymmetric_params.input = input; + asymmetric_params.input_len = input_len; + asymmetric_params.key = key; + asymmetric_params.output = output; + asymmetric_params.output_len = output_len; + asymmetric_params.ret_len = ret_len; + ret = UNIX_CALL(key_asymmetric_encrypt, &asymmetric_params); }
- EnterCriticalSection( &key->u.s.cs ); - ret = key_symmetric_encrypt( key, input, input_len, padding, iv, iv_len, output, output_len, ret_len, flags ); - LeaveCriticalSection( &key->u.s.cs ); return ret; }
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index b38bf4ba8ff..7d85eab0eeb 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -122,6 +122,7 @@ static int (*pgnutls_privkey_import_rsa_raw)(gnutls_privkey_t, const gnutls_datu const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *); static int (*pgnutls_privkey_decrypt_data)(gnutls_privkey_t, unsigned int flags, const gnutls_datum_t *, gnutls_datum_t *); +static int (*pgnutls_pubkey_encrypt_data)(gnutls_pubkey_t , unsigned int flags, const gnutls_datum_t *, gnutls_datum_t *);
/* Not present in gnutls version < 3.6.0 */ static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *); @@ -138,6 +139,7 @@ MAKE_FUNCPTR(gnutls_global_set_log_function); MAKE_FUNCPTR(gnutls_global_set_log_level); MAKE_FUNCPTR(gnutls_perror); MAKE_FUNCPTR(gnutls_privkey_decrypt_data); +MAKE_FUNCPTR(gnutls_pubkey_encrypt_data); MAKE_FUNCPTR(gnutls_privkey_deinit); MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw); MAKE_FUNCPTR(gnutls_privkey_init); @@ -253,6 +255,12 @@ static int compat_gnutls_privkey_decrypt_data(gnutls_privkey_t key, unsigned int return GNUTLS_E_UNKNOWN_PK_ALGORITHM; }
+static int compat_gnutls_pubkey_encrypt_data(gnutls_privkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text, + gnutls_datum_t *plain_text) +{ + return GNUTLS_E_UNKNOWN_PK_ALGORITHM; +} + static void gnutls_log( int level, const char *msg ) { TRACE( "<%d> %s", level, msg ); @@ -329,6 +337,7 @@ static NTSTATUS gnutls_process_attach( void *args ) LOAD_FUNCPTR_OPT(gnutls_decode_rs_value) LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw) LOAD_FUNCPTR_OPT(gnutls_privkey_decrypt_data) + LOAD_FUNCPTR_OPT(gnutls_pubkey_encrypt_data) #undef LOAD_FUNCPTR_OPT
if ((ret = pgnutls_global_init()) != GNUTLS_E_SUCCESS) @@ -1927,6 +1936,30 @@ static NTSTATUS key_asymmetric_decrypt( void *args ) return status; }
+static NTSTATUS key_asymmetric_encrypt( void *args ) +{ + const struct key_asymmetric_encrypt_params *params = args; + gnutls_datum_t d, e = { 0 }; + NTSTATUS status = STATUS_SUCCESS; + int ret; + + d.data = params->input; + d.size = params->input_len; + if ((ret = pgnutls_pubkey_encrypt_data(key_data(params->key)->a.pubkey, 0, &d, &e))) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + + *params->ret_len = e.size; + if (params->output_len >= e.size) memcpy( params->output, e.data, *params->ret_len ); + else if (params->output_len == 0) status = STATUS_SUCCESS; + else status = STATUS_BUFFER_TOO_SMALL; + + free( e.data ); + return status; +} + const unixlib_entry_t __wine_unix_call_funcs[] = { gnutls_process_attach, @@ -1939,6 +1972,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = key_symmetric_destroy, key_asymmetric_generate, key_asymmetric_decrypt, + key_asymmetric_encrypt, key_asymmetric_duplicate, key_asymmetric_sign, key_asymmetric_verify,