Module: wine Branch: master Commit: 3bfccbc7e42c1edb54618ef29fa879e2fad36ed7 URL: https://gitlab.winehq.org/wine/wine/-/commit/3bfccbc7e42c1edb54618ef29fa879e...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Dec 6 20:23:53 2023 +0100
bcrypt: Add support for retrieving DH parameters.
---
dlls/bcrypt/bcrypt_internal.h | 6 ++++-- dlls/bcrypt/bcrypt_main.c | 17 +++++++++++++++++ dlls/bcrypt/gnutls.c | 41 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 59 insertions(+), 5 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h index a31d170c621..a5dbeff4e8e 100644 --- a/dlls/bcrypt/bcrypt_internal.h +++ b/dlls/bcrypt/bcrypt_internal.h @@ -283,8 +283,10 @@ struct key_asymmetric_verify_params unsigned flags; };
-#define KEY_EXPORT_FLAG_PUBLIC 0x00000001 -#define KEY_EXPORT_FLAG_RSA_FULL 0x00000002 +#define KEY_EXPORT_FLAG_PUBLIC 0x00000001 +#define KEY_EXPORT_FLAG_RSA_FULL 0x00000002 +#define KEY_EXPORT_FLAG_DH_PARAMETERS 0x00000004 + struct key_asymmetric_export_params { struct key *key; diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index f58ddaf13aa..cce824ff602 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -917,6 +917,20 @@ static NTSTATUS get_hash_property( const struct hash *hash, const WCHAR *prop, U return status; }
+static NTSTATUS get_dh_property( const struct key *key, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) +{ + struct key_asymmetric_export_params params; + + if (wcscmp( prop, BCRYPT_DH_PARAMETERS )) return STATUS_NOT_SUPPORTED; + + params.key = (struct key *)key; + params.flags = KEY_EXPORT_FLAG_DH_PARAMETERS; + params.buf = buf; + params.len = size; + params.ret_len = ret_size; + return UNIX_CALL( key_asymmetric_export, ¶ms ); +} + static NTSTATUS get_key_property( const struct key *key, const WCHAR *prop, UCHAR *buf, ULONG size, ULONG *ret_size ) { if (!wcscmp( prop, BCRYPT_KEY_STRENGTH )) @@ -940,6 +954,9 @@ static NTSTATUS get_key_property( const struct key *key, const WCHAR *prop, UCHA if (!wcscmp( prop, BCRYPT_AUTH_TAG_LENGTH )) return STATUS_NOT_SUPPORTED; return get_aes_property( key->u.s.mode, prop, buf, size, ret_size );
+ case ALG_ID_DH: + return get_dh_property( key, prop, buf, size, ret_size ); + default: FIXME( "unsupported algorithm %u\n", key->alg_id ); return STATUS_NOT_IMPLEMENTED; diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index 0d912e7a2d7..4183aad6cec 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -1651,8 +1651,7 @@ static NTSTATUS key_export_dh( struct key *key, UCHAR *buf, ULONG len, ULONG *re return STATUS_INTERNAL_ERROR; }
- ret = pgnutls_privkey_export_dh_raw( key_data(key)->a.privkey, params, &y, &x, 0 ); - if (ret) + if ((ret = pgnutls_privkey_export_dh_raw( key_data(key)->a.privkey, params, &y, &x, 0 ))) { pgnutls_perror( ret ); pgnutls_dh_params_deinit( params ); @@ -1686,6 +1685,40 @@ static NTSTATUS key_export_dh( struct key *key, UCHAR *buf, ULONG len, ULONG *re return STATUS_SUCCESS; }
+static NTSTATUS key_export_dh_params( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len ) +{ + BCRYPT_DH_PARAMETER_HEADER *hdr = (BCRYPT_DH_PARAMETER_HEADER *)buf; + unsigned int size = sizeof(*hdr) + key->u.a.bitlen / 8 * 2; + gnutls_datum_t p, g; + NTSTATUS status = STATUS_SUCCESS; + UCHAR *dst; + int ret; + + if (!key_data(key)->a.dh_params) return STATUS_INVALID_PARAMETER; + + if ((ret = pgnutls_dh_params_export_raw( key_data(key)->a.dh_params, &p, &g, NULL ))) + { + pgnutls_perror( ret ); + return STATUS_INTERNAL_ERROR; + } + + *ret_len = size; + if (len < size) status = STATUS_BUFFER_TOO_SMALL; + else if (buf) + { + hdr->cbLength = size; + hdr->dwMagic = BCRYPT_DH_PARAMETERS_MAGIC; + hdr->cbKeyLength = key->u.a.bitlen / 8; + + dst = (UCHAR *)(hdr + 1); + dst += export_gnutls_datum( dst, hdr->cbKeyLength, &p, 1 ); + dst += export_gnutls_datum( dst, hdr->cbKeyLength, &g, 1 ); + } + + free( p.data ); free( g.data ); + return status; +} + static NTSTATUS key_asymmetric_export( void *args ) { const struct key_asymmetric_export_params *params = args; @@ -1720,7 +1753,9 @@ static NTSTATUS key_asymmetric_export( void *args ) return STATUS_NOT_IMPLEMENTED;
case ALG_ID_DH: - if (flags & KEY_EXPORT_FLAG_PUBLIC) + if (flags & KEY_EXPORT_FLAG_DH_PARAMETERS) + return key_export_dh_params( key, params->buf, params->len, params->ret_len ); + if (flags & KEY_EXPORT_FLAG_PUBLIC) return key_export_dh_public( key, params->buf, params->len, params->ret_len ); return key_export_dh( key, params->buf, params->len, params->ret_len );