bcrypt: Merge the various key import Unix calls into one.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2022-03-21 09:50:09 +01:00 committed by Alexandre Julliard
parent c1ed9ca9b1
commit 0c2408464c
3 changed files with 132 additions and 95 deletions

View file

@ -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 */

View file

@ -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, &params )))
{
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, &params )))
params.key = key;
params.flags = 0;
params.buf = input;
params.len = input_len;
if ((status = UNIX_CALL( key_asymmetric_import, &params )))
{
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, &params )))
{
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, &params )))
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, &params )))
{
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, &params )))
{
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, &params )))
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, &params )))
{
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, &params )))
{
key_destroy( key );
return status;
}
*ret_key = key;
return STATUS_SUCCESS;

View file

@ -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( &params );
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( &params );
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( &params );
ret = key_asymmetric_import( &params );
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 */