bcrypt: Add initial support for asymmetric keys in BCryptDecrypt().
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:
parent
497c902857
commit
38d9020f29
|
@ -206,6 +206,7 @@ struct key_funcs
|
||||||
void (CDECL *key_symmetric_destroy)( struct key * );
|
void (CDECL *key_symmetric_destroy)( struct key * );
|
||||||
NTSTATUS (CDECL *key_asymmetric_init)( struct key * );
|
NTSTATUS (CDECL *key_asymmetric_init)( struct key * );
|
||||||
NTSTATUS (CDECL *key_asymmetric_generate)( struct key * );
|
NTSTATUS (CDECL *key_asymmetric_generate)( struct key * );
|
||||||
|
NTSTATUS (CDECL *key_asymmetric_decrypt)( struct key *, UCHAR *, ULONG, UCHAR *, ULONG * );
|
||||||
NTSTATUS (CDECL *key_asymmetric_duplicate)( struct key *, struct key * );
|
NTSTATUS (CDECL *key_asymmetric_duplicate)( struct key *, struct key * );
|
||||||
NTSTATUS (CDECL *key_asymmetric_sign)( struct key *, void *, UCHAR *, ULONG, UCHAR *, ULONG, ULONG *, ULONG );
|
NTSTATUS (CDECL *key_asymmetric_sign)( struct key *, void *, UCHAR *, ULONG, UCHAR *, ULONG, ULONG *, ULONG );
|
||||||
NTSTATUS (CDECL *key_asymmetric_verify)( struct key *, void *, UCHAR *, ULONG, UCHAR *, ULONG, DWORD );
|
NTSTATUS (CDECL *key_asymmetric_verify)( struct key *, void *, UCHAR *, ULONG, UCHAR *, ULONG, DWORD );
|
||||||
|
|
|
@ -1160,8 +1160,8 @@ static NTSTATUS key_encrypt( struct key *key, UCHAR *input, ULONG input_len, vo
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS key_decrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
|
static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
|
||||||
ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
|
ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
|
||||||
{
|
{
|
||||||
ULONG bytes_left = input_len;
|
ULONG bytes_left = input_len;
|
||||||
UCHAR *buf, *src, *dst;
|
UCHAR *buf, *src, *dst;
|
||||||
|
@ -1240,6 +1240,24 @@ static NTSTATUS key_decrypt( struct key *key, UCHAR *input, ULONG input_len, voi
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS key_asymmetric_decrypt( struct key *key, UCHAR *input, ULONG input_len, UCHAR *output,
|
||||||
|
ULONG output_len, ULONG *ret_len )
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
if (!(status = key_funcs->key_asymmetric_decrypt( key, input, input_len, output, &output_len )))
|
||||||
|
*ret_len = output_len;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS key_decrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
|
||||||
|
ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
|
||||||
|
{
|
||||||
|
return key_is_symmetric( key ) ? key_symmetric_decrypt( key, input, input_len, padding, iv, iv_len,
|
||||||
|
output, output_len, ret_len, flags ) : key_asymmetric_decrypt( key, input, input_len, output, output_len, ret_len );
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
|
static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
|
||||||
ULONG input_len )
|
ULONG input_len )
|
||||||
{
|
{
|
||||||
|
|
|
@ -109,6 +109,7 @@ static int (*pgnutls_privkey_generate)(gnutls_privkey_t, gnutls_pk_algorithm_t,
|
||||||
static int (*pgnutls_privkey_import_rsa_raw)(gnutls_privkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
|
static int (*pgnutls_privkey_import_rsa_raw)(gnutls_privkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
|
||||||
const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *,
|
const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *,
|
||||||
const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *);
|
const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *);
|
||||||
|
static int (*pgnutls_privkey_decrypt_data)(gnutls_privkey_t, unsigned int flags, const gnutls_datum_t *, gnutls_datum_t *);
|
||||||
|
|
||||||
/* Not present in gnutls version < 3.6.0 */
|
/* Not present in gnutls version < 3.6.0 */
|
||||||
static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
|
static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
|
||||||
|
@ -124,6 +125,7 @@ MAKE_FUNCPTR(gnutls_global_init);
|
||||||
MAKE_FUNCPTR(gnutls_global_set_log_function);
|
MAKE_FUNCPTR(gnutls_global_set_log_function);
|
||||||
MAKE_FUNCPTR(gnutls_global_set_log_level);
|
MAKE_FUNCPTR(gnutls_global_set_log_level);
|
||||||
MAKE_FUNCPTR(gnutls_perror);
|
MAKE_FUNCPTR(gnutls_perror);
|
||||||
|
MAKE_FUNCPTR(gnutls_privkey_decrypt_data);
|
||||||
MAKE_FUNCPTR(gnutls_privkey_deinit);
|
MAKE_FUNCPTR(gnutls_privkey_deinit);
|
||||||
MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw);
|
MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw);
|
||||||
MAKE_FUNCPTR(gnutls_privkey_init);
|
MAKE_FUNCPTR(gnutls_privkey_init);
|
||||||
|
@ -215,6 +217,12 @@ static int compat_gnutls_privkey_import_rsa_raw(gnutls_privkey_t key, const gnut
|
||||||
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
|
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int compat_gnutls_privkey_decrypt_data(gnutls_privkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
|
||||||
|
gnutls_datum_t *plain_text)
|
||||||
|
{
|
||||||
|
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
|
||||||
|
}
|
||||||
|
|
||||||
static void gnutls_log( int level, const char *msg )
|
static void gnutls_log( int level, const char *msg )
|
||||||
{
|
{
|
||||||
TRACE( "<%d> %s", level, msg );
|
TRACE( "<%d> %s", level, msg );
|
||||||
|
@ -341,6 +349,11 @@ static BOOL gnutls_initialize(void)
|
||||||
WARN("gnutls_privkey_import_rsa_raw not found\n");
|
WARN("gnutls_privkey_import_rsa_raw not found\n");
|
||||||
pgnutls_privkey_import_rsa_raw = compat_gnutls_privkey_import_rsa_raw;
|
pgnutls_privkey_import_rsa_raw = compat_gnutls_privkey_import_rsa_raw;
|
||||||
}
|
}
|
||||||
|
if (!(pgnutls_privkey_decrypt_data = dlsym( libgnutls_handle, "gnutls_privkey_decrypt_data" )))
|
||||||
|
{
|
||||||
|
WARN("gnutls_privkey_decrypt_data not found\n");
|
||||||
|
pgnutls_privkey_decrypt_data = compat_gnutls_privkey_decrypt_data;
|
||||||
|
}
|
||||||
|
|
||||||
if (TRACE_ON( bcrypt ))
|
if (TRACE_ON( bcrypt ))
|
||||||
{
|
{
|
||||||
|
@ -1883,6 +1896,35 @@ static NTSTATUS CDECL key_asymmetric_duplicate( struct key *key_orig, struct key
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS CDECL key_asymmetric_decrypt( struct key *key, UCHAR *input, ULONG input_len,
|
||||||
|
UCHAR *output, ULONG *output_len )
|
||||||
|
{
|
||||||
|
gnutls_datum_t e, d = { 0 };
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
e.data = (unsigned char *)input;
|
||||||
|
e.size = input_len;
|
||||||
|
|
||||||
|
if ((ret = pgnutls_privkey_decrypt_data( key_data(key)->privkey, 0, &e, &d )))
|
||||||
|
{
|
||||||
|
pgnutls_perror( ret );
|
||||||
|
return STATUS_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*output_len >= d.size)
|
||||||
|
{
|
||||||
|
*output_len = d.size;
|
||||||
|
memcpy( output, d.data, *output_len );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
free( d.data );
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct key_funcs key_funcs =
|
static const struct key_funcs key_funcs =
|
||||||
{
|
{
|
||||||
key_set_property,
|
key_set_property,
|
||||||
|
@ -1895,6 +1937,7 @@ static const struct key_funcs key_funcs =
|
||||||
key_symmetric_destroy,
|
key_symmetric_destroy,
|
||||||
key_asymmetric_init,
|
key_asymmetric_init,
|
||||||
key_asymmetric_generate,
|
key_asymmetric_generate,
|
||||||
|
key_asymmetric_decrypt,
|
||||||
key_asymmetric_duplicate,
|
key_asymmetric_duplicate,
|
||||||
key_asymmetric_sign,
|
key_asymmetric_sign,
|
||||||
key_asymmetric_verify,
|
key_asymmetric_verify,
|
||||||
|
|
|
@ -271,6 +271,13 @@ static NTSTATUS CDECL key_asymmetric_duplicate( struct key *key_orig, struct key
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS CDECL key_asymmetric_decrypt( struct key *key, UCHAR *input, ULONG input_len,
|
||||||
|
UCHAR *output, ULONG *output_len )
|
||||||
|
{
|
||||||
|
FIXME( "not implemented on Mac\n" );
|
||||||
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct key_funcs key_funcs =
|
static const struct key_funcs key_funcs =
|
||||||
{
|
{
|
||||||
key_set_property,
|
key_set_property,
|
||||||
|
@ -283,6 +290,7 @@ static const struct key_funcs key_funcs =
|
||||||
key_symmetric_destroy,
|
key_symmetric_destroy,
|
||||||
key_asymmetric_init,
|
key_asymmetric_init,
|
||||||
key_asymmetric_generate,
|
key_asymmetric_generate,
|
||||||
|
key_asymmetric_decrypt,
|
||||||
key_asymmetric_duplicate,
|
key_asymmetric_duplicate,
|
||||||
key_asymmetric_sign,
|
key_asymmetric_sign,
|
||||||
key_asymmetric_verify,
|
key_asymmetric_verify,
|
||||||
|
|
Loading…
Reference in New Issue