From a71cf8446f1055d4bc327c6096d83183d16dbe3d Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Wed, 9 Aug 2006 14:31:44 +0200 Subject: [PATCH] secur32: Add tests for MakeSignature, VerifySignature, EncryptMessage and DecryptMessage. --- dlls/secur32/tests/ntlm.c | 202 +++++++++++++++++++++++++++++++++++++- 1 file changed, 201 insertions(+), 1 deletion(-) diff --git a/dlls/secur32/tests/ntlm.c b/dlls/secur32/tests/ntlm.c index fc45874fcc2..ba3fc73e46d 100644 --- a/dlls/secur32/tests/ntlm.c +++ b/dlls/secur32/tests/ntlm.c @@ -49,6 +49,14 @@ static SECURITY_STATUS (SEC_ENTRY * pAcceptSecurityContext)(PCredHandle, PCtxtHa 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, BOOL fake) } } +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); }