Santino Mazza : ncrypt: Implement NCryptImportKey function.

Alexandre Julliard julliard at winehq.org
Wed Feb 16 15:30:25 CST 2022


Module: wine
Branch: master
Commit: 2252613aba4ebce74442e8c303df68b324f10d8d
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2252613aba4ebce74442e8c303df68b324f10d8d

Author: Santino Mazza <mazzasantino1206 at gmail.com>
Date:   Wed Feb 16 15:13:05 2022 +0100

ncrypt: Implement NCryptImportKey function.

Signed-off-by: Santino Mazza <mazzasantino1206 at gmail.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ncrypt/main.c            | 116 +++++++++++++++++++++++++++++++++++-------
 dlls/ncrypt/ncrypt_internal.h |  31 +++++++++++
 dlls/ncrypt/tests/ncrypt.c    |   2 -
 3 files changed, 128 insertions(+), 21 deletions(-)

diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c
index 44cfe781e7c..0d5a40b7b26 100644
--- a/dlls/ncrypt/main.c
+++ b/dlls/ncrypt/main.c
@@ -24,17 +24,17 @@
 #include "windef.h"
 #include "winbase.h"
 #include "ncrypt.h"
+#include "bcrypt.h"
 #include "ncrypt_internal.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ncrypt);
 
 SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE *key,
-                                                const WCHAR *algid, const WCHAR *name, DWORD keyspec,
-                                                DWORD flags)
+                                                const WCHAR *algid, const WCHAR *name, DWORD keyspec, DWORD flags)
 {
     FIXME("(0x%lx, %p, %s, %s, 0x%08x, 0x%08x): stub\n", provider, key, wine_dbgstr_w(algid),
-                                                         wine_dbgstr_w(name), keyspec, flags);
+          wine_dbgstr_w(name), keyspec, flags);
     return NTE_NOT_SUPPORTED;
 }
 
@@ -42,7 +42,7 @@ SECURITY_STATUS WINAPI NCryptDecrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD i
                                      BYTE *output, DWORD outsize, DWORD *result, DWORD flags)
 {
     FIXME("(0x%lx, %p, %u, %p, %p, %u, %p, 0x%08x): stub\n", key, input, insize, padding,
-                                                             output, outsize, result, flags);
+          output, outsize, result, flags);
     return NTE_NOT_SUPPORTED;
 }
 
@@ -56,13 +56,12 @@ SECURITY_STATUS WINAPI NCryptEncrypt(NCRYPT_KEY_HANDLE key, BYTE *input, DWORD i
                                      BYTE *output, DWORD outsize, DWORD *result, DWORD flags)
 {
     FIXME("(0x%lx, %p, %u, %p, %p, %u, %p, 0x%08x): stub\n", key, input, insize, padding,
-                                                             output, outsize, result, flags);
+          output, outsize, result, flags);
     return NTE_NOT_SUPPORTED;
 }
 
 SECURITY_STATUS WINAPI NCryptEnumAlgorithms(NCRYPT_PROV_HANDLE provider, DWORD alg_ops,
-                                            DWORD *alg_count, NCryptAlgorithmName **alg_list,
-                                            DWORD flags)
+                                            DWORD *alg_count, NCryptAlgorithmName **alg_list, DWORD flags)
 {
     FIXME("(0x%lx, 0x%08x, %p, %p, 0x%08x): stub\n", provider, alg_ops, alg_count, alg_list, flags);
     return NTE_NOT_SUPPORTED;
@@ -96,8 +95,7 @@ SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE object)
 SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE object, const WCHAR *property, PBYTE output,
                                          DWORD outsize, DWORD *result, DWORD flags)
 {
-    FIXME("(0x%lx, %s, %p, %u, %p, 0x%08x): stub\n", object, wine_dbgstr_w(property), output, outsize,
-                                                         result, flags);
+    FIXME("(0x%lx, %s, %p, %u, %p, 0x%08x): stub\n", object, wine_dbgstr_w(property), output, outsize, result, flags);
     return NTE_NOT_SUPPORTED;
 }
 
@@ -110,17 +108,98 @@ static struct object *allocate_object(enum object_type type)
 }
 
 SECURITY_STATUS WINAPI NCryptImportKey(NCRYPT_PROV_HANDLE provider, NCRYPT_KEY_HANDLE decrypt_key,
-                                       const WCHAR *type, NCryptBufferDesc *params, NCRYPT_KEY_HANDLE *key,
-                                       PBYTE data, DWORD datasize, DWORD flags)
+                                       const WCHAR *type, NCryptBufferDesc *params, NCRYPT_KEY_HANDLE *handle,
+                                       BYTE *data, DWORD datasize, DWORD flags)
 {
-    FIXME("(0x%lx, 0x%lx, %s, %p, %p, %p, %u, 0x%08x): stub\n", provider, decrypt_key,
-                                                                wine_dbgstr_w(type), params,
-                                                                key, data, datasize, flags);
-    return NTE_NOT_SUPPORTED;
+    BCRYPT_KEY_BLOB *header = (BCRYPT_KEY_BLOB *)data;
+
+    TRACE("(0x%lx, 0x%lx, %s, %p, %p, %p, %u, 0x%08x): stub\n", provider, decrypt_key, wine_dbgstr_w(type),
+          params, handle, data, datasize, flags);
+
+    if (decrypt_key)
+    {
+        FIXME("Key blob decryption not implemented\n");
+        return NTE_NOT_SUPPORTED;
+    }
+    if (params)
+    {
+        FIXME("Parameter information not implemented\n");
+        return NTE_NOT_SUPPORTED;
+    }
+    if (flags == NCRYPT_SILENT_FLAG)
+    {
+        FIXME("Silent flag not implemented\n");
+    }
+    else if (flags)
+    {
+        ERR("Invalid flags 0x%x\n", flags);
+        return NTE_BAD_FLAGS;
+    }
+
+    switch (header->Magic)
+    {
+    case BCRYPT_RSAPUBLIC_MAGIC:
+    {
+        DWORD expected_size;
+        struct object *object;
+        struct key *key;
+        BYTE *public_exp, *modulus;
+        BCRYPT_RSAKEY_BLOB *rsaheader = (BCRYPT_RSAKEY_BLOB *)data;
+
+        if (datasize < sizeof(*rsaheader))
+        {
+            ERR("Invalid buffer size.\n");
+            return NTE_BAD_DATA;
+        }
+
+        expected_size = sizeof(*rsaheader) + rsaheader->cbPublicExp + rsaheader->cbModulus;
+        if (datasize != expected_size)
+        {
+            ERR("Invalid buffer size.\n");
+            return NTE_BAD_DATA;
+        }
+
+        if (!(object = allocate_object(KEY)))
+        {
+            ERR("Error allocating memory.\n");
+            return NTE_NO_MEMORY;
+        }
+
+        key = &object->key;
+        key->alg = RSA;
+        key->rsa.public_exp_size = rsaheader->cbPublicExp;
+        key->rsa.modulus_size = rsaheader->cbModulus;
+        if (!(key->rsa.public_exp = malloc(rsaheader->cbPublicExp)))
+        {
+            ERR("Error allocating memory.\n");
+            free(object);
+            return NTE_NO_MEMORY;
+        }
+        if (!(key->rsa.modulus = malloc(rsaheader->cbModulus)))
+        {
+            ERR("Error allocating memory.\n");
+            free(key->rsa.public_exp);
+            free(object);
+            return NTE_NO_MEMORY;
+        }
+
+        public_exp = &data[sizeof(*rsaheader)]; /* The public exp is after the header. */
+        modulus = &public_exp[rsaheader->cbPublicExp];  /* The modulus is after the public exp. */
+        memcpy(key->rsa.public_exp, public_exp, rsaheader->cbPublicExp);
+        memcpy(key->rsa.modulus, modulus, rsaheader->cbModulus);
+
+        *handle = (NCRYPT_KEY_HANDLE)object;
+        break;
+    }
+    default:
+        FIXME("unhandled key magic %x\n", header->Magic);
+        return NTE_INVALID_PARAMETER;
+    }
+
+    return ERROR_SUCCESS;
 }
 
-SECURITY_STATUS WINAPI NCryptIsAlgSupported(NCRYPT_PROV_HANDLE provider, const WCHAR *algid,
-                                            DWORD flags)
+SECURITY_STATUS WINAPI NCryptIsAlgSupported(NCRYPT_PROV_HANDLE provider, const WCHAR *algid, DWORD flags)
 {
     FIXME("(0x%lx, %s, 0x%08x): stub\n", provider, wine_dbgstr_w(algid), flags);
     return NTE_NOT_SUPPORTED;
@@ -157,7 +236,6 @@ SECURITY_STATUS WINAPI NCryptOpenStorageProvider(NCRYPT_PROV_HANDLE *provider, c
 SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE object, const WCHAR *property,
                                          PBYTE input, DWORD insize, DWORD flags)
 {
-    FIXME("(%lx, %s, %p, %u, 0x%08x): stub\n", object, wine_dbgstr_w(property), input, insize,
-                                               flags);
+    FIXME("(%lx, %s, %p, %u, 0x%08x): stub\n", object, wine_dbgstr_w(property), input, insize, flags);
     return NTE_NOT_SUPPORTED;
 }
diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h
index 7a2d96f8417..fe5f27ea1eb 100644
--- a/dlls/ncrypt/ncrypt_internal.h
+++ b/dlls/ncrypt/ncrypt_internal.h
@@ -16,12 +16,42 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+enum key_algorithm
+{
+    DH,
+    DSA,
+    ECC,
+    RSA,
+};
+
+struct rsa_key
+{
+    DWORD public_exp_size;
+    BYTE *public_exp;
+    DWORD modulus_size;
+    BYTE *modulus;
+    DWORD prime1_size;
+    BYTE *prime1;
+    DWORD prime2_size;
+    BYTE *prime2;
+};
+
+struct key
+{
+    enum key_algorithm alg;
+    union
+    {
+        struct rsa_key rsa;
+    };
+};
+
 struct storage_provider
 {
 };
 
 enum object_type
 {
+    KEY,
     STORAGE_PROVIDER,
 };
 
@@ -39,6 +69,7 @@ struct object
     struct object_property *properties;
     union
     {
+        struct key key;
         struct storage_provider storage_provider;
     };
 };
diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c
index 06551ab3a94..68b893282c2 100644
--- a/dlls/ncrypt/tests/ncrypt.c
+++ b/dlls/ncrypt/tests/ncrypt.c
@@ -97,7 +97,6 @@ static void test_key_import_rsa(void)
     ok(ret == ERROR_SUCCESS, "got %#lx\n", ret);
     ok(prov, "got null handle\n");
 
-    todo_wine {
     key = 0;
     ret = NCryptImportKey(prov, 0, BCRYPT_RSAPUBLIC_BLOB, NULL, &key, rsa_key_blob, sizeof(rsa_key_blob), 0);
     ok(ret == ERROR_SUCCESS, "got %#lx\n", ret);
@@ -135,7 +134,6 @@ static void test_key_import_rsa(void)
     ok(ret == NTE_BAD_DATA, "got %#lx\n", ret);
 
     NCryptFreeObject(prov);
-    }
 }
 
 START_TEST(ncrypt)




More information about the wine-cvs mailing list