Signed-off-by: Hans Leidekker hans@codeweavers.com --- dlls/bcrypt/bcrypt_internal.h | 2 - dlls/bcrypt/bcrypt_main.c | 68 +---- dlls/bcrypt/gnutls.c | 481 ++++++++-------------------------- 3 files changed, 125 insertions(+), 426 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h index 7342b66479a..d57819f2ec6 100644 --- a/dlls/bcrypt/bcrypt_internal.h +++ b/dlls/bcrypt/bcrypt_internal.h @@ -175,8 +175,6 @@ struct key_asymmetric { ULONG bitlen; /* ignored for ECC keys */ unsigned flags; - UCHAR *pubkey; - unsigned pubkey_len; DSSSEED dss_seed; };
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c index 23f30833235..2ffeff66d7b 100644 --- a/dlls/bcrypt/bcrypt_main.c +++ b/dlls/bcrypt/bcrypt_main.c @@ -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; diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c index 28119fc9e78..6a55c84efef 100644 --- a/dlls/bcrypt/gnutls.c +++ b/dlls/bcrypt/gnutls.c @@ -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 (status) + if ((ret = pgnutls_pubkey_import_privkey( pubkey, privkey, 0, 0 ))) { - pgnutls_privkey_deinit( handle ); - return status; + pgnutls_perror( ret ); + pgnutls_privkey_deinit( privkey ); + pgnutls_pubkey_deinit( pubkey ); + return STATUS_INTERNAL_ERROR; }
- 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; }