Kai Blin : secur32: Add tests for MakeSignature, VerifySignature, EncryptMessage and DecryptMessage.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Aug 9 10:37:20 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: a71cf8446f1055d4bc327c6096d83183d16dbe3d
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=a71cf8446f1055d4bc327c6096d83183d16dbe3d

Author: Kai Blin <kai.blin at gmail.com>
Date:   Wed Aug  9 14:31:44 2006 +0200

secur32: Add tests for MakeSignature, VerifySignature, EncryptMessage and DecryptMessage.

---

 dlls/secur32/tests/ntlm.c |  202 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 201 insertions(+), 1 deletions(-)

diff --git a/dlls/secur32/tests/ntlm.c b/dlls/secur32/tests/ntlm.c
index fc45874..ba3fc73 100644
--- a/dlls/secur32/tests/ntlm.c
+++ b/dlls/secur32/tests/ntlm.c
@@ -49,6 +49,14 @@ static SECURITY_STATUS (SEC_ENTRY * pAcc
 static SECURITY_STATUS (SEC_ENTRY * pFreeCredentialsHandle)(PCredHandle);
 static SECURITY_STATUS (SEC_ENTRY * pDeleteSecurityContext)(PCtxtHandle);
 static SECURITY_STATUS (SEC_ENTRY * pQueryContextAttributesA)(PCtxtHandle, ULONG, PVOID);
+static SECURITY_STATUS (SEC_ENTRY * pMakeSignature)(PCtxtHandle, ULONG,
+                            PSecBufferDesc, ULONG);
+static SECURITY_STATUS (SEC_ENTRY * pVerifySignature)(PCtxtHandle, PSecBufferDesc,
+                            ULONG, PULONG);
+static SECURITY_STATUS (SEC_ENTRY * pEncryptMessage)(PCtxtHandle, ULONG,
+                            PSecBufferDesc, ULONG);
+static SECURITY_STATUS (SEC_ENTRY * pDecryptMessage)(PCtxtHandle, PSecBufferDesc,
+                            ULONG, PULONG);
 
 typedef struct _SspiData {
     PCredHandle cred;
@@ -99,6 +107,32 @@ static BYTE native_challenge[] = 
     0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
     0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00};
 
+static BYTE message_signature[] =
+   {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static BYTE message_binary[] =
+   {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72,
+    0x6c, 0x64, 0x21};
+
+static char message[] = "Hello, world!";
+
+static BYTE crypt_trailer_client[] =
+   {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xc7,
+    0xaa, 0x26, 0x16, 0x39, 0x07, 0x4e};
+
+static BYTE crypt_message_client[] =
+   {0x86, 0x9c, 0x5a, 0x10, 0x78, 0xb3, 0x30, 0x98, 0x46, 0x15,
+    0xa0, 0x31, 0xd9};
+
+static BYTE crypt_trailer_server[] =
+   {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x46,
+    0x2e, 0x77, 0xeb, 0xf0, 0xf6, 0x9e};
+
+static BYTE crypt_message_server[] =
+   {0xf6, 0xb7, 0x92, 0x0c, 0xac, 0xea, 0x98, 0xe6, 0xef, 0xa0,
+    0x29, 0x66, 0xfd};
+
 static void InitFunctionPtrs(void)
 {
     secdll = LoadLibraryA("secur32.dll");
@@ -116,6 +150,10 @@ static void InitFunctionPtrs(void)
         pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle");
         pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext");
         pQueryContextAttributesA = (PVOID)GetProcAddress(secdll, "QueryContextAttributesA");
+        pMakeSignature = (PVOID)GetProcAddress(secdll, "MakeSignature");
+        pVerifySignature = (PVOID)GetProcAddress(secdll, "VerifySignature");
+        pEncryptMessage = (PVOID)GetProcAddress(secdll, "EncryptMessage");
+        pDecryptMessage = (PVOID)GetProcAddress(secdll, "DecryptMessage");
     }
 }
 
@@ -636,6 +674,165 @@ static void testAuth(ULONG data_rep, BOO
     }
 }
 
+static void testSignSeal()
+{
+    SECURITY_STATUS         client_stat = SEC_I_CONTINUE_NEEDED;
+    SECURITY_STATUS         server_stat = SEC_I_CONTINUE_NEEDED;
+    SECURITY_STATUS         sec_status;
+    PSecPkgInfo             pkg_info = NULL;
+    BOOL                    first = TRUE;
+    SspiData                client, server;
+    SEC_WINNT_AUTH_IDENTITY id;
+    static char             sec_pkg_name[] = "NTLM";
+    PSecBufferDesc          crypt = NULL;
+    PSecBuffer              data = NULL;
+    ULONG                   qop = 0;
+    SecPkgContext_Sizes     ctxt_sizes;
+
+    /****************************************************************
+     * This is basically the same as in testAuth with a fake server,
+     * as we need a valid, authenticated context.
+     */
+    if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)== SEC_E_OK)
+    {
+        pFreeContextBuffer(pkg_info);
+        id.User = (unsigned char*) "testuser";
+        id.UserLength = strlen((char *) id.User);
+        id.Domain = (unsigned char *) "WORKGROUP";
+        id.DomainLength = strlen((char *) id.Domain);
+        id.Password = (unsigned char*) "testpass";
+        id.PasswordLength = strlen((char *) id.Password);
+        id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
+
+        client.id = &id;
+
+        sec_status = setupClient(&client, sec_pkg_name);
+
+        if(sec_status != SEC_E_OK)
+        {
+            trace("Error: Setting up the client returned %s, exiting test!\n",
+                    getSecError(sec_status));
+            pFreeCredentialsHandle(client.cred);
+            return;
+        }
+
+        sec_status = setupFakeServer(&server, sec_pkg_name);
+
+        while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
+        {
+            client_stat = runClient(&client, first, SECURITY_NETWORK_DREP);
+
+            communicate(&client, &server);
+
+            server_stat = runFakeServer(&server, first, SECURITY_NETWORK_DREP);
+
+            communicate(&server, &client);
+            trace("Looping\n");
+            first = FALSE;
+        }
+
+        /********************************************
+         *    Now start with the actual testing     *
+         ********************************************/
+
+        if(pQueryContextAttributesA(client.ctxt, SECPKG_ATTR_SIZES,
+                    &ctxt_sizes) != SEC_E_OK)
+        {
+            trace("Failed to get context sizes, aborting test.\n");
+            goto end;
+        }
+
+        if((crypt = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc))) == NULL)
+        {
+            trace("Failed to allocate the crypto buffer, aborting test.\n");
+            goto end;
+        }
+
+        crypt->ulVersion = SECBUFFER_VERSION;
+        crypt->cBuffers = 2;
+
+        if((data = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBuffer) * 2)) == NULL)
+        {
+            trace("Failed to allocate the crypto buffer, aborting test.\n");
+            goto end;
+        }
+
+        crypt->pBuffers = data;
+
+        data[0].BufferType = SECBUFFER_TOKEN;
+        data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
+        data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[0].cbBuffer);
+
+        data[1].BufferType = SECBUFFER_DATA;
+        data[1].cbBuffer = lstrlen(message);
+        data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
+        memcpy(data[1].pvBuffer, message, data[1].cbBuffer);
+
+        /* As we forced NTLM to fall back to a password-derived session key,
+         * we should get the same signature for our data, no matter if
+         * it is sent by the client or the server
+         */
+        sec_status = pMakeSignature(client.ctxt, 0, crypt, 0);
+        todo_wine {
+        ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
+                getSecError(sec_status));
+        ok(!memcmp(crypt->pBuffers[0].pvBuffer, message_signature,
+                   crypt->pBuffers[0].cbBuffer), "Signature is not as expected.\n");
+        }
+
+        data[0].cbBuffer = sizeof(message_signature);
+        memcpy(data[0].pvBuffer, message_signature, data[0].cbBuffer);
+
+        sec_status = pVerifySignature(client.ctxt, crypt, 0, &qop);
+        todo_wine {
+        ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK.\n",
+                getSecError(sec_status));
+        }
+
+        sec_status = pEncryptMessage(client.ctxt, 0, crypt, 0);
+        todo_wine{
+        ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
+                getSecError(sec_status));
+        ok(!memcmp(crypt->pBuffers[0].pvBuffer, crypt_trailer_client,
+                   crypt->pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n");
+        ok(!memcmp(crypt->pBuffers[1].pvBuffer, crypt_message_client,
+                   crypt->pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
+        }
+
+        data[0].cbBuffer = sizeof(crypt_trailer_server);
+        data[1].cbBuffer = sizeof(crypt_message_server);
+        memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer);
+        memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer);
+
+        sec_status = pDecryptMessage(client.ctxt, crypt, 0, &qop);
+        todo_wine {
+        ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
+                getSecError(sec_status));
+        ok(!memcmp(crypt->pBuffers[1].pvBuffer, message_binary,
+                   crypt->pBuffers[1].cbBuffer),
+                "Failed to decrypt message correctly.\n");
+        }
+
+end:
+        cleanupBuffers(&client);
+        cleanupBuffers(&server);
+
+        pDeleteSecurityContext(client.ctxt);
+        pFreeCredentialsHandle(client.cred);
+        if(data)
+        {
+            HeapFree(GetProcessHeap(), 0, data[0].pvBuffer);
+            HeapFree(GetProcessHeap(), 0, data[1].pvBuffer);
+        }
+        HeapFree(GetProcessHeap(), 0, data);
+        HeapFree(GetProcessHeap(), 0, crypt);
+    }
+    else
+    {
+        trace("Package not installed, skipping test.\n");
+    }
+}
+
 START_TEST(ntlm)
 {
     InitFunctionPtrs();
@@ -652,8 +849,11 @@ START_TEST(ntlm)
             testAuth(SECURITY_NATIVE_DREP, FALSE);
             testAuth(SECURITY_NETWORK_DREP, FALSE);
         }
+        if(pMakeSignature && pVerifySignature && pEncryptMessage &&
+           pDecryptMessage)
+            testSignSeal();
      }
-    
+
     if(secdll)
         FreeLibrary(secdll);
 }




More information about the wine-cvs mailing list