mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-21 12:04:09 +00:00
bcrypt: Store a public key handle instead of a blob.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0c2408464c
commit
b352d353b4
|
@ -175,8 +175,6 @@ struct key_asymmetric
|
|||
{
|
||||
ULONG bitlen; /* ignored for ECC keys */
|
||||
unsigned flags;
|
||||
UCHAR *pubkey;
|
||||
unsigned pubkey_len;
|
||||
DSSSEED dss_seed;
|
||||
};
|
||||
|
||||
|
|
|
@ -968,8 +968,7 @@ NTSTATUS WINAPI BCryptHash( BCRYPT_ALG_HANDLE algorithm, UCHAR *secret, ULONG se
|
|||
return status;
|
||||
}
|
||||
|
||||
static NTSTATUS key_asymmetric_create( struct key **ret_key, enum alg_id alg_id, ULONG bitlen,
|
||||
const UCHAR *pubkey, ULONG pubkey_len )
|
||||
static NTSTATUS key_asymmetric_create( enum alg_id alg_id, ULONG bitlen, struct key **ret_key )
|
||||
{
|
||||
struct key *key;
|
||||
|
||||
|
@ -983,14 +982,6 @@ static NTSTATUS key_asymmetric_create( struct key **ret_key, enum alg_id alg_id,
|
|||
key->hdr.magic = MAGIC_KEY;
|
||||
key->alg_id = alg_id;
|
||||
key->u.a.bitlen = bitlen;
|
||||
key->u.a.pubkey_len = pubkey_len;
|
||||
|
||||
if (!(key->u.a.pubkey = malloc( pubkey_len )))
|
||||
{
|
||||
free( key );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
if (pubkey) memcpy( key->u.a.pubkey, pubkey, pubkey_len );
|
||||
|
||||
*ret_key = key;
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -1377,8 +1368,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
if (ecc_blob->cbKey != key_size || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 2)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
size = sizeof(*ecc_blob) + ecc_blob->cbKey * 2;
|
||||
if ((status = key_asymmetric_create( &key, alg->id, key_size * 8, (BYTE *)ecc_blob, size ))) return status;
|
||||
if ((status = key_asymmetric_create( alg->id, key_size * 8, &key ))) return status;
|
||||
params.key = key;
|
||||
params.flags = KEY_IMPORT_FLAG_PUBLIC;
|
||||
params.buf = input;
|
||||
|
@ -1419,8 +1409,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
if (ecc_blob->cbKey != key_size || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 3)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
size = sizeof(*ecc_blob) + key_size * 2;
|
||||
if ((status = key_asymmetric_create( &key, alg->id, key_size * 8, NULL, size ))) return status;
|
||||
if ((status = key_asymmetric_create( alg->id, key_size * 8, &key ))) return status;
|
||||
params.key = key;
|
||||
params.flags = 0;
|
||||
params.buf = input;
|
||||
|
@ -1445,7 +1434,7 @@ 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;
|
||||
|
||||
if ((status = key_asymmetric_create( &key, alg->id, rsa_blob->BitLength, (BYTE *)rsa_blob, size ))) return status;
|
||||
if ((status = key_asymmetric_create( alg->id, rsa_blob->BitLength, &key ))) return status;
|
||||
params.key = key;
|
||||
params.flags = KEY_IMPORT_FLAG_PUBLIC;
|
||||
params.buf = input;
|
||||
|
@ -1467,8 +1456,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
if (alg->id != ALG_ID_RSA || (rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC &&
|
||||
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;
|
||||
if ((status = key_asymmetric_create( alg->id, rsa_blob->BitLength, &key ))) return status;
|
||||
params.key = key;
|
||||
params.flags = 0;
|
||||
params.buf = input;
|
||||
|
@ -1490,8 +1478,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
if ((alg->id != ALG_ID_DSA) || dsa_blob->dwMagic != BCRYPT_DSA_PUBLIC_MAGIC)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
|
||||
size = sizeof(*dsa_blob) + dsa_blob->cbKey * 3;
|
||||
if ((status = key_asymmetric_create( &key, alg->id, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size ))) return status;
|
||||
if ((status = key_asymmetric_create( alg->id, dsa_blob->cbKey * 8, &key ))) return status;
|
||||
params.key = key;
|
||||
params.flags = KEY_IMPORT_FLAG_PUBLIC;
|
||||
params.buf = input;
|
||||
|
@ -1530,8 +1517,7 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
if (input_len < sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 2 + 40 + sizeof(DSSSEED))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
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;
|
||||
if ((status = key_asymmetric_create( alg->id, pubkey->bitlen, &key ))) return status;
|
||||
key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
|
||||
params.key = key;
|
||||
params.flags = 0;
|
||||
|
@ -1567,7 +1553,7 @@ 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 (input_len < size) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
if ((status = key_asymmetric_create( &key, alg->id, pubkey->bitlen, (BYTE *)hdr, size ))) return status;
|
||||
if ((status = key_asymmetric_create( alg->id, pubkey->bitlen, &key ))) return status;
|
||||
key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
|
||||
params.key = key;
|
||||
params.flags = KEY_IMPORT_FLAG_PUBLIC;
|
||||
|
@ -1660,36 +1646,15 @@ NTSTATUS WINAPI BCryptGenerateKeyPair( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_H
|
|||
struct algorithm *alg = algorithm;
|
||||
struct key *key;
|
||||
NTSTATUS status;
|
||||
ULONG size;
|
||||
|
||||
TRACE( "%p, %p, %lu, %#lx\n", algorithm, handle, key_len, flags );
|
||||
|
||||
if (!alg || alg->hdr.magic != MAGIC_ALG) return STATUS_INVALID_HANDLE;
|
||||
if (!handle) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
switch (alg->id)
|
||||
{
|
||||
case ALG_ID_ECDH_P256:
|
||||
case ALG_ID_ECDSA_P256:
|
||||
size = sizeof(BCRYPT_ECCKEY_BLOB) + 2 * 256 / 8;
|
||||
break;
|
||||
case ALG_ID_ECDSA_P384:
|
||||
size = sizeof(BCRYPT_ECCKEY_BLOB) + 2 * 384 / 8;
|
||||
break;
|
||||
case ALG_ID_RSA:
|
||||
case ALG_ID_RSA_SIGN:
|
||||
size = sizeof(BCRYPT_RSAKEY_BLOB) + 2 * key_len / 8;
|
||||
break;
|
||||
case ALG_ID_DSA:
|
||||
size = sizeof(BCRYPT_DSA_KEY_BLOB) + 3 * key_len / 8;
|
||||
break;
|
||||
default:
|
||||
FIXME( "algorithm %u not supported\n", alg->id );
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (!(status = key_asymmetric_create( &key, alg->id, key_len, NULL, size ))) *handle = key;
|
||||
return status;
|
||||
if ((status = key_asymmetric_create( alg->id, key_len, &key ))) return status;
|
||||
*handle = key;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI BCryptFinalizeKeyPair( BCRYPT_KEY_HANDLE handle, ULONG flags )
|
||||
|
@ -1766,14 +1731,9 @@ static NTSTATUS key_duplicate( struct key *key_orig, struct key *key_copy )
|
|||
{
|
||||
struct key_asymmetric_duplicate_params params;
|
||||
|
||||
if (!(buffer = malloc( key_orig->u.a.pubkey_len ))) return STATUS_NO_MEMORY;
|
||||
memcpy( buffer, key_orig->u.a.pubkey, key_orig->u.a.pubkey_len );
|
||||
|
||||
key_copy->u.a.bitlen = key_orig->u.a.bitlen;
|
||||
key_copy->u.a.flags = key_orig->u.a.flags;
|
||||
key_copy->u.a.pubkey = buffer;
|
||||
key_copy->u.a.pubkey_len = key_orig->u.a.pubkey_len;
|
||||
key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
|
||||
key_copy->u.a.bitlen = key_orig->u.a.bitlen;
|
||||
key_copy->u.a.flags = key_orig->u.a.flags;
|
||||
key_copy->u.a.dss_seed = key_orig->u.a.dss_seed;
|
||||
|
||||
params.key_orig = key_orig;
|
||||
params.key_copy = key_copy;
|
||||
|
|
|
@ -72,7 +72,11 @@ typedef enum
|
|||
union key_data
|
||||
{
|
||||
gnutls_cipher_hd_t cipher;
|
||||
gnutls_privkey_t privkey;
|
||||
struct
|
||||
{
|
||||
gnutls_privkey_t privkey;
|
||||
gnutls_pubkey_t pubkey;
|
||||
} a;
|
||||
};
|
||||
C_ASSERT( sizeof(union key_data) <= sizeof(((struct key *)0)->private) );
|
||||
|
||||
|
@ -98,6 +102,7 @@ static int (*pgnutls_pubkey_import_rsa_raw)(gnutls_pubkey_t, const gnutls_datum_
|
|||
/* Not present in gnutls version < 2.12.0 */
|
||||
static int (*pgnutls_pubkey_import_dsa_raw)(gnutls_pubkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
|
||||
const gnutls_datum_t *, const gnutls_datum_t *);
|
||||
static int (*pgnutls_pubkey_import_privkey)(gnutls_pubkey_t, gnutls_privkey_t, unsigned int, unsigned int);
|
||||
|
||||
/* Not present in gnutls version < 3.3.0 */
|
||||
static int (*pgnutls_privkey_export_ecc_raw)(gnutls_privkey_t, gnutls_ecc_curve_t *,
|
||||
|
@ -133,6 +138,7 @@ MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw);
|
|||
MAKE_FUNCPTR(gnutls_privkey_init);
|
||||
MAKE_FUNCPTR(gnutls_privkey_sign_hash);
|
||||
MAKE_FUNCPTR(gnutls_pubkey_deinit);
|
||||
MAKE_FUNCPTR(gnutls_pubkey_import_privkey);
|
||||
MAKE_FUNCPTR(gnutls_pubkey_init);
|
||||
#undef MAKE_FUNCPTR
|
||||
|
||||
|
@ -272,6 +278,7 @@ static NTSTATUS gnutls_process_attach( void *args )
|
|||
LOAD_FUNCPTR(gnutls_privkey_init);
|
||||
LOAD_FUNCPTR(gnutls_privkey_sign_hash);
|
||||
LOAD_FUNCPTR(gnutls_pubkey_deinit);
|
||||
LOAD_FUNCPTR(gnutls_pubkey_import_privkey);
|
||||
LOAD_FUNCPTR(gnutls_pubkey_init);
|
||||
#undef LOAD_FUNCPTR
|
||||
|
||||
|
@ -609,234 +616,6 @@ static ULONG export_gnutls_datum( UCHAR *buffer, ULONG buflen, gnutls_datum_t *d
|
|||
return size;
|
||||
}
|
||||
|
||||
#define EXPORT_SIZE(d,f,p) export_gnutls_datum( NULL, bitlen / f, &d, p )
|
||||
static NTSTATUS export_gnutls_pubkey_rsa( gnutls_privkey_t gnutls_key, ULONG bitlen, void *pubkey, unsigned *pubkey_len )
|
||||
{
|
||||
BCRYPT_RSAKEY_BLOB *rsa_blob = pubkey;
|
||||
gnutls_datum_t m, e;
|
||||
UCHAR *dst;
|
||||
int ret;
|
||||
|
||||
if ((ret = pgnutls_privkey_export_rsa_raw( gnutls_key, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (*pubkey_len < sizeof(*rsa_blob) + EXPORT_SIZE(e,8,0) + EXPORT_SIZE(m,8,1))
|
||||
{
|
||||
FIXME( "wrong pubkey len %u\n", *pubkey_len );
|
||||
pgnutls_perror( ret );
|
||||
free( e.data ); free( m.data );
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
dst = (UCHAR *)(rsa_blob + 1);
|
||||
rsa_blob->cbPublicExp = export_gnutls_datum( dst, bitlen / 8, &e, 0 );
|
||||
|
||||
dst += rsa_blob->cbPublicExp;
|
||||
rsa_blob->cbModulus = export_gnutls_datum( dst, bitlen / 8, &m, 1 );
|
||||
|
||||
rsa_blob->Magic = BCRYPT_RSAPUBLIC_MAGIC;
|
||||
rsa_blob->BitLength = bitlen;
|
||||
rsa_blob->cbPrime1 = 0;
|
||||
rsa_blob->cbPrime2 = 0;
|
||||
|
||||
*pubkey_len = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
|
||||
|
||||
free( e.data ); free( m.data );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#undef EXPORT_SIZE
|
||||
|
||||
static NTSTATUS export_gnutls_pubkey_ecc( gnutls_privkey_t gnutls_key, enum alg_id alg_id, void *pubkey,
|
||||
unsigned *pubkey_len )
|
||||
{
|
||||
BCRYPT_ECCKEY_BLOB *ecc_blob = pubkey;
|
||||
gnutls_ecc_curve_t curve;
|
||||
gnutls_datum_t x, y;
|
||||
DWORD magic, size;
|
||||
UCHAR *dst;
|
||||
int ret;
|
||||
|
||||
switch (alg_id)
|
||||
{
|
||||
case ALG_ID_ECDH_P256:
|
||||
magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
|
||||
size = 32;
|
||||
break;
|
||||
case ALG_ID_ECDSA_P256:
|
||||
magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
|
||||
size = 32;
|
||||
break;
|
||||
default:
|
||||
FIXME( "algorithm %u not supported\n", alg_id );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_privkey_export_ecc_raw( gnutls_key, &curve, &x, &y, NULL )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (curve != GNUTLS_ECC_CURVE_SECP256R1)
|
||||
{
|
||||
FIXME( "curve %u not supported\n", curve );
|
||||
free( x.data ); free( y.data );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (*pubkey_len < sizeof(*ecc_blob) + size * 2)
|
||||
{
|
||||
FIXME( "wrong pubkey len %u / %lu\n", *pubkey_len, sizeof(*ecc_blob) + size * 2 );
|
||||
pgnutls_perror( ret );
|
||||
free( x.data ); free( y.data );
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
ecc_blob->dwMagic = magic;
|
||||
ecc_blob->cbKey = size;
|
||||
|
||||
dst = (UCHAR *)(ecc_blob + 1);
|
||||
export_gnutls_datum( dst, size, &x, 1 );
|
||||
|
||||
dst += size;
|
||||
export_gnutls_datum( dst, size, &y, 1 );
|
||||
|
||||
*pubkey_len = sizeof(*ecc_blob) + ecc_blob->cbKey * 2;
|
||||
|
||||
free( x.data ); free( y.data );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS export_gnutls_pubkey_dsa( gnutls_privkey_t gnutls_key, ULONG bitlen, void *pubkey, unsigned *pubkey_len )
|
||||
{
|
||||
BCRYPT_DSA_KEY_BLOB *dsa_blob = pubkey;
|
||||
gnutls_datum_t p, q, g, y;
|
||||
UCHAR *dst;
|
||||
int ret;
|
||||
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( gnutls_key, &p, &q, &g, &y, NULL )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (bitlen > 1024)
|
||||
{
|
||||
FIXME( "bitlen > 1024 not supported\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (*pubkey_len < sizeof(*dsa_blob) + bitlen / 8 * 3)
|
||||
{
|
||||
FIXME( "wrong pubkey len %u / %lu\n", *pubkey_len, sizeof(*dsa_blob) + bitlen / 8 * 3 );
|
||||
pgnutls_perror( ret );
|
||||
free( p.data ); free( q.data ); free( g.data ); free( y.data );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
dst = (UCHAR *)(dsa_blob + 1);
|
||||
export_gnutls_datum( dst, bitlen / 8, &p, 1 );
|
||||
|
||||
dst += bitlen / 8;
|
||||
export_gnutls_datum( dst, bitlen / 8, &g, 1 );
|
||||
|
||||
dst += bitlen / 8;
|
||||
export_gnutls_datum( dst, bitlen / 8, &y, 1 );
|
||||
|
||||
dst = dsa_blob->q;
|
||||
export_gnutls_datum( dst, sizeof(dsa_blob->q), &q, 1 );
|
||||
|
||||
dsa_blob->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC;
|
||||
dsa_blob->cbKey = bitlen / 8;
|
||||
memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
|
||||
memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
|
||||
|
||||
*pubkey_len = sizeof(*dsa_blob) + dsa_blob->cbKey * 3;
|
||||
|
||||
free( p.data ); free( q.data ); free( g.data ); free( y.data );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void reverse_bytes( UCHAR *buf, ULONG len )
|
||||
{
|
||||
unsigned int i;
|
||||
UCHAR tmp;
|
||||
|
||||
for (i = 0; i < len / 2; ++i)
|
||||
{
|
||||
tmp = buf[i];
|
||||
buf[i] = buf[len - i - 1];
|
||||
buf[len - i - 1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
#define Q_SIZE 20
|
||||
static NTSTATUS export_gnutls_pubkey_dsa_capi( gnutls_privkey_t gnutls_key, const DSSSEED *seed, unsigned bitlen,
|
||||
void *pubkey, unsigned *pubkey_len )
|
||||
{
|
||||
BLOBHEADER *hdr = pubkey;
|
||||
DSSPUBKEY *dsskey;
|
||||
gnutls_datum_t p, q, g, y;
|
||||
UCHAR *dst;
|
||||
int ret, size = sizeof(*hdr) + sizeof(*dsskey) + sizeof(*seed);
|
||||
|
||||
if (bitlen > 1024)
|
||||
{
|
||||
FIXME( "bitlen > 1024 not supported\n" );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( gnutls_key, &p, &q, &g, &y, NULL )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (*pubkey_len < size + bitlen / 8 * 3 + Q_SIZE)
|
||||
{
|
||||
FIXME( "wrong pubkey len %u / %u\n", *pubkey_len, size + bitlen / 8 * 3 + Q_SIZE );
|
||||
pgnutls_perror( ret );
|
||||
free( p.data ); free( q.data ); free( g.data ); free( y.data );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
hdr->bType = PUBLICKEYBLOB;
|
||||
hdr->bVersion = 2;
|
||||
hdr->reserved = 0;
|
||||
hdr->aiKeyAlg = CALG_DSS_SIGN;
|
||||
|
||||
dsskey = (DSSPUBKEY *)(hdr + 1);
|
||||
dsskey->magic = MAGIC_DSS1;
|
||||
dsskey->bitlen = bitlen;
|
||||
|
||||
dst = (UCHAR *)(dsskey + 1);
|
||||
export_gnutls_datum( dst, bitlen / 8, &p, 1 );
|
||||
reverse_bytes( dst, bitlen / 8 );
|
||||
dst += bitlen / 8;
|
||||
|
||||
export_gnutls_datum( dst, Q_SIZE, &q, 1 );
|
||||
reverse_bytes( dst, Q_SIZE );
|
||||
dst += Q_SIZE;
|
||||
|
||||
export_gnutls_datum( dst, bitlen / 8, &g, 1 );
|
||||
reverse_bytes( dst, bitlen / 8 );
|
||||
dst += bitlen / 8;
|
||||
|
||||
export_gnutls_datum( dst, bitlen / 8, &y, 1 );
|
||||
reverse_bytes( dst, bitlen / 8 );
|
||||
dst += bitlen / 8;
|
||||
|
||||
memcpy( dst, seed, sizeof(*seed) );
|
||||
|
||||
*pubkey_len = size + bitlen / 8 * 3 + Q_SIZE;
|
||||
|
||||
free( p.data ); free( q.data ); free( g.data ); free( y.data );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define EXPORT_SIZE(d,f,p) export_gnutls_datum( NULL, key->u.a.bitlen / f, &d, p )
|
||||
static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
|
||||
{
|
||||
|
@ -845,7 +624,7 @@ static NTSTATUS key_export_rsa_public( struct key *key, UCHAR *buf, ULONG len, U
|
|||
UCHAR *dst;
|
||||
int ret;
|
||||
|
||||
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->privkey, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL )))
|
||||
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -894,7 +673,7 @@ static NTSTATUS key_export_ecc_public( struct key *key, UCHAR *buf, ULONG len, U
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->privkey, &curve, &x, &y, NULL )))
|
||||
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, NULL )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -931,7 +710,7 @@ static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, U
|
|||
UCHAR *dst;
|
||||
int ret;
|
||||
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->privkey, &p, &q, &g, &y, NULL )))
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -968,6 +747,19 @@ static NTSTATUS key_export_dsa_public( struct key *key, UCHAR *buf, ULONG len, U
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void reverse_bytes( UCHAR *buf, ULONG len )
|
||||
{
|
||||
unsigned int i;
|
||||
UCHAR tmp;
|
||||
|
||||
for (i = 0; i < len / 2; ++i)
|
||||
{
|
||||
tmp = buf[i];
|
||||
buf[i] = buf[len - i - 1];
|
||||
buf[len - i - 1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
#define Q_SIZE 20
|
||||
static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
|
||||
{
|
||||
|
@ -983,7 +775,7 @@ static NTSTATUS key_export_dsa_capi_public( struct key *key, UCHAR *buf, ULONG l
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->privkey, &p, &q, &g, &y, NULL )))
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, NULL )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -1029,13 +821,13 @@ static NTSTATUS key_asymmetric_generate( void *args )
|
|||
{
|
||||
struct key *key = args;
|
||||
gnutls_pk_algorithm_t pk_alg;
|
||||
gnutls_privkey_t handle;
|
||||
gnutls_privkey_t privkey;
|
||||
gnutls_pubkey_t pubkey;
|
||||
unsigned int bitlen;
|
||||
NTSTATUS status;
|
||||
int ret;
|
||||
|
||||
if (!libgnutls_handle) return STATUS_INTERNAL_ERROR;
|
||||
if (key_data(key)->privkey) return STATUS_INVALID_HANDLE;
|
||||
if (key_data(key)->a.privkey) return STATUS_INVALID_HANDLE;
|
||||
|
||||
switch (key->alg_id)
|
||||
{
|
||||
|
@ -1061,45 +853,35 @@ static NTSTATUS key_asymmetric_generate( void *args )
|
|||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_privkey_init( &handle )))
|
||||
if ((ret = pgnutls_privkey_init( &privkey )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_privkey_generate( handle, pk_alg, bitlen, 0 )))
|
||||
if ((ret = pgnutls_pubkey_init( &pubkey )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_privkey_deinit( handle );
|
||||
pgnutls_privkey_deinit( privkey );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
switch (pk_alg)
|
||||
if ((ret = pgnutls_privkey_generate( privkey, pk_alg, bitlen, 0 )))
|
||||
{
|
||||
case GNUTLS_PK_RSA:
|
||||
status = export_gnutls_pubkey_rsa( handle, key->u.a.bitlen, key->u.a.pubkey, &key->u.a.pubkey_len );
|
||||
break;
|
||||
|
||||
case GNUTLS_PK_ECC:
|
||||
status = export_gnutls_pubkey_ecc( handle, key->alg_id, key->u.a.pubkey, &key->u.a.pubkey_len );
|
||||
break;
|
||||
|
||||
case GNUTLS_PK_DSA:
|
||||
status = export_gnutls_pubkey_dsa( handle, key->u.a.bitlen, key->u.a.pubkey, &key->u.a.pubkey_len );
|
||||
break;
|
||||
|
||||
default:
|
||||
ERR( "unhandled algorithm %u\n", pk_alg );
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_privkey_deinit( privkey );
|
||||
pgnutls_pubkey_deinit( pubkey );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
if ((ret = pgnutls_pubkey_import_privkey( pubkey, privkey, 0, 0 )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_privkey_deinit( privkey );
|
||||
pgnutls_pubkey_deinit( pubkey );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (status)
|
||||
{
|
||||
pgnutls_privkey_deinit( handle );
|
||||
return status;
|
||||
}
|
||||
|
||||
key_data(key)->privkey = handle;
|
||||
key_data(key)->a.privkey = privkey;
|
||||
key_data(key)->a.pubkey = pubkey;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1128,7 +910,7 @@ static NTSTATUS key_export_ecc( struct key *key, UCHAR *buf, ULONG len, ULONG *r
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->privkey, &curve, &x, &y, &d )))
|
||||
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key)->a.privkey, &curve, &x, &y, &d )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -1168,7 +950,6 @@ static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
|
|||
gnutls_ecc_curve_t curve;
|
||||
gnutls_privkey_t handle;
|
||||
gnutls_datum_t x, y, k;
|
||||
NTSTATUS status;
|
||||
int ret;
|
||||
|
||||
switch (key->alg_id)
|
||||
|
@ -1204,14 +985,8 @@ static NTSTATUS key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
|
|||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((status = export_gnutls_pubkey_ecc( handle, key->alg_id, key->u.a.pubkey, &key->u.a.pubkey_len )))
|
||||
{
|
||||
pgnutls_privkey_deinit( handle );
|
||||
return status;
|
||||
}
|
||||
|
||||
if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
|
||||
key_data(key)->privkey = handle;
|
||||
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
|
||||
key_data(key)->a.privkey = handle;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1224,7 +999,7 @@ static NTSTATUS key_export_rsa( struct key *key, ULONG flags, UCHAR *buf, ULONG
|
|||
UCHAR *dst;
|
||||
int ret;
|
||||
|
||||
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
|
||||
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -1301,8 +1076,8 @@ static NTSTATUS key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
|
|||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
|
||||
key_data(key)->privkey = handle;
|
||||
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
|
||||
key_data(key)->a.privkey = handle;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1314,7 +1089,7 @@ static NTSTATUS key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULO
|
|||
UCHAR *dst;
|
||||
int ret, size;
|
||||
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->privkey, &p, &q, &g, &y, &x )))
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key)->a.privkey, &p, &q, &g, &y, &x )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -1374,7 +1149,6 @@ static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
|
|||
unsigned char dummy[128];
|
||||
unsigned char *data, p_data[128], q_data[20], g_data[128], x_data[20];
|
||||
int i, ret, size;
|
||||
NTSTATUS status;
|
||||
|
||||
if ((ret = pgnutls_privkey_init( &handle )))
|
||||
{
|
||||
|
@ -1423,29 +1197,24 @@ static NTSTATUS key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG len )
|
|||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((status = export_gnutls_pubkey_dsa_capi( handle, &key->u.a.dss_seed, key->u.a.bitlen,
|
||||
key->u.a.pubkey, &key->u.a.pubkey_len )))
|
||||
{
|
||||
pgnutls_privkey_deinit( handle );
|
||||
return status;
|
||||
}
|
||||
|
||||
memcpy( &key->u.a.dss_seed, data, sizeof(key->u.a.dss_seed) );
|
||||
|
||||
if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
|
||||
key_data(key)->privkey = handle;
|
||||
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 import_gnutls_pubkey_ecc( struct key *key, gnutls_pubkey_t *gnutls_key )
|
||||
static NTSTATUS key_import_ecc_public( struct key *key, UCHAR *buf, ULONG len )
|
||||
{
|
||||
BCRYPT_ECCKEY_BLOB *ecc_blob;
|
||||
gnutls_ecc_curve_t curve;
|
||||
gnutls_datum_t x, y;
|
||||
gnutls_pubkey_t handle;
|
||||
int ret;
|
||||
|
||||
switch (key->alg_id)
|
||||
{
|
||||
case ALG_ID_ECDH_P256:
|
||||
case ALG_ID_ECDSA_P256: curve = GNUTLS_ECC_CURVE_SECP256R1; break;
|
||||
case ALG_ID_ECDSA_P384: curve = GNUTLS_ECC_CURVE_SECP384R1; break;
|
||||
|
||||
|
@ -1454,103 +1223,112 @@ static NTSTATUS import_gnutls_pubkey_ecc( struct key *key, gnutls_pubkey_t *gnut
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if ((ret = pgnutls_pubkey_init( gnutls_key )))
|
||||
if ((ret = pgnutls_pubkey_init( &handle )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
ecc_blob = (BCRYPT_ECCKEY_BLOB *)key->u.a.pubkey;
|
||||
x.data = key->u.a.pubkey + sizeof(*ecc_blob);
|
||||
ecc_blob = (BCRYPT_ECCKEY_BLOB *)buf;
|
||||
x.data = buf + sizeof(*ecc_blob);
|
||||
x.size = ecc_blob->cbKey;
|
||||
y.data = key->u.a.pubkey + sizeof(*ecc_blob) + ecc_blob->cbKey;
|
||||
y.data = buf + sizeof(*ecc_blob) + ecc_blob->cbKey;
|
||||
y.size = ecc_blob->cbKey;
|
||||
|
||||
if ((ret = pgnutls_pubkey_import_ecc_raw( *gnutls_key, curve, &x, &y )))
|
||||
if ((ret = pgnutls_pubkey_import_ecc_raw( handle, curve, &x, &y )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_pubkey_deinit( *gnutls_key );
|
||||
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 import_gnutls_pubkey_rsa( struct key *key, gnutls_pubkey_t *gnutls_key )
|
||||
static NTSTATUS key_import_rsa_public( struct key *key, UCHAR *buf, ULONG len )
|
||||
{
|
||||
BCRYPT_RSAKEY_BLOB *rsa_blob;
|
||||
gnutls_pubkey_t handle;
|
||||
gnutls_datum_t m, e;
|
||||
int ret;
|
||||
|
||||
if ((ret = pgnutls_pubkey_init( gnutls_key )))
|
||||
if ((ret = pgnutls_pubkey_init( &handle )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
rsa_blob = (BCRYPT_RSAKEY_BLOB *)key->u.a.pubkey;
|
||||
e.data = key->u.a.pubkey + sizeof(*rsa_blob);
|
||||
rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
|
||||
e.data = buf + sizeof(*rsa_blob);
|
||||
e.size = rsa_blob->cbPublicExp;
|
||||
m.data = key->u.a.pubkey + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
|
||||
m.data = buf + sizeof(*rsa_blob) + rsa_blob->cbPublicExp;
|
||||
m.size = rsa_blob->cbModulus;
|
||||
|
||||
if ((ret = pgnutls_pubkey_import_rsa_raw( *gnutls_key, &m, &e )))
|
||||
if ((ret = pgnutls_pubkey_import_rsa_raw( handle, &m, &e )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_pubkey_deinit( *gnutls_key );
|
||||
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 import_gnutls_pubkey_dsa( struct key *key, gnutls_pubkey_t *gnutls_key )
|
||||
static NTSTATUS key_import_dsa_public( struct key *key, UCHAR *buf, ULONG len )
|
||||
{
|
||||
BCRYPT_DSA_KEY_BLOB *dsa_blob;
|
||||
gnutls_datum_t p, q, g, y;
|
||||
gnutls_pubkey_t handle;
|
||||
int ret;
|
||||
|
||||
if ((ret = pgnutls_pubkey_init( gnutls_key )))
|
||||
if ((ret = pgnutls_pubkey_init( &handle )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
dsa_blob = (BCRYPT_DSA_KEY_BLOB *)key->u.a.pubkey;
|
||||
p.data = key->u.a.pubkey + sizeof(*dsa_blob);
|
||||
dsa_blob = (BCRYPT_DSA_KEY_BLOB *)buf;
|
||||
p.data = buf + sizeof(*dsa_blob);
|
||||
p.size = dsa_blob->cbKey;
|
||||
q.data = dsa_blob->q;
|
||||
q.size = sizeof(dsa_blob->q);
|
||||
g.data = key->u.a.pubkey + sizeof(*dsa_blob) + dsa_blob->cbKey;
|
||||
g.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey;
|
||||
g.size = dsa_blob->cbKey;
|
||||
y.data = key->u.a.pubkey + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
|
||||
y.data = buf + sizeof(*dsa_blob) + dsa_blob->cbKey * 2;
|
||||
y.size = dsa_blob->cbKey;
|
||||
|
||||
if ((ret = pgnutls_pubkey_import_dsa_raw( *gnutls_key, &p, &q, &g, &y )))
|
||||
if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_pubkey_deinit( *gnutls_key );
|
||||
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 import_gnutls_pubkey_dsa_capi( struct key *key, gnutls_pubkey_t *gnutls_key )
|
||||
static NTSTATUS key_import_dsa_capi_public( struct key *key, UCHAR *buf, ULONG len )
|
||||
{
|
||||
BLOBHEADER *hdr;
|
||||
DSSPUBKEY *pubkey;
|
||||
gnutls_datum_t p, q, g, y;
|
||||
gnutls_pubkey_t handle;
|
||||
unsigned char *data, p_data[128], q_data[20], g_data[128], y_data[128];
|
||||
int i, ret, size;
|
||||
|
||||
if ((ret = pgnutls_pubkey_init( gnutls_key )))
|
||||
if ((ret = pgnutls_pubkey_init( &handle )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
hdr = (BLOBHEADER *)key->u.a.pubkey;
|
||||
hdr = (BLOBHEADER *)buf;
|
||||
pubkey = (DSSPUBKEY *)(hdr + 1);
|
||||
size = pubkey->bitlen / 8;
|
||||
data = (unsigned char *)(pubkey + 1);
|
||||
|
@ -1574,40 +1352,18 @@ static NTSTATUS import_gnutls_pubkey_dsa_capi( struct key *key, gnutls_pubkey_t
|
|||
y.size = sizeof(y_data);
|
||||
for (i = 0; i < y.size; i++) y.data[i] = data[y.size - i - 1];
|
||||
|
||||
if ((ret = pgnutls_pubkey_import_dsa_raw( *gnutls_key, &p, &q, &g, &y )))
|
||||
if ((ret = pgnutls_pubkey_import_dsa_raw( handle, &p, &q, &g, &y )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
pgnutls_pubkey_deinit( *gnutls_key );
|
||||
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 import_gnutls_pubkey( struct key *key, gnutls_pubkey_t *gnutls_key )
|
||||
{
|
||||
switch (key->alg_id)
|
||||
{
|
||||
case ALG_ID_ECDSA_P256:
|
||||
case ALG_ID_ECDSA_P384:
|
||||
return import_gnutls_pubkey_ecc( key, gnutls_key );
|
||||
|
||||
case ALG_ID_RSA:
|
||||
case ALG_ID_RSA_SIGN:
|
||||
return import_gnutls_pubkey_rsa( key, gnutls_key );
|
||||
|
||||
case ALG_ID_DSA:
|
||||
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
|
||||
return import_gnutls_pubkey_dsa_capi( key, gnutls_key );
|
||||
else
|
||||
return import_gnutls_pubkey_dsa( key, gnutls_key );
|
||||
|
||||
default:
|
||||
FIXME("algorithm %u not yet supported\n", key->alg_id );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
static NTSTATUS key_asymmetric_export( void *args )
|
||||
{
|
||||
const struct key_asymmetric_export_params *params = args;
|
||||
|
@ -1658,26 +1414,21 @@ static NTSTATUS key_asymmetric_import( void *args )
|
|||
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_public( key, params->buf, params->len );
|
||||
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_public( key, params->buf, params->len );
|
||||
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_public( key, params->buf, params->len );
|
||||
return key_import_dsa_public( key, params->buf, params->len );
|
||||
}
|
||||
if (key->u.a.flags & KEY_FLAG_LEGACY_DSA_V2)
|
||||
return key_import_dsa_capi( key, params->buf, params->len );
|
||||
|
@ -1760,7 +1511,6 @@ static NTSTATUS key_asymmetric_verify( void *args )
|
|||
gnutls_sign_algorithm_t sign_alg;
|
||||
gnutls_datum_t gnutls_hash, gnutls_signature;
|
||||
gnutls_pk_algorithm_t pk_alg;
|
||||
gnutls_pubkey_t gnutls_key;
|
||||
NTSTATUS status;
|
||||
int ret;
|
||||
|
||||
|
@ -1824,19 +1574,14 @@ static NTSTATUS key_asymmetric_verify( void *args )
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if ((status = import_gnutls_pubkey( key, &gnutls_key ))) return status;
|
||||
if ((status = prepare_gnutls_signature( key, params->signature, params->signature_len, &gnutls_signature )))
|
||||
{
|
||||
pgnutls_pubkey_deinit( gnutls_key );
|
||||
return status;
|
||||
}
|
||||
|
||||
gnutls_hash.data = params->hash;
|
||||
gnutls_hash.size = params->hash_len;
|
||||
ret = pgnutls_pubkey_verify_hash2( gnutls_key, sign_alg, 0, &gnutls_hash, &gnutls_signature );
|
||||
ret = pgnutls_pubkey_verify_hash2( key_data(key)->a.pubkey, sign_alg, 0, &gnutls_hash, &gnutls_signature );
|
||||
|
||||
if (gnutls_signature.data != params->signature) free( gnutls_signature.data );
|
||||
pgnutls_pubkey_deinit( gnutls_key );
|
||||
return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1975,7 +1720,7 @@ static NTSTATUS key_asymmetric_sign( void *args )
|
|||
*params->ret_len = key->u.a.bitlen / 8;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
if (!key_data(key)->privkey) return STATUS_INVALID_PARAMETER;
|
||||
if (!key_data(key)->a.privkey) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
hash.data = params->input;
|
||||
hash.size = params->input_len;
|
||||
|
@ -1983,15 +1728,13 @@ static NTSTATUS key_asymmetric_sign( void *args )
|
|||
signature.data = NULL;
|
||||
signature.size = 0;
|
||||
|
||||
if ((ret = pgnutls_privkey_sign_hash( key_data(key)->privkey, hash_alg, 0, &hash, &signature )))
|
||||
if ((ret = pgnutls_privkey_sign_hash( key_data(key)->a.privkey, hash_alg, 0, &hash, &signature )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
status = format_gnutls_signature( key->alg_id, signature, params->output,
|
||||
params->output_len, params->ret_len );
|
||||
|
||||
status = format_gnutls_signature( key->alg_id, signature, params->output, params->output_len, params->ret_len );
|
||||
free( signature.data );
|
||||
return status;
|
||||
}
|
||||
|
@ -2000,7 +1743,8 @@ static NTSTATUS key_asymmetric_destroy( void *args )
|
|||
{
|
||||
struct key *key = args;
|
||||
|
||||
if (key_data(key)->privkey) pgnutls_privkey_deinit( key_data(key)->privkey );
|
||||
if (key_data(key)->a.privkey) pgnutls_privkey_deinit( key_data(key)->a.privkey );
|
||||
if (key_data(key)->a.pubkey) pgnutls_pubkey_deinit( key_data(key)->a.pubkey );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2011,9 +1755,9 @@ static NTSTATUS key_asymmetric_duplicate( void *args )
|
|||
struct key *key_copy = params->key_copy;
|
||||
int ret;
|
||||
|
||||
if (!key_data(key_orig)->privkey) return STATUS_SUCCESS;
|
||||
if (!key_data(key_orig)->a.privkey) return STATUS_SUCCESS;
|
||||
|
||||
if ((ret = pgnutls_privkey_init( &key_data(key_copy)->privkey )))
|
||||
if ((ret = pgnutls_privkey_init( &key_data(key_copy)->a.privkey )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -2025,12 +1769,12 @@ static NTSTATUS key_asymmetric_duplicate( void *args )
|
|||
case ALG_ID_RSA_SIGN:
|
||||
{
|
||||
gnutls_datum_t m, e, d, p, q, u, e1, e2;
|
||||
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
|
||||
if ((ret = pgnutls_privkey_export_rsa_raw( key_data(key_orig)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
ret = pgnutls_privkey_import_rsa_raw( key_data(key_copy)->privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
|
||||
ret = pgnutls_privkey_import_rsa_raw( key_data(key_copy)->a.privkey, &m, &e, &d, &p, &q, &u, &e1, &e2 );
|
||||
free( m.data ); free( e.data ); free( d.data ); free( p.data ); free( q.data ); free( u.data );
|
||||
free( e1.data ); free( e2.data );
|
||||
if (ret)
|
||||
|
@ -2043,12 +1787,12 @@ static NTSTATUS key_asymmetric_duplicate( void *args )
|
|||
case ALG_ID_DSA:
|
||||
{
|
||||
gnutls_datum_t p, q, g, y, x;
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->privkey, &p, &q, &g, &y, &x )))
|
||||
if ((ret = pgnutls_privkey_export_dsa_raw( key_data(key_orig)->a.privkey, &p, &q, &g, &y, &x )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
ret = pgnutls_privkey_import_dsa_raw( key_data(key_copy)->privkey, &p, &q, &g, &y, &x );
|
||||
ret = pgnutls_privkey_import_dsa_raw( key_data(key_copy)->a.privkey, &p, &q, &g, &y, &x );
|
||||
free( p.data ); free( q.data ); free( g.data ); free( y.data ); free( x.data );
|
||||
if (ret)
|
||||
{
|
||||
|
@ -2063,12 +1807,12 @@ static NTSTATUS key_asymmetric_duplicate( void *args )
|
|||
{
|
||||
gnutls_ecc_curve_t curve;
|
||||
gnutls_datum_t x, y, k;
|
||||
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->privkey, &curve, &x, &y, &k )))
|
||||
if ((ret = pgnutls_privkey_export_ecc_raw( key_data(key_orig)->a.privkey, &curve, &x, &y, &k )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
ret = pgnutls_privkey_import_ecc_raw( key_data(key_copy)->privkey, curve, &x, &y, &k );
|
||||
ret = pgnutls_privkey_import_ecc_raw( key_data(key_copy)->a.privkey, curve, &x, &y, &k );
|
||||
free( x.data ); free( y.data ); free( k.data );
|
||||
if (ret)
|
||||
{
|
||||
|
@ -2094,7 +1838,7 @@ static NTSTATUS key_asymmetric_decrypt( void *args )
|
|||
|
||||
e.data = params->input;
|
||||
e.size = params->input_len;
|
||||
if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->privkey, 0, &e, &d )))
|
||||
if ((ret = pgnutls_privkey_decrypt_data( key_data(params->key)->a.privkey, 0, &e, &d )))
|
||||
{
|
||||
pgnutls_perror( ret );
|
||||
return STATUS_INTERNAL_ERROR;
|
||||
|
@ -2187,8 +1931,6 @@ static struct key *get_asymmetric_key( struct key32 *key32, struct key *key )
|
|||
key->private[1] = key32->private[1];
|
||||
key->u.a.bitlen = key32->u.a.bitlen;
|
||||
key->u.a.flags = key32->u.a.flags;
|
||||
key->u.a.pubkey = ULongToPtr(key32->u.a.pubkey);
|
||||
key->u.a.pubkey_len = key32->u.a.pubkey_len;
|
||||
key->u.a.dss_seed = key32->u.a.dss_seed;
|
||||
return key;
|
||||
}
|
||||
|
@ -2204,7 +1946,6 @@ static void put_asymmetric_key32( struct key *key, struct key32 *key32 )
|
|||
key32->private[0] = key->private[0];
|
||||
key32->private[1] = key->private[1];
|
||||
key32->u.a.flags = key->u.a.flags;
|
||||
key32->u.a.pubkey_len = key->u.a.pubkey_len;
|
||||
key32->u.a.dss_seed = key->u.a.dss_seed;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue