[PATCH v2] bcrypt: Add support for PUBLICKEY blob types.

Santino Mazza mazzasantino1206 at gmail.com
Thu Mar 3 21:49:10 CST 2022


Signed-off-by: Santino Mazza <mazzasantino1206 at gmail.com>
---
 dlls/bcrypt/bcrypt_main.c  | 398 ++++++++++++++++++++++---------------
 dlls/bcrypt/tests/bcrypt.c |  12 ++
 2 files changed, 255 insertions(+), 155 deletions(-)

diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 9fb9b6adf87..2ef67bc3024 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -1318,207 +1318,295 @@ static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG inpu
     return status;
 }
 
-static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
-                                 ULONG input_len )
+static NTSTATUS key_import_ecc_public( struct algorithm *alg, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
+                                       ULONG input_len )
 {
-    struct key_import_params params;
-    struct key *key;
-    NTSTATUS status;
+    BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)input;
+    DWORD key_size, magic;
     ULONG size;
 
-    if (!wcscmp( type, BCRYPT_ECCPUBLIC_BLOB ))
+    if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER;
+
+    switch (alg->id)
     {
-        BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)input;
-        DWORD key_size, magic;
+    case ALG_ID_ECDH_P256:
+        key_size = 32;
+        magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
+        break;
 
-        if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER;
+    case ALG_ID_ECDSA_P256:
+        key_size = 32;
+        magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
+        break;
 
-        switch (alg->id)
-        {
-        case ALG_ID_ECDH_P256:
-            key_size = 32;
-            magic = BCRYPT_ECDH_PUBLIC_P256_MAGIC;
-            break;
+    case ALG_ID_ECDSA_P384:
+        key_size = 48;
+        magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
+        break;
 
-        case ALG_ID_ECDSA_P256:
-            key_size = 32;
-            magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
-            break;
+    default:
+        FIXME( "algorithm %u does not yet support importing blob of type %s\n", alg->id, debugstr_w(BCRYPT_ECCPUBLIC_BLOB) );
+        return STATUS_NOT_SUPPORTED;
+    }
 
-        case ALG_ID_ECDSA_P384:
-            key_size = 48;
-            magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
-            break;
+    if (ecc_blob->dwMagic != magic) return STATUS_INVALID_PARAMETER;
+    if (ecc_blob->cbKey != key_size || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 2)
+        return STATUS_INVALID_PARAMETER;
 
-        default:
-            FIXME( "algorithm %u does not yet support importing blob of type %s\n", alg->id, debugstr_w(type) );
-            return STATUS_NOT_SUPPORTED;
-        }
+    size = sizeof(*ecc_blob) + ecc_blob->cbKey * 2;
+    return key_asymmetric_create( (struct key **)ret_key, alg, key_size * 8, (BYTE *)ecc_blob, size );
+}
 
-        if (ecc_blob->dwMagic != magic) return STATUS_INVALID_PARAMETER;
-        if (ecc_blob->cbKey != key_size || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 2)
-            return STATUS_INVALID_PARAMETER;
+static NTSTATUS key_import_ecc_private( struct algorithm *alg, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
+                                        ULONG input_len )
+{
+    struct key_import_params params;
+    struct key *key;
+    BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)input;
+    DWORD key_size, magic;
+    NTSTATUS status;
+    DWORD size;
+
+    if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER;
+
+    switch (alg->id)
+    {
+    case ALG_ID_ECDH_P256:
+        key_size = 32;
+        magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
+        break;
+    case ALG_ID_ECDSA_P256:
+        key_size = 32;
+        magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
+        break;
 
-        size = sizeof(*ecc_blob) + ecc_blob->cbKey * 2;
-        return key_asymmetric_create( (struct key **)ret_key, alg, key_size * 8, (BYTE *)ecc_blob, size );
+    default:
+        FIXME( "algorithm %u does not yet support importing blob of type %s\n", alg->id, debugstr_w(BCRYPT_ECCPUBLIC_BLOB) );
+        return STATUS_NOT_SUPPORTED;
     }
-    else if (!wcscmp( type, BCRYPT_ECCPRIVATE_BLOB ))
+
+    if (ecc_blob->dwMagic != magic) return STATUS_INVALID_PARAMETER;
+    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, key_size * 8, NULL, size ))) return status;
+
+    params.key = key;
+    params.buf = input;
+    params.len = input_len;
+    if ((status = UNIX_CALL( key_import_ecc, &params )))
     {
-        BCRYPT_ECCKEY_BLOB *ecc_blob = (BCRYPT_ECCKEY_BLOB *)input;
-        DWORD key_size, magic;
+        BCryptDestroyKey( key );
+        return status;
+    }
 
-        if (input_len < sizeof(*ecc_blob)) return STATUS_INVALID_PARAMETER;
+    *ret_key = key;
+    return STATUS_SUCCESS;
+}
 
-        switch (alg->id)
-        {
-        case ALG_ID_ECDH_P256:
-            key_size = 32;
-            magic = BCRYPT_ECDH_PRIVATE_P256_MAGIC;
-            break;
-        case ALG_ID_ECDSA_P256:
-            key_size = 32;
-            magic = BCRYPT_ECDSA_PRIVATE_P256_MAGIC;
-            break;
+static NTSTATUS key_import_rsa_public( struct algorithm *alg, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
+                                       ULONG input_len )
+{
+    BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
+    DWORD size;
 
-        default:
-            FIXME( "algorithm %u does not yet support importing blob of type %s\n", alg->id, debugstr_w(type) );
-            return STATUS_NOT_SUPPORTED;
-        }
+    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)
+        return STATUS_NOT_SUPPORTED;
 
-        if (ecc_blob->dwMagic != magic) return STATUS_INVALID_PARAMETER;
-        if (ecc_blob->cbKey != key_size || input_len < sizeof(*ecc_blob) + ecc_blob->cbKey * 3)
-            return STATUS_INVALID_PARAMETER;
+    size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
+    return key_asymmetric_create( (struct key **)ret_key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size );
+}
 
-        size = sizeof(*ecc_blob) + key_size * 2;
-        if ((status = key_asymmetric_create( &key, alg, key_size * 8, NULL, size ))) return status;
+static NTSTATUS key_import_rsa_private( struct algorithm *alg, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
+                                        ULONG input_len )
+{
+    BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
+    struct key_import_params params;
+    struct key *key;
+    NTSTATUS status;
+    DWORD size;
 
-        params.key = key;
-        params.buf = input;
-        params.len = input_len;
-        if ((status = UNIX_CALL( key_import_ecc, &params )))
-        {
-            BCryptDestroyKey( key );
-            return status;
-        }
+    if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER;
+    if (alg->id != ALG_ID_RSA || (rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC &&
+        rsa_blob->Magic != BCRYPT_RSAFULLPRIVATE_MAGIC)) return STATUS_NOT_SUPPORTED;
 
-        *ret_key = key;
-        return STATUS_SUCCESS;
-    }
-    else if (!wcscmp( type, BCRYPT_RSAPUBLIC_BLOB ))
+    size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
+    if ((status = key_asymmetric_create( &key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size )))
+        return status;
+    params.key = key;
+    params.buf = input;
+    params.len = input_len;
+    if ((status = UNIX_CALL( key_import_rsa, &params )))
     {
-        BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
+        BCryptDestroyKey( key );
+        return status;
+    }
 
-        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)
-            return STATUS_NOT_SUPPORTED;
+    *ret_key = key;
+    return STATUS_SUCCESS;
+}
 
-        size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
-        return key_asymmetric_create( (struct key **)ret_key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size );
-    }
-    else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ) || !wcscmp( type, BCRYPT_RSAFULLPRIVATE_BLOB ))
-    {
-        BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
+static NTSTATUS key_import_dsa_public( struct algorithm *alg, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
+                                       ULONG input_len )
+{
+    BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)input;
+    DWORD size;
 
-        if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER;
-        if (alg->id != ALG_ID_RSA || (rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC &&
-            rsa_blob->Magic != BCRYPT_RSAFULLPRIVATE_MAGIC)) return STATUS_NOT_SUPPORTED;
+    if (input_len < sizeof(*dsa_blob)) return STATUS_INVALID_PARAMETER;
+    if ((alg->id != ALG_ID_DSA) || dsa_blob->dwMagic != BCRYPT_DSA_PUBLIC_MAGIC)
+        return STATUS_NOT_SUPPORTED;
 
-        size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
-        if ((status = key_asymmetric_create( &key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size )))
-            return status;
-        params.key = key;
-        params.buf = input;
-        params.len = input_len;
-        if ((status = UNIX_CALL( key_import_rsa, &params )))
-        {
-            BCryptDestroyKey( key );
-            return status;
-        }
+    size = sizeof(*dsa_blob) + dsa_blob->cbKey * 3;
+    return key_asymmetric_create( (struct key **)ret_key, alg, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size );
+}
 
-        *ret_key = key;
-        return STATUS_SUCCESS;
-    }
-    else if (!wcscmp( type, BCRYPT_DSA_PUBLIC_BLOB ))
-    {
-        BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)input;
+static NTSTATUS key_import_legacy_dsa_v2_public( struct algorithm *alg, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
+                                                 ULONG input_len )
+{
+    BLOBHEADER *hdr = (BLOBHEADER *)input;
+    DSSPUBKEY *pubkey;
+    struct key_import_params params;
+    struct key *key;
+    DWORD size;
+    NTSTATUS status;
 
-        if (input_len < sizeof(*dsa_blob)) return STATUS_INVALID_PARAMETER;
-        if ((alg->id != ALG_ID_DSA) || dsa_blob->dwMagic != BCRYPT_DSA_PUBLIC_MAGIC)
-            return STATUS_NOT_SUPPORTED;
+    if (alg->id != ALG_ID_DSA) return STATUS_NOT_SUPPORTED;
+    if (input_len < sizeof(*hdr)) return STATUS_INVALID_PARAMETER;
 
-        size = sizeof(*dsa_blob) + dsa_blob->cbKey * 3;
-        return key_asymmetric_create( (struct key **)ret_key, alg, dsa_blob->cbKey * 8, (BYTE *)dsa_blob, size );
-    }
-    else if (!wcscmp( type, LEGACY_DSA_V2_PRIVATE_BLOB ))
+    if (hdr->bType != PUBLICKEYBLOB && hdr->bVersion != 2 && hdr->aiKeyAlg != CALG_DSS_SIGN)
     {
-        BLOBHEADER *hdr = (BLOBHEADER *)input;
-        DSSPUBKEY *pubkey;
+        FIXME( "blob type %u version %u alg id %u not supported\n", hdr->bType, hdr->bVersion, hdr->aiKeyAlg );
+        return STATUS_NOT_SUPPORTED;
+    }
 
-        if (input_len < sizeof(*hdr)) return STATUS_INVALID_PARAMETER;
+    if (input_len < sizeof(*hdr) + sizeof(*pubkey)) return STATUS_INVALID_PARAMETER;
+    pubkey = (DSSPUBKEY *)(hdr + 1);
+    if (pubkey->magic != MAGIC_DSS1) return STATUS_NOT_SUPPORTED;
 
-        if (hdr->bType != PRIVATEKEYBLOB && hdr->bVersion != 2 && hdr->aiKeyAlg != CALG_DSS_SIGN)
-        {
-            FIXME( "blob type %u version %u alg id %u not supported\n", hdr->bType, hdr->bVersion, hdr->aiKeyAlg );
-            return STATUS_NOT_SUPPORTED;
-        }
-        if (alg->id != ALG_ID_DSA)
-        {
-            FIXME( "algorithm %u does not support importing blob of type %s\n", alg->id, debugstr_w(type) );
-            return STATUS_NOT_SUPPORTED;
-        }
+    size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED);
+    if (input_len < size) return STATUS_INVALID_PARAMETER;
 
-        if (input_len < sizeof(*hdr) + sizeof(*pubkey)) return STATUS_INVALID_PARAMETER;
-        pubkey = (DSSPUBKEY *)(hdr + 1);
-        if (pubkey->magic != MAGIC_DSS2) return STATUS_NOT_SUPPORTED;
+    if ((status = key_asymmetric_create( &key, alg, pubkey->bitlen, (BYTE *)hdr, size ))) return status;
+    key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
 
-        if (input_len < sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 2 + 40 + sizeof(DSSSEED))
-            return STATUS_INVALID_PARAMETER;
+    *ret_key = key;
+    return STATUS_SUCCESS;
+}
 
-        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;
+static NTSTATUS key_import_legacy_dsa_v2_private( struct algorithm *alg, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
+                                                  ULONG input_len )
+{
+    BLOBHEADER *hdr = (BLOBHEADER *)input;
+    DSSPUBKEY *pubkey;
+    struct key_import_params params;
+    struct key *key;
+    NTSTATUS status;
+    DWORD size;
 
-        params.key = key;
-        params.buf = input;
-        params.len = input_len;
-        if ((status = UNIX_CALL( key_import_dsa_capi, &params )))
-        {
-            BCryptDestroyKey( key );
-            return status;
-        }
+    if (input_len < sizeof(*hdr)) return STATUS_INVALID_PARAMETER;
 
-        *ret_key = key;
-        return STATUS_SUCCESS;
+    if (hdr->bType != PRIVATEKEYBLOB && hdr->bVersion != 2 && hdr->aiKeyAlg != CALG_DSS_SIGN)
+    {
+        FIXME( "blob type %u version %u alg id %u not supported\n", hdr->bType, hdr->bVersion, hdr->aiKeyAlg );
+        return STATUS_NOT_SUPPORTED;
     }
-    else if (!wcscmp( type, LEGACY_DSA_V2_PUBLIC_BLOB )) /* not supported on native */
+    if (alg->id != ALG_ID_DSA)
     {
-        BLOBHEADER *hdr = (BLOBHEADER *)input;
-        DSSPUBKEY *pubkey;
+        FIXME( "algorithm %u does not support importing blob of type %s\n", alg->id, debugstr_w(LEGACY_DSA_V2_PRIVATE_BLOB) );
+        return STATUS_NOT_SUPPORTED;
+    }
 
-        if (alg->id != ALG_ID_DSA) return STATUS_NOT_SUPPORTED;
-        if (input_len < sizeof(*hdr)) return STATUS_INVALID_PARAMETER;
+    if (input_len < sizeof(*hdr) + sizeof(*pubkey)) return STATUS_INVALID_PARAMETER;
+    pubkey = (DSSPUBKEY *)(hdr + 1);
+    if (pubkey->magic != MAGIC_DSS2) return STATUS_NOT_SUPPORTED;
 
-        if (hdr->bType != PUBLICKEYBLOB && hdr->bVersion != 2 && hdr->aiKeyAlg != CALG_DSS_SIGN)
-        {
-            FIXME( "blob type %u version %u alg id %u not supported\n", hdr->bType, hdr->bVersion, hdr->aiKeyAlg );
-            return STATUS_NOT_SUPPORTED;
-        }
+    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, pubkey->bitlen, NULL, size ))) return status;
 
-        if (input_len < sizeof(*hdr) + sizeof(*pubkey)) return STATUS_INVALID_PARAMETER;
-        pubkey = (DSSPUBKEY *)(hdr + 1);
-        if (pubkey->magic != MAGIC_DSS1) return STATUS_NOT_SUPPORTED;
+    params.key = key;
+    params.buf = input;
+    params.len = input_len;
+    if ((status = UNIX_CALL( key_import_dsa_capi, &params )))
+    {
+        BCryptDestroyKey( key );
+        return status;
+    }
 
-        size = sizeof(*hdr) + sizeof(*pubkey) + (pubkey->bitlen / 8) * 3 + 20 + sizeof(DSSSEED);
-        if (input_len < size) return STATUS_INVALID_PARAMETER;
+    *ret_key = key;
+    return STATUS_SUCCESS;
+}
 
-        if ((status = key_asymmetric_create( &key, alg, pubkey->bitlen, (BYTE *)hdr, size ))) return status;
-        key->u.a.flags |= KEY_FLAG_LEGACY_DSA_V2;
+static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
+                                 ULONG input_len )
+{
+    WCHAR *final_type = type;
+    NTSTATUS status;
 
-        *ret_key = key;
-        return STATUS_SUCCESS;
+    if (!wcscmp( type, BCRYPT_PUBLIC_KEY_BLOB ))
+    {
+        DWORD magic = *(DWORD *)input;
+        switch(magic)
+        {
+        case BCRYPT_ECDH_PUBLIC_P256_MAGIC:
+        case BCRYPT_ECDSA_PUBLIC_P256_MAGIC:
+        case BCRYPT_ECDSA_PUBLIC_P384_MAGIC:
+            final_type = malloc( sizeof(BCRYPT_ECCPUBLIC_BLOB) );
+            wcscpy( final_type, BCRYPT_ECCPUBLIC_BLOB );
+            break;
+        case BCRYPT_RSAPUBLIC_MAGIC:
+            final_type = malloc( sizeof(BCRYPT_RSAPUBLIC_BLOB) );
+            wcscpy( final_type, BCRYPT_RSAPUBLIC_BLOB );
+            break;
+        default:
+        {
+            FIXME( "Unsupported key magic %#lx\n", magic );
+            return STATUS_NOT_SUPPORTED;
+        }
+        }
     }
 
-    FIXME( "unsupported key type %s\n", debugstr_w(type) );
-    return STATUS_NOT_SUPPORTED;
+    if (!wcscmp( final_type, BCRYPT_ECCPUBLIC_BLOB ))
+    {
+        status = key_import_ecc_public( alg, ret_key, input, input_len );
+    }
+    else if (!wcscmp( final_type, BCRYPT_ECCPRIVATE_BLOB ))
+    {
+        status = key_import_ecc_private( alg, ret_key, input, input_len );
+    }
+    else if (!wcscmp( final_type, BCRYPT_RSAPUBLIC_BLOB ))
+    {
+        status = key_import_rsa_public(alg, ret_key, input, input_len);
+    }
+    else if (!wcscmp( final_type, BCRYPT_RSAPRIVATE_BLOB ) || !wcscmp( type, BCRYPT_RSAFULLPRIVATE_BLOB ))
+    {
+        status = key_import_rsa_private( alg, ret_key, input, input_len );
+    }
+    else if (!wcscmp( final_type, BCRYPT_DSA_PUBLIC_BLOB ))
+    {
+        status = key_import_dsa_public( alg, ret_key, input, input_len );
+    }
+    else if (!wcscmp( final_type, LEGACY_DSA_V2_PRIVATE_BLOB ))
+    {
+        status = key_import_legacy_dsa_v2_private( alg, ret_key, input, input_len );
+    }
+    else if (!wcscmp( final_type, LEGACY_DSA_V2_PUBLIC_BLOB )) /* not supported on native */
+    {
+        status = key_import_legacy_dsa_v2_public( alg, ret_key, input, input_len );
+    }
+    else
+    {
+        FIXME( "unsupported key type %s\n", debugstr_w(type) );
+        return STATUS_NOT_SUPPORTED;
+    }
+
+    if (!wcscmp( type, BCRYPT_PUBLIC_KEY_BLOB )) free(final_type);
+
+    return status;
 }
 
 static ULONG get_block_size( struct algorithm *alg )
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
index e7619897cfd..6fc4097492b 100644
--- a/dlls/bcrypt/tests/bcrypt.c
+++ b/dlls/bcrypt/tests/bcrypt.c
@@ -1845,6 +1845,10 @@ static void test_ECDSA(void)
 
     ecckey->dwMagic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
     ecckey->cbKey = 32;
+    status = BCryptImportKeyPair(alg, NULL, BCRYPT_PUBLIC_KEY_BLOB, &key, buffer, size, 0);
+    ok(!status, "BCryptImportKeyPair failed: %#lx\n", status);
+    BCryptDestroyKey(key);
+
     status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &key, buffer, size, 0);
     ok(!status, "BCryptImportKeyPair failed: %#lx\n", status);
 
@@ -1997,6 +2001,10 @@ static void test_RSA(void)
     ok(schemes, "schemes not set\n");
     ok(size == sizeof(schemes), "got %lu\n", size);
 
+    ret = BCryptImportKeyPair(alg, NULL, BCRYPT_PUBLIC_KEY_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0);
+    ok(!ret, "BCryptImportKeyPair failed: %#lx\n", ret);
+    BCryptDestroyKey(key);
+
     ret = BCryptImportKeyPair(alg, NULL, BCRYPT_RSAPUBLIC_BLOB, &key, rsaPublicBlob, sizeof(rsaPublicBlob), 0);
     ok(!ret, "BCryptImportKeyPair failed: %#lx\n", ret);
 
@@ -2317,6 +2325,10 @@ static void test_ECDH(void)
     ok(ecckey->cbKey == 32, "got %lu\n", ecckey->cbKey);
     ok(size == sizeof(*ecckey) + ecckey->cbKey * 2, "got %lu\n", size);
 
+    status = BCryptImportKeyPair(alg, NULL, BCRYPT_PUBLIC_KEY_BLOB, &pubkey, buf, size, 0);
+    ok(status == STATUS_SUCCESS, "got %#lx\n", status);
+    BCryptDestroyKey(pubkey);
+
     status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, &pubkey, buf, size, 0);
     ok(status == STATUS_SUCCESS, "got %#lx\n", status);
     HeapFree(GetProcessHeap(), 0, buf);
-- 
2.32.0




More information about the wine-devel mailing list