bcrypt: Move public key allocation to the PE side.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
52ca433e78
commit
696255907c
|
@ -974,17 +974,15 @@ static NTSTATUS key_asymmetric_create( struct key **ret_key, struct algorithm *a
|
|||
key->hdr.magic = MAGIC_KEY;
|
||||
key->alg_id = alg->id;
|
||||
key->u.a.bitlen = bitlen;
|
||||
key->u.a.pubkey_len = pubkey_len;
|
||||
|
||||
if (pubkey_len)
|
||||
if (!(key->u.a.pubkey = heap_alloc( pubkey_len )))
|
||||
{
|
||||
if (!(key->u.a.pubkey = heap_alloc( pubkey_len )))
|
||||
{
|
||||
heap_free( key );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
memcpy( key->u.a.pubkey, pubkey, pubkey_len );
|
||||
key->u.a.pubkey_len = pubkey_len;
|
||||
heap_free( key );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
if (pubkey) memcpy( key->u.a.pubkey, pubkey, pubkey_len );
|
||||
|
||||
*ret_key = key;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -1268,11 +1266,12 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
{
|
||||
struct key *key;
|
||||
NTSTATUS status;
|
||||
ULONG size;
|
||||
|
||||
if (!wcscmp( type, BCRYPT_ECCPUBLIC_BLOB ))
|
||||
{
|
||||
BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)input;
|
||||
DWORD key_size, magic, size;
|
||||
DWORD key_size, magic;
|
||||
|
||||
if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
|
@ -1332,7 +1331,8 @@ 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;
|
||||
|
||||
if ((status = key_asymmetric_create( &key, alg, key_size * 8, NULL, 0 ))) return status;
|
||||
size = sizeof(*ecc_blob) + key_size * 2;
|
||||
if ((status = key_asymmetric_create( &key, alg, key_size * 8, NULL, size ))) return status;
|
||||
if ((status = key_funcs->key_import_ecc( key, input, input_len )))
|
||||
{
|
||||
BCryptDestroyKey( key );
|
||||
|
@ -1345,7 +1345,6 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
else if (!wcscmp( type, BCRYPT_RSAPUBLIC_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 && alg->id != ALG_ID_RSA_SIGN) || rsa_blob->Magic != BCRYPT_RSAPUBLIC_MAGIC)
|
||||
|
@ -1357,7 +1356,6 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
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)
|
||||
|
@ -1378,7 +1376,6 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
else if (!wcscmp( type, BCRYPT_DSA_PUBLIC_BLOB ))
|
||||
{
|
||||
BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)input;
|
||||
ULONG size;
|
||||
|
||||
if (input_len < sizeof(*dsa_blob)) return STATUS_INVALID_PARAMETER;
|
||||
if ((alg->id != ALG_ID_DSA) || dsa_blob->dwMagic != BCRYPT_DSA_PUBLIC_MAGIC)
|
||||
|
@ -1412,7 +1409,8 @@ 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;
|
||||
|
||||
if ((status = key_asymmetric_create( &key, alg, pubkey->bitlen, NULL, 0 ))) return status;
|
||||
size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED);
|
||||
if ((status = key_asymmetric_create( &key, alg, pubkey->bitlen, NULL, size ))) return status;
|
||||
if ((status = key_funcs->key_import_dsa_capi( key, input, input_len )))
|
||||
{
|
||||
BCryptDestroyKey( key );
|
||||
|
@ -1426,7 +1424,6 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
|
|||
{
|
||||
BLOBHEADER *hdr = (BLOBHEADER *)input;
|
||||
DSSPUBKEY *pubkey;
|
||||
ULONG size;
|
||||
|
||||
if (alg->id != ALG_ID_DSA) return STATUS_NOT_SUPPORTED;
|
||||
if (input_len < sizeof(*hdr)) return STATUS_INVALID_PARAMETER;
|
||||
|
@ -1508,6 +1505,7 @@ NTSTATUS WINAPI BCryptGenerateKeyPair( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_H
|
|||
struct algorithm *alg = algorithm;
|
||||
struct key *key;
|
||||
NTSTATUS status;
|
||||
ULONG size;
|
||||
|
||||
TRACE( "%p, %p, %u, %08x\n", algorithm, handle, key_len, flags );
|
||||
|
||||
|
@ -1518,18 +1516,25 @@ NTSTATUS WINAPI BCryptGenerateKeyPair( BCRYPT_ALG_HANDLE algorithm, BCRYPT_KEY_H
|
|||
{
|
||||
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:
|
||||
if (!(status = key_asymmetric_create( &key, alg, key_len, NULL, 0 ))) *handle = key;
|
||||
return status;
|
||||
|
||||
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, key_len, NULL, size ))) *handle = key;
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI BCryptFinalizeKeyPair( BCRYPT_KEY_HANDLE handle, ULONG flags )
|
||||
|
|
|
@ -594,9 +594,9 @@ static void export_gnutls_datum( UCHAR *buffer, ULONG length, gnutls_datum_t *d,
|
|||
memcpy( buffer + offset, src, size );
|
||||
}
|
||||
|
||||
static NTSTATUS export_gnutls_pubkey_rsa( gnutls_privkey_t gnutls_key, ULONG bitlen, UCHAR **pubkey, ULONG *pubkey_len )
|
||||
static NTSTATUS export_gnutls_pubkey_rsa( gnutls_privkey_t gnutls_key, ULONG bitlen, void *pubkey, ULONG *pubkey_len )
|
||||
{
|
||||
BCRYPT_RSAKEY_BLOB *rsa_blob;
|
||||
BCRYPT_RSAKEY_BLOB *rsa_blob = pubkey;
|
||||
gnutls_datum_t m, e;
|
||||
UCHAR *dst;
|
||||
int ret;
|
||||
|
@ -607,11 +607,12 @@ static NTSTATUS export_gnutls_pubkey_rsa( gnutls_privkey_t gnutls_key, ULONG bit
|
|||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (!(rsa_blob = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*rsa_blob) + e.size + m.size )))
|
||||
if (*pubkey_len < sizeof(*rsa_blob) + e.size + m.size)
|
||||
{
|
||||
FIXME( "wrong pubkey len %u / %u\n", *pubkey_len, (ULONG)sizeof(*rsa_blob) + e.size + m.size );
|
||||
pgnutls_perror( ret );
|
||||
free( e.data ); free( m.data );
|
||||
return STATUS_NO_MEMORY;
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
dst = (UCHAR *)(rsa_blob + 1);
|
||||
|
@ -625,17 +626,16 @@ static NTSTATUS export_gnutls_pubkey_rsa( gnutls_privkey_t gnutls_key, ULONG bit
|
|||
rsa_blob->cbPrime1 = 0;
|
||||
rsa_blob->cbPrime2 = 0;
|
||||
|
||||
*pubkey = (UCHAR *)rsa_blob;
|
||||
*pubkey_len = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
|
||||
|
||||
free( e.data ); free( m.data );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS export_gnutls_pubkey_ecc( gnutls_privkey_t gnutls_key, enum alg_id alg_id, UCHAR **pubkey,
|
||||
static NTSTATUS export_gnutls_pubkey_ecc( gnutls_privkey_t gnutls_key, enum alg_id alg_id, void *pubkey,
|
||||
ULONG *pubkey_len )
|
||||
{
|
||||
BCRYPT_ECCKEY_BLOB *ecc_blob;
|
||||
BCRYPT_ECCKEY_BLOB *ecc_blob = pubkey;
|
||||
gnutls_ecc_curve_t curve;
|
||||
gnutls_datum_t x, y;
|
||||
DWORD magic, size;
|
||||
|
@ -670,11 +670,12 @@ static NTSTATUS export_gnutls_pubkey_ecc( gnutls_privkey_t gnutls_key, enum alg_
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (!(ecc_blob = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*ecc_blob) + size * 2 )))
|
||||
if (*pubkey_len < sizeof(*ecc_blob) + size * 2)
|
||||
{
|
||||
FIXME( "wrong pubkey len %u / %u\n", *pubkey_len, (ULONG)sizeof(*ecc_blob) + size * 2 );
|
||||
pgnutls_perror( ret );
|
||||
free( x.data ); free( y.data );
|
||||
return STATUS_NO_MEMORY;
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
ecc_blob->dwMagic = magic;
|
||||
|
@ -686,16 +687,15 @@ static NTSTATUS export_gnutls_pubkey_ecc( gnutls_privkey_t gnutls_key, enum alg_
|
|||
dst += size;
|
||||
export_gnutls_datum( dst, size, &y, NULL );
|
||||
|
||||
*pubkey = (UCHAR *)ecc_blob;
|
||||
*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, UCHAR **pubkey, ULONG *pubkey_len )
|
||||
static NTSTATUS export_gnutls_pubkey_dsa( gnutls_privkey_t gnutls_key, ULONG bitlen, void *pubkey, ULONG *pubkey_len )
|
||||
{
|
||||
BCRYPT_DSA_KEY_BLOB *dsa_blob;
|
||||
BCRYPT_DSA_KEY_BLOB *dsa_blob = pubkey;
|
||||
gnutls_datum_t p, q, g, y;
|
||||
UCHAR *dst;
|
||||
int ret;
|
||||
|
@ -712,8 +712,9 @@ static NTSTATUS export_gnutls_pubkey_dsa( gnutls_privkey_t gnutls_key, ULONG bit
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (!(dsa_blob = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*dsa_blob) + bitlen / 8 * 3 )))
|
||||
if (*pubkey_len < sizeof(*dsa_blob) + bitlen / 8 * 3)
|
||||
{
|
||||
FIXME( "wrong pubkey len %u / %u\n", *pubkey_len, (ULONG)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;
|
||||
|
@ -736,7 +737,6 @@ static NTSTATUS export_gnutls_pubkey_dsa( gnutls_privkey_t gnutls_key, ULONG bit
|
|||
memset( dsa_blob->Count, 0, sizeof(dsa_blob->Count) ); /* FIXME */
|
||||
memset( dsa_blob->Seed, 0, sizeof(dsa_blob->Seed) ); /* FIXME */
|
||||
|
||||
*pubkey = (UCHAR *)dsa_blob;
|
||||
*pubkey_len = sizeof(*dsa_blob) + dsa_blob->cbKey * 3;
|
||||
|
||||
free( p.data ); free( q.data ); free( g.data ); free( y.data );
|
||||
|
@ -758,9 +758,9 @@ static void reverse_bytes( UCHAR *buf, ULONG len )
|
|||
|
||||
#define Q_SIZE 20
|
||||
static NTSTATUS export_gnutls_pubkey_dsa_capi( gnutls_privkey_t gnutls_key, const DSSSEED *seed, ULONG bitlen,
|
||||
UCHAR **pubkey, ULONG *pubkey_len )
|
||||
void *pubkey, ULONG *pubkey_len )
|
||||
{
|
||||
BLOBHEADER *hdr;
|
||||
BLOBHEADER *hdr = pubkey;
|
||||
DSSPUBKEY *dsskey;
|
||||
gnutls_datum_t p, q, g, y;
|
||||
UCHAR *dst;
|
||||
|
@ -778,8 +778,9 @@ static NTSTATUS export_gnutls_pubkey_dsa_capi( gnutls_privkey_t gnutls_key, cons
|
|||
return STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (!(hdr = RtlAllocateHeap( GetProcessHeap(), 0, size + bitlen / 8 * 3 + Q_SIZE )))
|
||||
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;
|
||||
|
@ -813,7 +814,6 @@ static NTSTATUS export_gnutls_pubkey_dsa_capi( gnutls_privkey_t gnutls_key, cons
|
|||
|
||||
memcpy( dst, seed, sizeof(*seed) );
|
||||
|
||||
*pubkey = (UCHAR *)hdr;
|
||||
*pubkey_len = size + bitlen / 8 * 3 + Q_SIZE;
|
||||
|
||||
free( p.data ); free( q.data ); free( g.data ); free( y.data );
|
||||
|
@ -870,15 +870,15 @@ static NTSTATUS CDECL key_asymmetric_generate( struct key *key )
|
|||
switch (pk_alg)
|
||||
{
|
||||
case GNUTLS_PK_RSA:
|
||||
status = export_gnutls_pubkey_rsa( handle, key->u.a.bitlen, &key->u.a.pubkey, &key->u.a.pubkey_len );
|
||||
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 );
|
||||
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 );
|
||||
status = export_gnutls_pubkey_dsa( handle, key->u.a.bitlen, key->u.a.pubkey, &key->u.a.pubkey_len );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -997,7 +997,7 @@ static NTSTATUS CDECL 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 )))
|
||||
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;
|
||||
|
@ -1158,8 +1158,8 @@ static NTSTATUS CDECL key_import_dsa_capi( struct key *key, UCHAR *buf, ULONG le
|
|||
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 )))
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue