bcrypt: Implement RSA key pair importing.

Requires libgnutls 3.7.0, that contains fixes for optional arguments handling
in gnutls_privkey_import_rsa_raw() to support BCRYPT_RSAPRIVATE_BLOB.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-12-03 09:02:35 +03:00 committed by Alexandre Julliard
parent 4c6b675198
commit 21839185d9
4 changed files with 65 additions and 2 deletions

View file

@ -214,6 +214,7 @@ struct key_funcs
NTSTATUS (CDECL *key_export_ecc)( struct key *, UCHAR *, ULONG, ULONG * );
NTSTATUS (CDECL *key_import_dsa_capi)( struct key *, UCHAR *, ULONG );
NTSTATUS (CDECL *key_import_ecc)( struct key *, UCHAR *, ULONG );
NTSTATUS (CDECL *key_import_rsa)( struct key *, UCHAR *, ULONG );
};
#endif /* __BCRYPT_INTERNAL_H */

View file

@ -1331,6 +1331,27 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
return key_asymmetric_create( (struct key **)ret_key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size );
}
else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ))
{
BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
ULONG size;
if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER;
if (alg->id != ALG_ID_RSA || rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC)
return STATUS_NOT_SUPPORTED;
size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
if ((status = key_asymmetric_create( &key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size )))
return status;
if ((status = key_funcs->key_import_rsa( key, input, input_len )))
{
BCryptDestroyKey( key );
return status;
}
*ret_key = key;
return STATUS_SUCCESS;
}
else if (!wcscmp( type, BCRYPT_DSA_PUBLIC_BLOB ))
{
BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)input;

View file

@ -1119,6 +1119,39 @@ static NTSTATUS CDECL key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
return STATUS_SUCCESS;
}
static NTSTATUS CDECL key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
{
BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
gnutls_datum_t m, e, p, q;
gnutls_privkey_t handle;
int ret;
if ((ret = pgnutls_privkey_init( &handle )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
e.data = (unsigned char *)(rsa_blob + 1);
e.size = rsa_blob->cbPublicExp;
m.data = e.data + e.size;
m.size = rsa_blob->cbModulus;
p.data = m.data + m.size;
p.size = rsa_blob->cbPrime1;
q.data = p.data + p.size;
q.size = rsa_blob->cbPrime2;
if ((ret = pgnutls_privkey_import_rsa_raw( handle, &m, &e, NULL, &p, &q, NULL, NULL, NULL )))
{
pgnutls_perror( ret );
pgnutls_privkey_deinit( handle );
return STATUS_INTERNAL_ERROR;
}
key_data(key)->privkey = handle;
return STATUS_SUCCESS;
}
static NTSTATUS CDECL key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
{
BLOBHEADER *hdr;
@ -1869,7 +1902,8 @@ static const struct key_funcs key_funcs =
key_export_dsa_capi,
key_export_ecc,
key_import_dsa_capi,
key_import_ecc
key_import_ecc,
key_import_rsa
};
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )

View file

@ -249,6 +249,12 @@ static NTSTATUS CDECL key_import_ecc( struct key *key, UCHAR *input, ULONG len )
return STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS CDECL key_import_rsa( struct key *key, UCHAR *input, ULONG len )
{
FIXME( "not implemented on Mac\n" );
return STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS CDECL key_asymmetric_generate( struct key *key )
{
FIXME( "not implemented on Mac\n" );
@ -284,7 +290,8 @@ static const struct key_funcs key_funcs =
key_export_dsa_capi,
key_export_ecc,
key_import_dsa_capi,
key_import_ecc
key_import_ecc,
key_import_rsa
};
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )