Paul Gofman (@gofman) commented about dlls/bcrypt/gnutls.c:
- BCRYPT_DH_PARAMETER_HEADER *hdr = (BCRYPT_DH_PARAMETER_HEADER *)buf;
- unsigned int size = sizeof(*hdr) + key->u.a.bitlen / 8 * 2;
- gnutls_datum_t p, g, x;
- gnutls_dh_params_t params;
- NTSTATUS status = STATUS_SUCCESS;
- UCHAR *dst;
- int ret;
- if ((ret = pgnutls_dh_params_init( ¶ms )))
- {
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
- }
- if ((ret = pgnutls_privkey_export_dh_raw( key_data(key)->a.privkey, params, NULL, &x, 0 )))
- {
This assumes that the bcrypt key was generated. But if DH params were just imported and BCryptFinalizeKeyPair() wasn't called this will fail as privkey is not generated yet. We don't have such a test, but I just tested BCryptGetProperty(BCRYPT_DH_PARAMETERS) right after BCryptSetProperty(BCRYPT_DH_PARAMETERS) and before BCryptFinalizeKeyPair() and that succeeds on Windows while fails with the patch.
I guess one way to do it straightforward is to store gnutls_dh_params_t handle in key data as I suggested above and export from it. Then, full key generation without DH parameters set will generate it first, and whatever happened (just setting the parameters or full DH key generation) this will work without extra checks.