From 0c2408464cfea0d3e5b073c56ac0d264d1abe576 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Mon, 21 Mar 2022 09:50:09 +0100 Subject: [PATCH] bcrypt: Merge the various key import Unix calls into one. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/bcrypt/bcrypt_internal.h | 8 +-- dlls/bcrypt/bcrypt_main.c | 87 ++++++++++++++++------ dlls/bcrypt/gnutls.c | 132 ++++++++++++++++------------------ 3 files changed, 132 insertions(+), 95 deletions(-) diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h index d299def6e11..7342b66479a 100644 --- a/dlls/bcrypt/bcrypt_internal.h +++ b/dlls/bcrypt/bcrypt_internal.h @@ -279,9 +279,11 @@ struct key_asymmetric_export_params ULONG *ret_len; }; -struct key_import_params +#define KEY_IMPORT_FLAG_PUBLIC 0x00000001 +struct key_asymmetric_import_params { struct key *key; + ULONG flags; UCHAR *buf; ULONG len; }; @@ -303,9 +305,7 @@ enum key_funcs unix_key_asymmetric_verify, unix_key_asymmetric_destroy, unix_key_asymmetric_export, - unix_key_import_dsa_capi, - unix_key_import_ecc, - unix_key_import_rsa, + unix_key_asymmetric_import, }; #endif /* __BCRYPT_INTERNAL_H */ diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 408c477b92f..23f30833235 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -1339,7 +1339,7 @@ static void key_destroy( struct key *key ) static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input, ULONG input_len ) { - struct key_import_params params; + struct key_asymmetric_import_params params; struct key *key; NTSTATUS status; ULONG size; @@ -1378,7 +1378,19 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP return STATUS_INVALID_PARAMETER; size = sizeof(*ecc_blob) + ecc_blob->cbKey * 2; - return key_asymmetric_create( (struct key **)ret_key, alg->id, key_size * 8, (BYTE *)ecc_blob, size ); + if ((status = key_asymmetric_create( &key, alg->id, key_size * 8, (BYTE *)ecc_blob, size ))) return status; + params.key = key; + params.flags = KEY_IMPORT_FLAG_PUBLIC; + params.buf = input; + params.len = input_len; + if ((status = UNIX_CALL( key_asymmetric_import, ¶ms ))) + { + key_destroy( key ); + return status; + } + + *ret_key = key; + return STATUS_SUCCESS; } else if (!wcscmp( type, BCRYPT_ECCPRIVATE_BLOB )) { @@ -1409,11 +1421,11 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP size = sizeof(*ecc_blob) + key_size * 2; if ((status = key_asymmetric_create( &key, alg->id, key_size * 8, NULL, size ))) return status; - - params.key = key; - params.buf = input; - params.len = input_len; - if ((status = UNIX_CALL( key_import_ecc, ¶ms ))) + params.key = key; + params.flags = 0; + params.buf = input; + params.len = input_len; + if ((status = UNIX_CALL( key_asymmetric_import, ¶ms ))) { key_destroy( key ); return status; @@ -1432,7 +1444,20 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus; if (size != input_len) return NTE_BAD_DATA; - return key_asymmetric_create( (struct key **)ret_key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size ); + + if ((status = key_asymmetric_create( &key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size ))) return status; + params.key = key; + params.flags = KEY_IMPORT_FLAG_PUBLIC; + params.buf = input; + params.len = input_len; + if ((status = UNIX_CALL( key_asymmetric_import, ¶ms ))) + { + key_destroy( key ); + return status; + } + + *ret_key = key; + return STATUS_SUCCESS; } else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ) || !wcscmp( type, BCRYPT_RSAFULLPRIVATE_BLOB )) { @@ -1443,12 +1468,12 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP rsa_blob->Magic != BCRYPT_RSAFULLPRIVATE_MAGIC)) return STATUS_NOT_SUPPORTED; size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus; - if ((status = key_asymmetric_create( &key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size ))) - return status; - params.key = key; - params.buf = input; - params.len = input_len; - if ((status = UNIX_CALL( key_import_rsa, ¶ms ))) + if ((status = key_asymmetric_create( &key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size ))) return status; + params.key = key; + params.flags = 0; + params.buf = input; + params.len = input_len; + if ((status = UNIX_CALL( key_asymmetric_import, ¶ms ))) { key_destroy( key ); return status; @@ -1466,7 +1491,19 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP return STATUS_NOT_SUPPORTED; size = sizeof(*dsa_blob) + dsa_blob->cbKey * 3; - return key_asymmetric_create( (struct key **)ret_key, alg->id, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size ); + if ((status = key_asymmetric_create( &key, alg->id, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size ))) return status; + params.key = key; + params.flags = KEY_IMPORT_FLAG_PUBLIC; + params.buf = input; + params.len = input_len; + if ((status = UNIX_CALL( key_asymmetric_import, ¶ms ))) + { + key_destroy( key ); + return status; + } + + *ret_key = key; + return STATUS_SUCCESS; } else if (!wcscmp( type, LEGACY_DSA_V2_PRIVATE_BLOB )) { @@ -1495,11 +1532,12 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED); if ((status = key_asymmetric_create( &key, alg->id, pubkey->bitlen, NULL, size ))) return status; - - params.key = key; - params.buf = input; - params.len = input_len; - if ((status = UNIX_CALL( key_import_dsa_capi, ¶ms ))) + key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2; + params.key = key; + params.flags = 0; + params.buf = input; + params.len = input_len; + if ((status = UNIX_CALL( key_asymmetric_import, ¶ms ))) { key_destroy( key ); return status; @@ -1531,6 +1569,15 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP if ((status = key_asymmetric_create( &key, alg->id, pubkey->bitlen, (BYTE *)hdr, size ))) return status; key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2; + params.key = key; + params.flags = KEY_IMPORT_FLAG_PUBLIC; + params.buf = input; + params.len = input_len; + if ((status = UNIX_CALL( key_asymmetric_import, ¶ms ))) + { + key_destroy( key ); + return status; + } *ret_key = key; return STATUS_SUCCESS; diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index 01e1fe72092..28119fc9e78 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -1162,10 +1162,8 @@ static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *r return STATUS_SUCCESS; } -static NTSTATUS key_import_ecc( void *args ) +static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len ) { - const struct key_import_params *params = args; - struct key *key = params->key; BCRYPT_ECCKEY_BLOB *ecc_blob; gnutls_ecc_curve_t curve; gnutls_privkey_t handle; @@ -1191,7 +1189,7 @@ static NTSTATUS key_import_ecc( void *args ) return STATUS_INTERNAL_ERROR; } - ecc_blob = (BCRYPT_ECCKEY_BLOB *)params->buf; + ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf; x.data = (unsigned char *)(ecc_blob + 1); x.size = ecc_blob->cbKey; y.data = x.data + ecc_blob->cbKey; @@ -1212,6 +1210,7 @@ static NTSTATUS key_import_ecc( void *args ) return status; } + if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey ); key_data(key)->privkey = handle; return STATUS_SUCCESS; } @@ -1273,10 +1272,9 @@ static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG return STATUS_SUCCESS; } -static NTSTATUS key_import_rsa( void *args ) +static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len ) { - const struct key_import_params *params = args; - BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)params->buf; + BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf; gnutls_datum_t m, e, p, q; gnutls_privkey_t handle; int ret; @@ -1303,7 +1301,8 @@ static NTSTATUS key_import_rsa( void *args ) return STATUS_INTERNAL_ERROR; } - key_data(params->key)->privkey = handle; + if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey ); + key_data(key)->privkey = handle; return STATUS_SUCCESS; } @@ -1366,11 +1365,9 @@ static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULO return STATUS_SUCCESS; } -static NTSTATUS key_import_dsa_capi( void *args ) +static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len ) { - const struct key_import_params *params = args; - struct key *key = params->key; - BLOBHEADER *hdr = (BLOBHEADER *)params->buf; + BLOBHEADER *hdr = (BLOBHEADER *)buf; DSSPUBKEY *pubkey; gnutls_privkey_t handle; gnutls_datum_t p, q, g, y, x; @@ -1435,9 +1432,8 @@ static NTSTATUS key_import_dsa_capi( void *args ) memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) ); - key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2; + if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey ); key_data(key)->privkey = handle; - return STATUS_SUCCESS; } @@ -1650,6 +1646,50 @@ static NTSTATUS key_asymmetric_export( void *args ) } } +static NTSTATUS key_asymmetric_import( void *args ) +{ + const struct key_asymmetric_import_params *params = args; + struct key *key = params->key; + unsigned flags = params->flags; + + switch (key->alg_id) + { + case ALG_ID_ECDH_P256: + case ALG_ID_ECDSA_P256: + case ALG_ID_ECDSA_P384: + if (flags & KEY_IMPORT_FLAG_PUBLIC) + { + FIXME("\n"); + return STATUS_SUCCESS; + } + return key_import_ecc( key, params->buf, params->len ); + + case ALG_ID_RSA: + case ALG_ID_RSA_SIGN: + if (flags & KEY_IMPORT_FLAG_PUBLIC) + { + FIXME("\n"); + return STATUS_SUCCESS; + } + return key_import_rsa( key, params->buf, params->len ); + + case ALG_ID_DSA: + if (flags & KEY_IMPORT_FLAG_PUBLIC) + { + FIXME("\n"); + return STATUS_SUCCESS; + } + if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2) + return key_import_dsa_capi( key, params->buf, params->len ); + FIXME( "DSA private key not supported\n" ); + return STATUS_NOT_IMPLEMENTED; + + default: + FIXME( "algorithm %u not yet supported\n", key->alg_id ); + return STATUS_NOT_IMPLEMENTED; + } +} + static NTSTATUS prepare_gnutls_signature_dsa( struct key *key, UCHAR *signature, ULONG signature_len, gnutls_datum_t *gnutls_signature ) { @@ -2085,9 +2125,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = key_asymmetric_verify, key_asymmetric_destroy, key_asymmetric_export, - key_import_dsa_capi, - key_import_ecc, - key_import_rsa + key_asymmetric_import }; #ifdef _WIN64 @@ -2477,11 +2515,12 @@ static NTSTATUS wow64_key_asymmetric_export( void *args ) return ret; } -static NTSTATUS wow64_key_import_dsa_capi( void *args ) +static NTSTATUS wow64_key_asymmetric_import( void *args ) { struct { PTR32 key; + ULONG flags; PTR32 buf; ULONG len; } const *params32 = args; @@ -2489,62 +2528,15 @@ static NTSTATUS wow64_key_import_dsa_capi( void *args ) NTSTATUS ret; struct key key; struct key32 *key32 = ULongToPtr( params32->key ); - struct key_import_params params = + struct key_asymmetric_import_params params = { get_asymmetric_key( key32, &key ), + params32->flags, ULongToPtr(params32->buf), params32->len }; - ret = key_import_dsa_capi( ¶ms ); - put_asymmetric_key32( &key, key32 ); - return ret; -} - -static NTSTATUS wow64_key_import_ecc( void *args ) -{ - struct - { - PTR32 key; - PTR32 buf; - ULONG len; - } const *params32 = args; - - NTSTATUS ret; - struct key key; - struct key32 *key32 = ULongToPtr( params32->key ); - struct key_import_params params = - { - get_asymmetric_key( key32, &key ), - ULongToPtr(params32->buf), - params32->len - }; - - ret = key_import_ecc( ¶ms ); - put_asymmetric_key32( &key, key32 ); - return ret; -} - -static NTSTATUS wow64_key_import_rsa( void *args ) -{ - struct - { - PTR32 key; - PTR32 buf; - ULONG len; - } const *params32 = args; - - NTSTATUS ret; - struct key key; - struct key32 *key32 = ULongToPtr( params32->key ); - struct key_import_params params = - { - get_asymmetric_key( key32, &key ), - ULongToPtr(params32->buf), - params32->len - }; - - ret = key_import_rsa( ¶ms ); + ret = key_asymmetric_import( ¶ms ); put_asymmetric_key32( &key, key32 ); return ret; } @@ -2566,9 +2558,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = wow64_key_asymmetric_verify, wow64_key_asymmetric_destroy, wow64_key_asymmetric_export, - wow64_key_import_dsa_capi, - wow64_key_import_ecc, - wow64_key_import_rsa + wow64_key_asymmetric_import }; #endif /* _WIN64 */