Module: wine Branch: master Commit: cfa655c4a32ac2e2d43aaebef4f3127621a92f78 URL: https://gitlab.winehq.org/wine/wine/-/commit/cfa655c4a32ac2e2d43aaebef4f3127...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Nov 29 09:29:18 2023 +0100
bcrypt: Implement BCryptSecretAgreement() and BCryptDestroySecret().
This series depends on secret agreement APIs added in GnuTLS 3.8.2.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49543
---
dlls/bcrypt/bcrypt_internal.h | 6 ++-- dlls/bcrypt/bcrypt_main.c | 65 ++++++++++++++++++++++++++----------------- 2 files changed, 43 insertions(+), 28 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h index 10b1cc12e8c..505435c6ac2 100644 --- a/dlls/bcrypt/bcrypt_internal.h +++ b/dlls/bcrypt/bcrypt_internal.h @@ -197,6 +197,8 @@ struct key struct secret { struct object hdr; + struct key *privkey; + struct key *pubkey; };
struct key_symmetric_set_auth_data_params @@ -253,8 +255,8 @@ struct key_asymmetric_encrypt_params
struct key_asymmetric_duplicate_params { - struct key *key_orig; - struct key *key_copy; + struct key *key_orig; + struct key *key_copy; };
struct key_asymmetric_sign_params diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index ebfcbfb7049..b76a36482de 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -1996,18 +1996,24 @@ NTSTATUS WINAPI BCryptExportKey( BCRYPT_KEY_HANDLE export_key_handle, BCRYPT_KEY return key_export( key, type, output, output_len, size ); }
-static NTSTATUS key_duplicate( struct key *key_orig, struct key *key_copy ) +static NTSTATUS key_duplicate( struct key *key_orig, struct key **ret_key ) { - UCHAR *buffer; + struct key_asymmetric_duplicate_params params; + struct key *key_copy; NTSTATUS status; + UCHAR *buffer;
- memset( key_copy, 0, sizeof(*key_copy) ); + if (!(key_copy = calloc( 1, sizeof(*key_copy) ))) return STATUS_NO_MEMORY; key_copy->hdr = key_orig->hdr; key_copy->alg_id = key_orig->alg_id;
if (is_symmetric_key( key_orig )) { - if (!(buffer = malloc( key_orig->u.s.secret_len ))) return STATUS_NO_MEMORY; + if (!(buffer = malloc( key_orig->u.s.secret_len ))) + { + free( key_copy ); + return STATUS_NO_MEMORY; + } memcpy( buffer, key_orig->u.s.secret, key_orig->u.s.secret_len );
key_copy->u.s.mode = key_orig->u.s.mode; @@ -2015,25 +2021,23 @@ static NTSTATUS key_duplicate( struct key *key_orig, struct key *key_copy ) key_copy->u.s.secret = buffer; key_copy->u.s.secret_len = key_orig->u.s.secret_len; InitializeCriticalSection( &key_copy->u.s.cs ); + *ret_key = key_copy; + return STATUS_SUCCESS; } - else - { - struct key_asymmetric_duplicate_params params; - - key_copy->u.a.bitlen = key_orig->u.a.bitlen; - key_copy->u.a.flags = key_orig->u.a.flags; - key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
- params.key_orig = key_orig; - params.key_copy = key_copy; - if ((status = UNIX_CALL( key_asymmetric_duplicate, ¶ms ))) return status; - } + key_copy->u.a.bitlen = key_orig->u.a.bitlen; + key_copy->u.a.flags = key_orig->u.a.flags; + key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
- return STATUS_SUCCESS; + params.key_orig = key_orig; + params.key_copy = key_copy; + if (!(status = UNIX_CALL( key_asymmetric_duplicate, ¶ms ))) *ret_key = key_copy; + else free( key_copy ); + return status; }
-NTSTATUS WINAPI BCryptDuplicateKey( BCRYPT_KEY_HANDLE handle, BCRYPT_KEY_HANDLE *handle_copy, - UCHAR *object, ULONG object_len, ULONG flags ) +NTSTATUS WINAPI BCryptDuplicateKey( BCRYPT_KEY_HANDLE handle, BCRYPT_KEY_HANDLE *handle_copy, UCHAR *object, + ULONG object_len, ULONG flags ) { struct key *key_orig = get_key_object( handle ); struct key *key_copy; @@ -2044,13 +2048,8 @@ NTSTATUS WINAPI BCryptDuplicateKey( BCRYPT_KEY_HANDLE handle, BCRYPT_KEY_HANDLE
if (!key_orig) return STATUS_INVALID_HANDLE; if (!handle_copy) return STATUS_INVALID_PARAMETER; - if (!(key_copy = malloc( sizeof(*key_copy) ))) return STATUS_NO_MEMORY;
- if ((status = key_duplicate( key_orig, key_copy ))) - { - key_destroy( key_copy ); - return status; - } + if ((status = key_duplicate( key_orig, &key_copy ))) return status;
*handle_copy = key_copy; return STATUS_SUCCESS; @@ -2433,8 +2432,9 @@ NTSTATUS WINAPI BCryptSecretAgreement( BCRYPT_KEY_HANDLE privkey_handle, BCRYPT_ struct key *privkey = get_key_object( privkey_handle ); struct key *pubkey = get_key_object( pubkey_handle ); struct secret *secret; + NTSTATUS status;
- FIXME( "%p, %p, %p, %#lx\n", privkey_handle, pubkey_handle, ret_handle, flags ); + TRACE( "%p, %p, %p, %#lx\n", privkey_handle, pubkey_handle, ret_handle, flags );
if (!privkey || !pubkey) return STATUS_INVALID_HANDLE; if (!is_agreement_key( privkey ) || !is_agreement_key( pubkey )) return STATUS_NOT_SUPPORTED; @@ -2442,6 +2442,17 @@ NTSTATUS WINAPI BCryptSecretAgreement( BCRYPT_KEY_HANDLE privkey_handle, BCRYPT_
if (!(secret = calloc( 1, sizeof(*secret) ))) return STATUS_NO_MEMORY; secret->hdr.magic = MAGIC_SECRET; + if ((status = key_duplicate( privkey, &secret->privkey ))) + { + free( secret ); + return status; + } + if ((status = key_duplicate( pubkey, &secret->pubkey ))) + { + key_destroy( secret->privkey ); + free( secret ); + return status; + }
*ret_handle = secret; return STATUS_SUCCESS; @@ -2451,9 +2462,11 @@ NTSTATUS WINAPI BCryptDestroySecret( BCRYPT_SECRET_HANDLE handle ) { struct secret *secret = get_secret_object( handle );
- FIXME( "%p\n", handle ); + TRACE( "%p\n", handle );
if (!secret) return STATUS_INVALID_HANDLE; + key_destroy( secret->privkey ); + key_destroy( secret->pubkey ); destroy_object( &secret->hdr ); return STATUS_SUCCESS; }