mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-01 19:38:31 +00:00
bcrypt: Add support for importing DH keys.
This commit is contained in:
parent
94d90ceec4
commit
36e1c9380c
|
@ -1819,7 +1819,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)input;
|
||||
|
||||
if (input_len < sizeof(*dsa_blob)) return STATUS_INVALID_PARAMETER;
|
||||
if ((alg->id != ALG_ID_DSA) || dsa_blob->dwMagic != BCRYPT_DSA_PUBLIC_MAGIC)
|
||||
if (alg->id != ALG_ID_DSA || dsa_blob->dwMagic != BCRYPT_DSA_PUBLIC_MAGIC)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
if ((status = key_asymmetric_create( alg->id, dsa_blob->cbKey * 8, &key ))) return status;
|
||||
|
@ -1912,6 +1912,50 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
*ret_key = key;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (!wcscmp( type, BCRYPT_DH_PRIVATE_BLOB ))
|
||||
{
|
||||
BCRYPT_DH_KEY_BLOB *dh_blob = (BCRYPT_DH_KEY_BLOB *)input;
|
||||
|
||||
if (input_len < sizeof(*dh_blob)) return STATUS_INVALID_PARAMETER;
|
||||
if (alg->id != ALG_ID_DH || dh_blob->dwMagic != BCRYPT_DH_PRIVATE_MAGIC)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
if ((status = key_asymmetric_create( alg->id, dh_blob->cbKey * 8, &key ))) 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;
|
||||
}
|
||||
|
||||
*ret_key = key;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (!wcscmp( type, BCRYPT_DH_PUBLIC_BLOB ))
|
||||
{
|
||||
BCRYPT_DH_KEY_BLOB *dh_blob = (BCRYPT_DH_KEY_BLOB *)input;
|
||||
|
||||
if (input_len < sizeof(*dh_blob)) return STATUS_INVALID_PARAMETER;
|
||||
if (alg->id != ALG_ID_DH || dh_blob->dwMagic != BCRYPT_DH_PUBLIC_MAGIC)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
if ((status = key_asymmetric_create( alg->id, dh_blob->cbKey * 8, &key ))) 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;
|
||||
}
|
||||
|
||||
FIXME( "unsupported key type %s\n", debugstr_w(type) );
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
|
|
@ -150,6 +150,9 @@ static int (*pgnutls_privkey_derive_secret)(gnutls_privkey_t, gnutls_pubkey_t, c
|
|||
static int (*pgnutls_privkey_export_dh_raw)(gnutls_privkey_t, gnutls_dh_params_t, gnutls_datum_t *, gnutls_datum_t *,
|
||||
unsigned int);
|
||||
static int (*pgnutls_pubkey_export_dh_raw)(gnutls_pubkey_t, gnutls_dh_params_t, gnutls_datum_t *, unsigned);
|
||||
static int (*pgnutls_privkey_import_dh_raw)(gnutls_privkey_t, const gnutls_dh_params_t, const gnutls_datum_t *,
|
||||
const gnutls_datum_t *);
|
||||
static int (*pgnutls_pubkey_import_dh_raw)(gnutls_pubkey_t, const gnutls_dh_params_t, const gnutls_datum_t *);
|
||||
|
||||
static void *libgnutls_handle;
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
|
@ -159,6 +162,7 @@ MAKE_FUNCPTR(gnutls_cipher_encrypt2);
|
|||
MAKE_FUNCPTR(gnutls_cipher_init);
|
||||
MAKE_FUNCPTR(gnutls_dh_params_deinit);
|
||||
MAKE_FUNCPTR(gnutls_dh_params_export_raw);
|
||||
MAKE_FUNCPTR(gnutls_dh_params_import_raw);
|
||||
MAKE_FUNCPTR(gnutls_dh_params_init);
|
||||
MAKE_FUNCPTR(gnutls_global_deinit);
|
||||
MAKE_FUNCPTR(gnutls_global_init);
|
||||
|
@ -330,6 +334,18 @@ static int compat_gnutls_pubkey_export_dh_raw(gnutls_pubkey_t pubkey, gnutls_dh_
|
|||
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
|
||||
}
|
||||
|
||||
static int compat_gnutls_privkey_import_dh_raw(gnutls_privkey_t privkey, const gnutls_dh_params_t params,
|
||||
const gnutls_datum_t *y, const gnutls_datum_t *x)
|
||||
{
|
||||
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
|
||||
}
|
||||
|
||||
static int compat_gnutls_pubkey_import_dh_raw(gnutls_pubkey_t pubkey, const gnutls_dh_params_t params,
|
||||
const gnutls_datum_t *y)
|
||||
{
|
||||
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
|
||||
}
|
||||
|
||||
static void gnutls_log( int level, const char *msg )
|
||||
{
|
||||
TRACE( "<%d> %s", level, msg );
|
||||
|
@ -369,6 +385,7 @@ static NTSTATUS gnutls_process_attach( void *args )
|
|||
LOAD_FUNCPTR(gnutls_cipher_init)
|
||||
LOAD_FUNCPTR(gnutls_dh_params_deinit)
|
||||
LOAD_FUNCPTR(gnutls_dh_params_export_raw)
|
||||
LOAD_FUNCPTR(gnutls_dh_params_import_raw)
|
||||
LOAD_FUNCPTR(gnutls_dh_params_init)
|
||||
LOAD_FUNCPTR(gnutls_global_deinit)
|
||||
LOAD_FUNCPTR(gnutls_global_init)
|
||||
|
@ -402,6 +419,7 @@ static NTSTATUS gnutls_process_attach( void *args )
|
|||
LOAD_FUNCPTR_OPT(gnutls_privkey_export_ecc_raw)
|
||||
LOAD_FUNCPTR_OPT(gnutls_privkey_export_rsa_raw)
|
||||
LOAD_FUNCPTR_OPT(gnutls_privkey_generate)
|
||||
LOAD_FUNCPTR_OPT(gnutls_privkey_import_dh_raw)
|
||||
LOAD_FUNCPTR_OPT(gnutls_privkey_import_ecc_raw)
|
||||
LOAD_FUNCPTR_OPT(gnutls_privkey_import_rsa_raw)
|
||||
LOAD_FUNCPTR_OPT(gnutls_privkey_set_spki)
|
||||
|
@ -410,6 +428,7 @@ static NTSTATUS gnutls_process_attach( void *args )
|
|||
LOAD_FUNCPTR_OPT(gnutls_pubkey_export_dsa_raw)
|
||||
LOAD_FUNCPTR_OPT(gnutls_pubkey_export_ecc_raw)
|
||||
LOAD_FUNCPTR_OPT(gnutls_pubkey_export_rsa_raw)
|
||||
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dh_raw)
|
||||
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_dsa_raw)
|
||||
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_ecc_raw)
|
||||
LOAD_FUNCPTR_OPT(gnutls_pubkey_import_rsa_raw)
|
||||
|
@ -1710,6 +1729,110 @@ static NTSTATUS key_asymmetric_export( void *args )
|
|||
}
|
||||
}
|
||||
|
||||
static NTSTATUS key_import_dh_public( struct key *key, UCHAR *buf, ULONG len )
|
||||
{
|
||||
BCRYPT_DH_KEY_BLOB *dh_blob;
|
||||
gnutls_dh_params_t params;
|
||||
gnutls_datum_t p, g, y;
|
||||
gnutls_pubkey_t handle;
|
||||
int ret;
|
||||
|
||||
if ((ret = pgnutls_pubkey_init( &handle )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_dh_params_init( ¶ms )) < 0)
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_pubkey_deinit( handle );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
|
||||
p.data = buf + sizeof(*dh_blob);
|
||||
p.size = dh_blob->cbKey;
|
||||
g.data = buf + sizeof(*dh_blob) + dh_blob->cbKey;
|
||||
g.size = dh_blob->cbKey;
|
||||
y.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 2;
|
||||
y.size = dh_blob->cbKey;
|
||||
|
||||
if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )) < 0)
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_dh_params_deinit( params );
|
||||
pgnutls_pubkey_deinit( handle );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
ret = pgnutls_pubkey_import_dh_raw( handle, params, &y );
|
||||
pgnutls_dh_params_deinit( params );
|
||||
if (ret < 0)
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_pubkey_deinit( handle );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
|
||||
key_data(key)->a.pubkey = handle;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS key_import_dh( struct key *key, UCHAR *buf, ULONG len )
|
||||
{
|
||||
BCRYPT_DH_KEY_BLOB *dh_blob;
|
||||
gnutls_dh_params_t params;
|
||||
gnutls_datum_t p, g, y, x;
|
||||
gnutls_privkey_t handle;
|
||||
int ret;
|
||||
|
||||
if ((ret = pgnutls_privkey_init( &handle )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_dh_params_init( ¶ms )) < 0)
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_privkey_deinit( handle );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
dh_blob = (BCRYPT_DH_KEY_BLOB *)buf;
|
||||
p.data = buf + sizeof(*dh_blob);
|
||||
p.size = dh_blob->cbKey;
|
||||
g.data = buf + sizeof(*dh_blob) + dh_blob->cbKey;
|
||||
g.size = dh_blob->cbKey;
|
||||
y.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 2;
|
||||
y.size = dh_blob->cbKey;
|
||||
x.data = buf + sizeof(*dh_blob) + dh_blob->cbKey * 3;
|
||||
x.size = dh_blob->cbKey;
|
||||
|
||||
if ((ret = pgnutls_dh_params_import_raw( params, &p, &g )) < 0)
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_dh_params_deinit( params );
|
||||
pgnutls_privkey_deinit( handle );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
ret = pgnutls_privkey_import_dh_raw( handle, params, &y, &x );
|
||||
pgnutls_dh_params_deinit( params );
|
||||
if (ret < 0)
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_privkey_deinit( handle );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
|
||||
key_data(key)->a.privkey = handle;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS key_asymmetric_import( void *args )
|
||||
{
|
||||
const struct key_asymmetric_import_params *params = args;
|
||||
|
@ -1751,6 +1874,11 @@ static NTSTATUS key_asymmetric_import( void *args )
|
|||
FIXME( "DSA private key not supported\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
case ALG_ID_DH:
|
||||
if (flags & KEY_IMPORT_FLAG_PUBLIC)
|
||||
return key_import_dh_public( key, params->buf, params->len );
|
||||
return key_import_dh( key, params->buf, params->len );
|
||||
|
||||
default:
|
||||
FIXME( "algorithm %u not yet supported\n", key->alg_id );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
|
Loading…
Reference in a new issue