[PATCH v3 2/5] ncrypt: Implement NCryptImportKey function.

Santino Mazza mazzasantino1206 at gmail.com
Tue Feb 15 12:43:12 CST 2022


Signed-off-by: Santino Mazza <mazzasantino1206 at gmail.com>
---
 dlls/ncrypt/main.c            | 116 +++++++++++++++++++++++++++++++---
 dlls/ncrypt/ncrypt_internal.h |  37 +++++++++++
 dlls/ncrypt/tests/ncrypt.c    |   2 -
 3 files changed, 143 insertions(+), 12 deletions(-)

diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c
index 7f844bf9e85..e82faa2c6d2 100644
--- a/dlls/ncrypt/main.c
+++ b/dlls/ncrypt/main.c
@@ -19,10 +19,12 @@
  */
 
 #include <stdarg.h>
+#include <stdlib.h>
 
 #include "windef.h"
 #include "winbase.h"
 #include "ncrypt.h"
+#include "bcrypt.h"
 #include "ncrypt_internal.h"
 #include "wine/debug.h"
 
@@ -33,7 +35,7 @@ SECURITY_STATUS WINAPI NCryptCreatePersistedKey(NCRYPT_PROV_HANDLE provider, NCR
                                                 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;
 }
 
@@ -41,7 +43,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;
 }
 
@@ -55,7 +57,7 @@ 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;
 }
 
@@ -96,18 +98,112 @@ SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE object, const WCHAR *prop
                                          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);
+          result, flags);
     return NTE_NOT_SUPPORTED;
 }
 
+int allocate_key_object(struct ncrypt_object **keyobject)
+{
+    *keyobject = malloc(sizeof(struct ncrypt_object));
+    if (keyobject == NULL)
+    {
+        ERR("Error allocating memory.\n");
+        return NTE_NO_MEMORY;
+    }
+    memset(*keyobject, 0, sizeof(struct ncrypt_object));
+    (*keyobject)->type = KEY;
+    return ERROR_SUCCESS;
+}
+
 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)
+                                       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 *keyheader = (BCRYPT_KEY_BLOB *)data;
+
+    if (decrypt_key != 0)
+    {
+        FIXME("Key blob decryption not implemented\n");
+        return NTE_NOT_SUPPORTED;
+    }
+
+    if (params != NULL)
+    {
+        FIXME("Parameter information not implemented\n");
+        return NTE_NOT_SUPPORTED;
+    }
+
+    if (flags == NCRYPT_SILENT_FLAG)
+    {
+        FIXME("Silent flag not implemented\n");
+    }
+    else if (flags != 0)
+    {
+        ERR("Invalid flags 0x%x\n", flags);
+        return NTE_BAD_FLAGS;
+    }
+
+    switch (keyheader->Magic)
+    {
+    case BCRYPT_RSAPUBLIC_MAGIC:
+    {
+        int ret;
+        DWORD expected_size;
+        struct ncrypt_object *rsakeyobject;
+        struct ncrypt_key_object *rsakey;
+        BYTE *public_exp;
+        BYTE *modulus;
+        BCRYPT_RSAKEY_BLOB *rsaheader = (BCRYPT_RSAKEY_BLOB *)data;
+
+        if (datasize < sizeof(BCRYPT_RSAKEY_BLOB))
+        {
+            ERR("Invalid buffer size.\n");
+            return NTE_BAD_DATA;
+        }
+
+        expected_size = sizeof(BCRYPT_RSAKEY_BLOB) + rsaheader->cbPublicExp + rsaheader->cbModulus;
+        if (datasize != expected_size)
+        {
+            ERR("Invalid buffer size.\n");
+            return NTE_BAD_DATA;
+        }
+
+        ret = allocate_key_object(&rsakeyobject);
+        if (ret != ERROR_SUCCESS)
+            return ret;
+
+        rsakey = &rsakeyobject->object.key;
+        rsakey->algtype = RSA;
+        rsakey->payload.rsa_key.public_exp_size = rsaheader->cbPublicExp;
+        rsakey->payload.rsa_key.modulus_size = rsaheader->cbModulus;
+        rsakey->payload.rsa_key.public_exp = malloc(rsaheader->cbPublicExp);
+        if (rsakey->payload.rsa_key.public_exp == NULL)
+        {
+            ERR("Error allocating memory.\n");
+            return NTE_NO_MEMORY;
+        }
+        rsakey->payload.rsa_key.modulus = malloc(rsaheader->cbModulus);
+        if (rsakey->payload.rsa_key.modulus == NULL)
+        {
+            ERR("Error allocating memory.\n");
+            return NTE_NO_MEMORY;
+        }
+
+        public_exp = &data[sizeof(BCRYPT_RSAKEY_BLOB)]; /* The public exp its after the header. */
+        modulus = &public_exp[rsaheader->cbPublicExp];  /* The modulus its after the public exp. */
+        memcpy(rsakey->payload.rsa_key.public_exp, public_exp, rsaheader->cbPublicExp);
+        memcpy(rsakey->payload.rsa_key.modulus, modulus, rsaheader->cbModulus);
+
+        *key = (NCRYPT_KEY_HANDLE)rsakeyobject;
+    }
+    break;
+
+    default:
+        ERR("Invalid key magic %x\n", keyheader->Magic);
+        return NTE_INVALID_PARAMETER;
+    }
+
+    return ERROR_SUCCESS;
 }
 
 SECURITY_STATUS WINAPI NCryptIsAlgSupported(NCRYPT_PROV_HANDLE provider, const WCHAR *algid,
@@ -153,6 +249,6 @@ SECURITY_STATUS WINAPI NCryptSetProperty(NCRYPT_HANDLE object, const WCHAR *prop
                                          PBYTE input, DWORD insize, DWORD flags)
 {
     FIXME("(%lx, %s, %p, %u, 0x%08x): stub\n", object, wine_dbgstr_w(property), input, insize,
-                                               flags);
+          flags);
     return NTE_NOT_SUPPORTED;
 }
diff --git a/dlls/ncrypt/ncrypt_internal.h b/dlls/ncrypt/ncrypt_internal.h
index 1201cdd857a..0948d84925e 100644
--- a/dlls/ncrypt/ncrypt_internal.h
+++ b/dlls/ncrypt/ncrypt_internal.h
@@ -25,6 +25,41 @@
 #include "winbase.h"
 #include "winternl.h"
 
+enum asymmetric_key_type
+{
+    PUBLIC,
+    PRIVATE,
+};
+
+enum key_algorithm_type
+{
+    DH,
+    DSA,
+    ECC,
+    RSA,
+};
+
+struct ncrypt_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 ncrypt_key_object
+{
+    enum key_algorithm_type algtype;
+    union
+    {
+        struct ncrypt_rsa_key rsa_key;
+    } payload;
+};
+
 struct ncrypt_storage_provider_object
 {
     // FIXME Stub
@@ -32,6 +67,7 @@ struct ncrypt_storage_provider_object
 
 enum ncrypt_object_type
 {
+    KEY,
     STORAGE_PROVIDER,
 };
 
@@ -49,6 +85,7 @@ struct ncrypt_object
     struct ncrypt_object_property *properties;
     union
     {
+        struct ncrypt_key_object key;
         struct ncrypt_storage_provider_object storage_provider;
     } object;
 };
diff --git a/dlls/ncrypt/tests/ncrypt.c b/dlls/ncrypt/tests/ncrypt.c
index 76e5396b288..eecd44a7ceb 100644
--- a/dlls/ncrypt/tests/ncrypt.c
+++ b/dlls/ncrypt/tests/ncrypt.c
@@ -90,7 +90,6 @@ static void test_key_import_rsa(void)
     SECURITY_STATUS ret = NCryptOpenStorageProvider(&prov, NULL, 0);
     ok(ret == ERROR_SUCCESS, "got 0x%x\n", ret);
 
-    todo_wine {
     NCRYPT_KEY_HANDLE key = NULL;
     ret = NCryptImportKey(prov, NULL, BCRYPT_RSAPUBLIC_BLOB, NULL, &key, rsa_key_blob, sizeof(rsa_key_blob), 0);
     ok(ret == ERROR_SUCCESS, "got 0x%x\n", ret);
@@ -124,7 +123,6 @@ static void test_key_import_rsa(void)
     ok(ret == NTE_BAD_DATA, "got 0x%x\n", ret);
 
     NCryptFreeObject(prov);
-    }
 }
 
 START_TEST(ncrypt)
-- 
2.32.0




More information about the wine-devel mailing list