https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e5fcda922b0ad049f22815a6ea1258205fa17927

commit e5fcda922b0ad049f22815a6ea1258205fa17927
Author:     Eric Kohl <[email protected]>
AuthorDate: Tue Sep 18 21:33:29 2018 +0200
Commit:     Eric Kohl <[email protected]>
CommitDate: Tue Sep 18 21:33:29 2018 +0200

    [ADVAPI32][SERVICES] Pass encrypted passwords to the service manager.
    
    - Encrypt passwords before passing them to the service manager. Right now, 
we are using a fixed encryption key. This will be fixed later.
    - Replace the calls to ZeroMemory which are used to wipe the password 
buffers by calls to SecureZeroMemory.
---
 base/system/services/config.c    | 58 +++++++++++++++++++++++++++++++---
 dll/win32/advapi32/service/scm.c | 67 +++++++++++++++++++++++++++++++---------
 2 files changed, 106 insertions(+), 19 deletions(-)

diff --git a/base/system/services/config.c b/base/system/services/config.c
index 14af8e5b0f..4d1f2471c6 100644
--- a/base/system/services/config.c
+++ b/base/system/services/config.c
@@ -15,6 +15,20 @@
 #define NDEBUG
 #include <debug.h>
 
+struct ustring
+{
+    DWORD Length;
+    DWORD MaximumLength;
+    unsigned char *Buffer;
+};
+
+NTSTATUS
+WINAPI
+SystemFunction005(
+    const struct ustring *in,
+    const struct ustring *key,
+    struct ustring *out);
+
 
 /* FUNCTIONS *****************************************************************/
 
@@ -684,17 +698,51 @@ ScmDecryptPassword(
     _In_ DWORD dwPasswordSize,
     _Out_ PWSTR *pClearTextPassword)
 {
+    struct ustring inData, keyData, outData;
+    PCHAR pszKey = "TestEncryptionKey";
     PWSTR pBuffer;
+    NTSTATUS Status;
+
+    inData.Length = dwPasswordSize;
+    inData.MaximumLength = inData.Length;
+    inData.Buffer = pPassword;
+
+    keyData.Length = strlen(pszKey);
+    keyData.MaximumLength = keyData.Length;
+    keyData.Buffer = (unsigned char *)pszKey;
+
+    outData.Length = 0;
+    outData.MaximumLength = 0;
+    outData.Buffer = NULL;
+
+    /* Get the required buffer size */
+    Status = SystemFunction005(&inData,
+                               &keyData,
+                               &outData);
+    if (Status != STATUS_BUFFER_TOO_SMALL)
+    {
+        DPRINT1("SystemFunction005 failed (Status 0x%08lx)\n", Status);
+        return RtlNtStatusToDosError(Status);
+    }
 
-    /* Allocate a buffer for the decrypted password */
-    pBuffer = HeapAlloc(GetProcessHeap(), 0, dwPasswordSize);
+    /* Allocate a buffer for the clear text password */
+    pBuffer = HeapAlloc(GetProcessHeap(), 0, outData.Length);
     if (pBuffer == NULL)
         return ERROR_OUTOFMEMORY;
 
+    outData.MaximumLength = outData.Length;
+    outData.Buffer = (unsigned char *)pBuffer;
+
     /* Decrypt the password */
-    CopyMemory(pBuffer,
-               pPassword,
-               dwPasswordSize);
+    Status = SystemFunction005(&inData,
+                               &keyData,
+                               &outData);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("SystemFunction005 failed (Status 0x%08lx)\n", Status);
+        HeapFree(GetProcessHeap(), 0, pBuffer);
+        return RtlNtStatusToDosError(Status);
+    }
 
     *pClearTextPassword = pBuffer;
 
diff --git a/dll/win32/advapi32/service/scm.c b/dll/win32/advapi32/service/scm.c
index 022864bba9..efa19f2b35 100644
--- a/dll/win32/advapi32/service/scm.c
+++ b/dll/win32/advapi32/service/scm.c
@@ -12,6 +12,12 @@
 #include <advapi32.h>
 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 
+NTSTATUS
+WINAPI
+SystemFunction004(
+    const struct ustring *in,
+    const struct ustring *key,
+    struct ustring *out);
 
 /* FUNCTIONS *****************************************************************/
 
@@ -162,21 +168,54 @@ ScmEncryptPassword(
     _Out_ PBYTE *pEncryptedPassword,
     _Out_ PDWORD pEncryptedPasswordSize)
 {
-    DWORD dwSize;
+    struct ustring inData, keyData, outData;
+    PCHAR pszKey = "TestEncryptionKey";
     PBYTE pBuffer;
+    NTSTATUS Status;
+
+    inData.Length = (wcslen(pClearTextPassword) + 1) * sizeof(WCHAR);
+    inData.MaximumLength = inData.Length;
+    inData.Buffer = (unsigned char *)pClearTextPassword;
+
+    keyData.Length = strlen(pszKey);
+    keyData.MaximumLength = keyData.Length;
+    keyData.Buffer = (unsigned char *)pszKey;
 
-    dwSize = (wcslen(pClearTextPassword) + 1) * sizeof(WCHAR);
+    outData.Length = 0;
+    outData.MaximumLength = 0;
+    outData.Buffer = NULL;
 
-    pBuffer = HeapAlloc(GetProcessHeap(), 0, dwSize);
+    /* Get the required buffer size */
+    Status = SystemFunction004(&inData,
+                               &keyData,
+                               &outData);
+    if (Status != STATUS_BUFFER_TOO_SMALL)
+    {
+        ERR("SystemFunction004 failed (Status 0x%08lx)\n", Status);
+        return RtlNtStatusToDosError(Status);
+    }
+
+    /* Allocate a buffer for the encrypted password */
+    pBuffer = HeapAlloc(GetProcessHeap(), 0, outData.Length);
     if (pBuffer == NULL)
         return ERROR_OUTOFMEMORY;
 
-    CopyMemory(pBuffer,
-               pClearTextPassword,
-               dwSize);
+    outData.MaximumLength = outData.Length;
+    outData.Buffer = pBuffer;
+
+    /* Encrypt the password */
+    Status = SystemFunction004(&inData,
+                               &keyData,
+                               &outData);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("SystemFunction004 failed (Status 0x%08lx)\n", Status);
+        HeapFree(GetProcessHeap(), 0, pBuffer);
+        return RtlNtStatusToDosError(Status);
+    }
 
-    *pEncryptedPassword = pBuffer;
-    *pEncryptedPasswordSize = dwSize;
+    *pEncryptedPassword = outData.Buffer;
+    *pEncryptedPasswordSize = outData.Length;
 
     return ERROR_SUCCESS;
 }
@@ -395,12 +434,12 @@ done:
     if (lpPasswordW != NULL)
     {
         /* Wipe and release the password buffers */
-        ZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * sizeof(WCHAR));
+        SecureZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * 
sizeof(WCHAR));
         HeapFree(GetProcessHeap(), 0, lpPasswordW);
 
         if (lpEncryptedPassword != NULL)
         {
-            ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+            SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
             HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
         }
     }
@@ -498,7 +537,7 @@ done:
     if (lpEncryptedPassword != NULL)
     {
         /* Wipe and release the password buffer */
-        ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+        SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
         HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
     }
 
@@ -723,12 +762,12 @@ done:
     if (lpPasswordW != NULL)
     {
         /* Wipe and release the password buffers */
-        ZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * sizeof(WCHAR));
+        SecureZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * 
sizeof(WCHAR));
         HeapFree(GetProcessHeap(), 0, lpPasswordW);
 
         if (lpEncryptedPassword != NULL)
         {
-            ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+            SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
             HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
         }
     }
@@ -837,7 +876,7 @@ done:
     if (lpEncryptedPassword != NULL)
     {
         /* Wipe and release the password buffers */
-        ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+        SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
         HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
     }
 

Reply via email to