6 * Copyright (C) 2010 pier11 <pier11@operamail.com>
7 * Copyright (C) 2008 Novell, Inc.
9 * Implemented with reference to the follow documentation:
10 * - http://davenport.sourceforge.net/ntlm.html
11 * - MS-NLMP: http://msdn.microsoft.com/en-us/library/cc207842.aspx
12 * - MS-SIP : http://msdn.microsoft.com/en-us/library/cc246115.aspx
14 * Please use "make tests" to build & run them!
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "sipe-sign.h"
35 #define _SIPE_COMPILING_TESTS
36 #include "sip-sec-ntlm.c"
40 static int successes
= 0;
41 static int failures
= 0;
44 hex_str_to_buff(const char *hex_str
, guint8
**bytes
)
52 gsize length
= strlen(hex_str
)/2;
53 buff
= (guint8
*)g_malloc(length
);
54 for (i
= 0; i
< length
; i
++) {
55 two_digits
[0] = hex_str
[i
* 2];
56 two_digits
[1] = hex_str
[i
* 2 + 1];
58 buff
[i
] = (guint8
)strtoul(two_digits
, NULL
, 16);
65 static void assert_equal(const char * expected
, const guchar
* got
, int len
, gboolean stringify
)
67 const gchar
* res
= (gchar
*) got
;
72 for (i
= 0, j
= 0; i
< len
; i
++, j
+=2) {
73 g_sprintf(&to_str
[j
], "%02X", (got
[i
]&0xff));
79 printf("expected: %s\n", expected
);
80 printf("received: %s\n", res
);
82 if (g_ascii_strncasecmp(expected
, res
, len
) == 0) {
91 /* NOTE: both values are expected to be in host byte order! */
92 static void assert_equal_guint32(guint32 expected
, guint32 got
)
94 printf("expected: %08X\n", expected
);
95 printf("received: %08X\n", got
);
97 if (expected
== got
) {
108 printf ("Starting Tests\n");
110 /* Initialization that libpurple/core.c would normally do */
111 purple_signals_init();
113 purple_debug_set_enabled(TRUE
);
114 purple_ciphers_init();
116 /* These tests are from the MS-SIPE document */
118 const char * password
= "Password";
119 const char * user
= "User";
120 const char * domain
= "Domain";
121 const guchar client_challenge
[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
122 /* server challenge */
123 const guchar nonce
[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
125 const guchar exported_session_key
[] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
126 const guchar text
[] = {0x50, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x78, 0x00, 0x74, 0x00}; //P·l·a·i·n·t·e·x·t·
129 ////// internal Cyphers tests ///////
130 printf ("\nTesting MD4()\n");
132 MD4 ((const unsigned char *)"message digest", 14, md4
);
133 assert_equal("D9130A8164549FE818874806E1C7014B", md4
, 16, TRUE
);
135 printf ("\nTesting MD5()\n");
137 MD5 ((const unsigned char *)"message digest", 14, md5
);
138 assert_equal("F96B697D7CB7938D525A2F31AAF161D0", md5
, 16, TRUE
);
140 printf ("\nTesting HMAC_MD5()\n");
141 guchar hmac_md5
[16];
142 HMAC_MD5 ((const unsigned char *)"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 16, (const unsigned char *)"Hi There", 8, hmac_md5
);
143 assert_equal("9294727A3638BB1C13F48EF8158BFC9D", hmac_md5
, 16, TRUE
);
146 ////// NTLMv1 (without Extended Session Security) ///////
150 | NTLMSSP_NEGOTIATE_KEY_EXCH
151 | NTLMSSP_NEGOTIATE_56
152 | NTLMSSP_NEGOTIATE_128
153 | NTLMSSP_NEGOTIATE_VERSION
154 | NTLMSSP_TARGET_TYPE_SERVER
155 | NTLMSSP_NEGOTIATE_ALWAYS_SIGN
156 | NTLMSSP_NEGOTIATE_NTLM
157 | NTLMSSP_NEGOTIATE_SEAL
158 | NTLMSSP_NEGOTIATE_SIGN
159 | NTLMSSP_NEGOTIATE_OEM
160 | NTLMSSP_NEGOTIATE_UNICODE
;
162 printf ("\n\nTesting Negotiation Flags\n");
163 assert_equal_guint32(0xE2028233, flags
);
165 printf ("\n\nTesting LMOWFv1()\n");
166 guchar response_key_lm
[16];
167 LMOWFv1 (password
, user
, domain
, response_key_lm
);
168 assert_equal("E52CAC67419A9A224A3B108F3FA6CB6D", response_key_lm
, 16, TRUE
);
170 printf ("\n\nTesting NTOWFv1()\n");
171 guchar response_key_nt
[16];
172 NTOWFv1 (password
, user
, domain
, response_key_nt
);
173 assert_equal("A4F49C406510BDCAB6824EE7C30FD852", response_key_nt
, 16, TRUE
);
175 printf ("\n\nTesting LM Response Generation\n");
176 printf ("Testing NT Response Generation\n");
177 printf ("Testing Session Base Key\n");
178 guchar nt_challenge_response
[24];
179 guchar lm_challenge_response
[24];
180 guchar session_base_key
[16];
182 compute_response(flags
,
188 NULL
, /* target_info */
189 0, /* target_info_len */
190 lm_challenge_response
, /* out */
191 nt_challenge_response
, /* out */
192 session_base_key
); /* out */
194 assert_equal("98DEF7B87F88AA5DAFE2DF779688A172DEF11C7D5CCDEF13", lm_challenge_response
, 24, TRUE
);
195 assert_equal("67C43011F30298A2AD35ECE64F16331C44BDBED927841F94", nt_challenge_response
, 24, TRUE
);
196 assert_equal("D87262B0CDE4B1CB7499BECCCDF10784", session_base_key
, 16, TRUE
);
198 printf ("\n\nTesting Key Exchange Key\n");
199 guchar key_exchange_key
[16];
200 KXKEY(flags
, session_base_key
, lm_challenge_response
, nonce
, key_exchange_key
);
201 assert_equal("D87262B0CDE4B1CB7499BECCCDF10784", key_exchange_key
, 16, TRUE
);
203 printf ("\n\nTesting Encrypted Session Key Generation\n");
204 guchar encrypted_random_session_key
[16];
205 RC4K (key_exchange_key
, 16, exported_session_key
, 16, encrypted_random_session_key
);
206 assert_equal("518822B1B3F350C8958682ECBB3E3CB7", encrypted_random_session_key
, 16, TRUE
);
208 printf ("\n\nTesting CRC32\n");
209 guint32 crc
= CRC32((char*)text
, 18);
210 assert_equal_guint32(0x93AA847D, crc
);
212 printf ("\n\nTesting Encryption\n");
213 guchar client_seal_key
[16];
214 //SEALKEY (flags, exported_session_key, TRUE, client_seal_key);
215 guchar buff
[18 + 12];
216 memcpy(buff
, text
, 18);
217 guchar text_enc
[18 + 12];
219 to_enc
[0] = GUINT32_TO_LE(0); // random pad
220 to_enc
[1] = GUINT32_TO_LE(crc
);
221 to_enc
[2] = GUINT32_TO_LE(0); // zero
222 memcpy(buff
+18, (gchar
*)to_enc
, 12);
223 RC4K (exported_session_key
, 16, buff
, 18 + 12, text_enc
);
224 //The point is to not reinitialize rc4 cypher
226 assert_equal("56FE04D861F9319AF0D7238A2E3B4D457FB8" "45C844E5" "09DCD1DF" "2E459D36", text_enc
, 18 + 12, TRUE
);
228 printf ("\n\nTesting MAC\n");
229 // won't work in the case with sealing because RC4 is re-initialized inside.
230 //gchar *mac = MAC (flags, (gchar*)text, 18, (guchar*)exported_session_key, 16, (guchar*)exported_session_key,16, 0x00000000, 0);
232 memcpy((gchar
*)enc
, text_enc
+18, 12);
234 mac2
[0] = GUINT32_TO_LE(1); // version
237 mac2
[3] = enc
[2] ^ (GUINT32_TO_LE(0)); // ^ seq
238 assert_equal("0100000045C844E509DCD1DF2E459D36", (guchar
*)mac2
, 16, TRUE
);
241 ////// EXTENDED_SESSIONSECURITY ///////
244 | NTLMSSP_NEGOTIATE_56
245 | NTLMSSP_NEGOTIATE_VERSION
246 | NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
247 | NTLMSSP_TARGET_TYPE_SERVER
248 | NTLMSSP_NEGOTIATE_ALWAYS_SIGN
249 | NTLMSSP_NEGOTIATE_NTLM
250 | NTLMSSP_NEGOTIATE_SEAL
251 | NTLMSSP_NEGOTIATE_SIGN
252 | NTLMSSP_NEGOTIATE_OEM
253 | NTLMSSP_NEGOTIATE_UNICODE
;
255 printf ("\n\n(Extended session security) Testing Negotiation Flags\n");
256 assert_equal_guint32(0x820A8233, flags
);
258 /* NTOWFv1() is not different from the above test for the same */
260 printf ("\n\n(Extended session security) Testing LM Response\n");
261 printf ("(Extended session security) Testing NT Response\n");
262 printf ("(Extended session security) Testing Session Base Key\n");
263 compute_response(flags
,
269 NULL
, /* target_info */
270 0, /* target_info_len */
271 lm_challenge_response
, /* out */
272 nt_challenge_response
, /* out */
273 session_base_key
); /* out */
275 assert_equal("AAAAAAAAAAAAAAAA00000000000000000000000000000000", lm_challenge_response
, 24, TRUE
);
276 assert_equal("7537F803AE367128CA458204BDE7CAF81E97ED2683267232", nt_challenge_response
, 24, TRUE
);
277 assert_equal("D87262B0CDE4B1CB7499BECCCDF10784", session_base_key
, 16, TRUE
);
279 printf ("\n\n(Extended session security) Testing Key Exchange Key\n");
280 KXKEY(flags
, session_base_key
, lm_challenge_response
, nonce
, key_exchange_key
);
281 assert_equal("EB93429A8BD952F8B89C55B87F475EDC", key_exchange_key
, 16, TRUE
);
283 printf ("\n\n(Extended session security) SIGNKEY\n");
284 guchar client_sign_key
[16];
285 SIGNKEY (key_exchange_key
, TRUE
, client_sign_key
);
286 assert_equal("60E799BE5C72FC92922AE8EBE961FB8D", client_sign_key
, 16, TRUE
);
288 printf ("\n\n(Extended session security) SEALKEY\n");
289 SEALKEY (flags
, key_exchange_key
, TRUE
, client_seal_key
);
290 assert_equal("04DD7F014D8504D265A25CC86A3A7C06", client_seal_key
, 16, TRUE
);
292 printf ("\n\n(Extended session security) Testing Encryption\n");
293 RC4K (client_seal_key
, 16, text
, 18, text_enc
);
294 assert_equal("A02372F6530273F3AA1EB90190CE5200C99D", text_enc
, 18, TRUE
);
296 printf ("\n\n(Extended session security) Testing MAC\n");
297 gchar
*mac
= MAC (flags
, (gchar
*)text
,18, client_sign_key
,16, client_seal_key
,16, 0, 0);
298 assert_equal("01000000FF2AEB52F681793A00000000", (guchar
*)mac
, 32, FALSE
);
302 ////// NTLMv2 ///////
305 | NTLMSSP_NEGOTIATE_KEY_EXCH
306 | NTLMSSP_NEGOTIATE_56
307 | NTLMSSP_NEGOTIATE_128
308 | NTLMSSP_NEGOTIATE_VERSION
309 | NTLMSSP_NEGOTIATE_TARGET_INFO
310 | NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
311 | NTLMSSP_TARGET_TYPE_SERVER
312 | NTLMSSP_NEGOTIATE_ALWAYS_SIGN
313 | NTLMSSP_NEGOTIATE_NTLM
314 | NTLMSSP_NEGOTIATE_SEAL
315 | NTLMSSP_NEGOTIATE_SIGN
316 | NTLMSSP_NEGOTIATE_OEM
317 | NTLMSSP_NEGOTIATE_UNICODE
;
319 printf ("\n\nTesting (NTLMv2) Negotiation Flags\n");
320 assert_equal_guint32(0xE28A8233, flags
);
322 printf ("\n\nTesting NTOWFv2()\n");
323 NTOWFv2 (password
, user
, domain
, response_key_nt
);
324 NTOWFv2 (password
, user
, domain
, response_key_lm
);
325 assert_equal("0C868A403BFD7A93A3001EF22EF02E3F", response_key_nt
, 16, TRUE
);
328 printf ("\n\nTesting (NTLMv2) LM Response Generation\n");
329 printf ("Testing (NTLMv2) NT Response Generation and Session Base Key\n");
332 4e544c4d53535000020000000c000c003800000033828ae20123456789abcdef00000000000000002400240044000000060070170000000f53006500720076006500720002000c0044006f006d00610069006e0001000c0053006500720076006500720000000000
334 NTLMSSP_NEGOTIATE_UNICODE
335 NTLMSSP_NEGOTIATE_OEM
336 NTLMSSP_NEGOTIATE_SIGN
337 NTLMSSP_NEGOTIATE_SEAL
338 NTLMSSP_NEGOTIATE_NTLM
339 NTLMSSP_NEGOTIATE_ALWAYS_SIGN
340 NTLMSSP_TARGET_TYPE_SERVER
341 NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
342 NTLMSSP_NEGOTIATE_TARGET_INFO
343 NTLMSSP_NEGOTIATE_VERSION
344 NTLMSSP_NEGOTIATE_128
345 NTLMSSP_NEGOTIATE_KEY_EXCH
348 target_name.maxlen: 12
349 target_name.offset: 56
351 target_info.maxlen: 36
352 target_info.offset: 68
353 product: 6.0.6000 (Windows Vista, Windows Server 2008, Windows 7 or Windows Server 2008 R2)
354 ntlm_revision_current: 0x0F (NTLMSSP_REVISION_W2K3)
356 MsvAvNbDomainName: Domain
357 MsvAvNbComputerName: Server
360 530065007200760065007200
362 02000c0044006f006d00610069006e0001000c0053006500720076006500720000000000
365 4e544c4d5353500003000000180018006c00000054005400840000000c000c00480000000800080054000000100010005c00000010001000d8000000358288e20501280a0000000f44006f006d00610069006e00550073006500720043004f004d005000550054004500520086c35097ac9cec102554764a57cccc19aaaaaaaaaaaaaaaa68cd0ab851e51c96aabc927bebef6a1c01010000000000000000000000000000aaaaaaaaaaaaaaaa0000000002000c0044006f006d00610069006e0001000c005300650072007600650072000000000000000000c5dad2544fc9799094ce1ce90bc9d03e
369 const guint64 time_val
= 0;
370 const guint8 target_info
[] = {
371 0x02, 0x00, 0x0C, 0x00, //NetBIOS Domain name, 4 bytes
372 0x44, 0x00, 0x6F, 0x00, 0x6D, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6E, 0x00, //D.o.m.a.i.n. 12bytes
373 0x01, 0x00, 0x0C, 0x00, //NetBIOS Server name, 4 bytes
374 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, //S.e.r.v.e.r. 12bytes
375 0x00, 0x00, 0x00, 0x00, //Av End, 4 bytes
377 const int target_info_len
= 32+4;
378 int ntlmssp_nt_resp_len
= (16 + (32+target_info_len
));
379 guchar nt_challenge_response_v2
[ntlmssp_nt_resp_len
];
381 compute_response(flags
,
387 target_info
, /* target_info */
388 target_info_len
, /* target_info_len */
389 lm_challenge_response
, /* out */
390 nt_challenge_response_v2
, /* out */
391 session_base_key
); /* out */
393 assert_equal("86C35097AC9CEC102554764A57CCCC19AAAAAAAAAAAAAAAA", lm_challenge_response
, 24, TRUE
);
394 assert_equal("68CD0AB851E51C96AABC927BEBEF6A1C", nt_challenge_response_v2
, 16, TRUE
);
395 /* the ref string is taken from binary dump of AUTHENTICATE_MESSAGE */
396 assert_equal("68CD0AB851E51C96AABC927BEBEF6A1C01010000000000000000000000000000AAAAAAAAAAAAAAAA0000000002000C0044006F006D00610069006E0001000C005300650072007600650072000000000000000000", nt_challenge_response_v2
, ntlmssp_nt_resp_len
, TRUE
);
397 assert_equal("8DE40CCADBC14A82F15CB0AD0DE95CA3", session_base_key
, 16, TRUE
);
399 printf ("\n\nTesting (NTLMv2) Encrypted Session Key\n");
400 // key_exchange_key = session_base_key for NTLMv2
401 KXKEY(flags
, session_base_key
, lm_challenge_response
, nonce
, key_exchange_key
);
402 //RC4 encryption of the RandomSessionKey with the KeyExchangeKey:
403 RC4K (key_exchange_key
, 16, exported_session_key
, 16, encrypted_random_session_key
);
404 assert_equal("C5DAD2544FC9799094CE1CE90BC9D03E", encrypted_random_session_key
, 16, TRUE
);
406 printf ("\n\nTesting (NTLMv2) SIGNKEY\n");
407 SIGNKEY (exported_session_key
, TRUE
, client_sign_key
);
408 assert_equal("4788DC861B4782F35D43FD98FE1A2D39", client_sign_key
, 16, TRUE
);
410 printf ("\n\nTesting (NTLMv2) SEALKEY\n");
411 SEALKEY (flags
, exported_session_key
, TRUE
, client_seal_key
);
412 assert_equal("59F600973CC4960A25480A7C196E4C58", client_seal_key
, 16, TRUE
);
414 printf ("\n\nTesting (NTLMv2) Encryption\n");
415 RC4K (client_seal_key
, 16, text
, 18, text_enc
);
416 assert_equal("54E50165BF1936DC996020C1811B0F06FB5F", text_enc
, 18, TRUE
);
418 // printf ("\n\nTesting (NTLMv2) Encryption\n");
419 //const guchar text2 [] = {0x50, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x78, 0x00, 0x74, 0x00
420 // , 0x70, 0x35, 0x28, 0x51, 0xf2, 0x56, 0x43, 0x09}; //P·l·a·i·n·t·e·x·t·
421 //guchar text_enc2 [18+8];
422 // RC4K (client_seal_key, 16, text2, 18+8, text_enc2);
423 // assert_equal("54E50165BF1936DC996020C1811B0F06FB5F", text_enc2, 18+8, TRUE);
425 printf ("\n\nTesting (NTLMv2) MAC (without RC4, as we don't keep its handle yet)\n");
426 mac
= MAC (flags
& ~NTLMSSP_NEGOTIATE_KEY_EXCH
, (gchar
*)text
,18, client_sign_key
,16, client_seal_key
,16, 0, 0);
427 assert_equal("0100000070352851F256430900000000", (guchar
*)mac
, 32, FALSE
);
431 /* End tests from the MS-SIPE document */
434 ////// davenport tests ///////
435 // Test from http://davenport.sourceforge.net/ntlm.html#ntlm1Signing
436 const gchar
*text_j
= "jCIFS";
437 printf ("\n\n(davenport) Testing Signature Algorithm\n");
438 guchar sk
[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0xe5, 0x38, 0xb0};
440 "0100000078010900397420FE0E5A0F89",
441 (guchar
*) MAC(NEGOTIATE_FLAGS
& ~NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
, text_j
, strlen(text_j
), sk
, 8, sk
,8, 0x00090178, 0),
445 // Tests from http://davenport.sourceforge.net/ntlm.html#ntlm2Signing
446 printf ("\n\n(davenport) SIGNKEY\n");
447 const guchar master_key
[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00};
448 SIGNKEY (master_key
, TRUE
, client_sign_key
);
449 assert_equal("F7F97A82EC390F9C903DAC4F6ACEB132", client_sign_key
, 16, TRUE
);
451 printf ("\n\n(davenport) Testing MAC - no Key Exchange flag\n");
452 mac
= MAC (flags
& ~NTLMSSP_NEGOTIATE_KEY_EXCH
, text_j
, strlen(text_j
), client_sign_key
, 16, client_sign_key
,16, 0, 0);
453 assert_equal("010000000A003602317A759A00000000", (guchar
*)mac
, 32, FALSE
);
457 ////// SIPE internal tests ///////
458 // Verify signature of SIPE message received from OCS 2007 after authenticating with pidgin-sipe
459 printf ("\n\nTesting MS-SIPE Example Message Signing\n");
460 char * msg1
= "<NTLM><0878F41B><1><SIP Communications Service><ocs1.ocs.provo.novell.com><8592g5DCBa1694i5887m0D0Bt2247b3F38xAE9Fx><3><REGISTER><sip:gabriel@ocs.provo.novell.com><2947328781><B816D65C2300A32CFA6D371F2AF537FD><900><200>";
461 guchar exported_session_key2
[] = { 0x5F, 0x02, 0x91, 0x53, 0xBC, 0x02, 0x50, 0x58, 0x96, 0x95, 0x48, 0x61, 0x5E, 0x70, 0x99, 0xBA };
463 "0100000000000000BF2E52667DDF6DED",
464 (guchar
*) MAC(NEGOTIATE_FLAGS
& ~NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
, msg1
, strlen(msg1
), exported_session_key2
, 16, exported_session_key2
,16, 0, 100),
468 // Verify parsing of message and signature verification
469 printf ("\n\nTesting MS-SIPE Example Message Parsing, Signing, and Verification\n(Authentication Protocol Version 2)\n");
470 char * msg2
= "SIP/2.0 200 OK\r\nms-keep-alive: UAS; tcp=no; hop-hop=yes; end-end=no; timeout=300\r\nAuthentication-Info: NTLM rspauth=\"0100000000000000BF2E52667DDF6DED\", srand=\"0878F41B\", snum=\"1\", opaque=\"4452DFB0\", qop=\"auth\", targetname=\"ocs1.ocs.provo.novell.com\", realm=\"SIP Communications Service\"\r\nFrom: \"Gabriel Burt\"<sip:gabriel@ocs.provo.novell.com>;tag=2947328781;epid=1234567890\r\nTo: <sip:gabriel@ocs.provo.novell.com>;tag=B816D65C2300A32CFA6D371F2AF537FD\r\nCall-ID: 8592g5DCBa1694i5887m0D0Bt2247b3F38xAE9Fx\r\nCSeq: 3 REGISTER\r\nVia: SIP/2.0/TLS 164.99.194.49:10409;branch=z9hG4bKE0E37DBAF252C3255BAD;received=164.99.195.20;ms-received-port=10409;ms-received-cid=1E00\r\nContact: <sip:164.99.195.20:10409;transport=tls;ms-received-cid=1E00>;expires=900\r\nExpires: 900\r\nAllow-Events: vnd-microsoft-provisioning,vnd-microsoft-roaming-contacts,vnd-microsoft-roaming-ACL,presence,presence.wpending,vnd-microsoft-roaming-self,vnd-microsoft-provisioning-v2\r\nSupported: adhoclist\r\nServer: RTC/3.0\r\nSupported: com.microsoft.msrtc.presence\r\nContent-Length: 0\r\n\r\n";
471 struct sipmsg
* msg
= sipmsg_parse_msg(msg2
);
472 struct sipmsg_breakdown msgbd
;
474 sipmsg_breakdown_parse(&msgbd
, "SIP Communications Service", "ocs1.ocs.provo.novell.com");
475 gchar
* msg_str
= sipmsg_breakdown_get_string(2, &msgbd
);
476 gchar
* sig
= sip_sec_ntlm_sipe_signature_make (NEGOTIATE_FLAGS
& ~NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
, msg_str
, 0, exported_session_key2
, exported_session_key2
);
477 sipmsg_breakdown_free(&msgbd
);
478 assert_equal ("0100000000000000BF2E52667DDF6DED", (guchar
*) sig
, 32, FALSE
);
479 printf("purple_ntlm_verify_signature result = %i\n", sip_sec_ntlm_verify_signature (sig
, "0100000000000000BF2E52667DDF6DED"));
482 ////// real Communicator 2007 R2 tests //////
483 ////// Recreated/verifyed real authentication communication between
484 ////// Communicator 2007 R2 and Office Communications Server 2007 R2
485 ////// with SIPE NTLMv2 implementation.
487 const char *password2
= "Pa$$word";
488 const char *user2
= "User";
489 const char *domain2
= "COSMO";
490 const char *host2
= "COSMO-OCS-R2";
493 //const char *type2 = "TlRMTVNTUAACAAAAAAAAADgAAADzgpji3Ruq9OfiGNEAAAAAAAAAAJYAlgA4AAAABQLODgAAAA8CAAoAQwBPAFMATQBPAAEAGABDAE8AUwBNAE8ALQBPAEMAUwAtAFIAMgAEABYAYwBvAHMAbQBvAC4AbABvAGMAYQBsAAMAMABjAG8AcwBtAG8ALQBvAGMAcwAtAHIAMgAuAGMAbwBzAG0AbwAuAGwAbwBjAGEAbAAFABYAYwBvAHMAbQBvAC4AbABvAGMAYQBsAAAAAAA=";
494 //in hex (base64 decoded):
495 const char *type2_hex
= "4E544C4D53535000020000000000000038000000F38298E2DD1BAAF4E7E218D1000000000000000096009600380000000502CE0E0000000F02000A0043004F0053004D004F000100180043004F0053004D004F002D004F00430053002D00520032000400160063006F0073006D006F002E006C006F00630061006C000300300063006F0073006D006F002D006F00630073002D00720032002E0063006F0073006D006F002E006C006F00630061006C000500160063006F0073006D006F002E006C006F00630061006C0000000000";
497 Message (length 206):
498 NTLMSSP_NEGOTIATE_UNICODE
499 NTLMSSP_NEGOTIATE_OEM
500 NTLMSSP_NEGOTIATE_SIGN
501 NTLMSSP_NEGOTIATE_SEAL
502 NTLMSSP_NEGOTIATE_DATAGRAM
503 NTLMSSP_NEGOTIATE_LM_KEY
504 NTLMSSP_NEGOTIATE_NTLM
505 NTLMSSP_NEGOTIATE_ALWAYS_SIGN
506 NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
507 NTLMSSP_NEGOTIATE_IDENTIFY
508 NTLMSSP_NEGOTIATE_TARGET_INFO
509 NTLMSSP_NEGOTIATE_VERSION
510 NTLMSSP_NEGOTIATE_128
511 NTLMSSP_NEGOTIATE_KEY_EXCH
513 server_challenge: DD1BAAF4E7E218D1
515 target_name.maxlen: 0
516 target_name.offset: 56
517 target_info.len : 150
518 target_info.maxlen: 150
519 target_info.offset: 56
520 product: 5.2.3790 (Windows Server 2003)
521 ntlm_revision_current: 0x0F (NTLMSSP_REVISION_W2K3)
522 target_info raw: 02000A0043004F0053004D004F000100180043004F0053004D004F002D004F00430053002D00520032000400160063006F0073006D006F002E006C006F00630061006C000300300063006F0073006D006F002D006F00630073002D00720032002E0063006F0073006D006F002E006C006F00630061006C000500160063006F0073006D006F002E006C006F00630061006C0000000000
523 MsvAvNbDomainName: COSMO
524 MsvAvNbComputerName: COSMO-OCS-R2
525 MsvAvDnsDomainName: cosmo.local
526 MsvAvDnsComputerName: cosmo-ocs-r2.cosmo.local
527 MsvAvDnsTreeName: cosmo.local
532 //const char *type3 = "TlRMTVNTUAADAAAAGAAYAHIAAADGAMYAigAAAAoACgBIAAAACAAIAFIAAAAYABgAWgAAABAAEABQAQAAVYKYYgUCzg4AAAAPQwBPAFMATQBPAFUAcwBlAHIAQwBPAFMATQBPAC0ATwBDAFMALQBSADIAoeku/k4Hi/fFwASazGFmwtauh1yw/apBjcDIAK527KYG0rn769BHMQEBAAAAAAAAWVGaFye5ygHWrodcsP2qQQAAAAACAAoAQwBPAFMATQBPAAEAGABDAE8AUwBNAE8ALQBPAEMAUwAtAFIAMgAEABYAYwBvAHMAbQBvAC4AbABvAGMAYQBsAAMAMABjAG8AcwBtAG8ALQBvAGMAcwAtAHIAMgAuAGMAbwBzAG0AbwAuAGwAbwBjAGEAbAAFABYAYwBvAHMAbQBvAC4AbABvAGMAYQBsAAAAAAAAAAAAMctznhyoCkmFkeiueXEV5A==";
533 //in hex (base64 decoded):
534 const char *type3_hex
= "4E544C4D53535000030000001800180072000000C600C6008A0000000A000A00480000000800080052000000180018005A0000001000100050010000558298620502CE0E0000000F43004F0053004D004F00550073006500720043004F0053004D004F002D004F00430053002D0052003200A1E92EFE4E078BF7C5C0049ACC6166C2D6AE875CB0FDAA418DC0C800AE76ECA606D2B9FBEBD04731010100000000000059519A1727B9CA01D6AE875CB0FDAA410000000002000A0043004F0053004D004F000100180043004F0053004D004F002D004F00430053002D00520032000400160063006F0073006D006F002E006C006F00630061006C000300300063006F0073006D006F002D006F00630073002D00720032002E0063006F0073006D006F002E006C006F00630061006C000500160063006F0073006D006F002E006C006F00630061006C00000000000000000031CB739E1CA80A498591E8AE797115E4";
536 Message (length 352):
537 NTLMSSP_NEGOTIATE_UNICODE
538 NTLMSSP_REQUEST_TARGET
539 NTLMSSP_NEGOTIATE_SIGN
540 NTLMSSP_NEGOTIATE_DATAGRAM
541 NTLMSSP_NEGOTIATE_NTLM
542 NTLMSSP_NEGOTIATE_ALWAYS_SIGN
543 NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
544 NTLMSSP_NEGOTIATE_IDENTIFY
545 NTLMSSP_NEGOTIATE_TARGET_INFO
546 NTLMSSP_NEGOTIATE_VERSION
547 NTLMSSP_NEGOTIATE_128
548 NTLMSSP_NEGOTIATE_KEY_EXCH
565 session_key.maxlen: 16
566 session_key.offset: 336
567 product: 5.2.3790 (Windows Server 2003)
568 ntlm_revision_current: 0x0F (NTLMSSP_REVISION_W2K3)
569 lm_resp: A1E92EFE4E078BF7C5C0049ACC6166C2D6AE875CB0FDAA41
570 nt_resp raw: 8DC0C800AE76ECA606D2B9FBEBD04731010100000000000059519A1727B9CA01D6AE875CB0FDAA410000000002000A0043004F0053004D004F000100180043004F0053004D004F002D004F00430053002D00520032000400160063006F0073006D006F002E006C006F00630061006C000300300063006F0073006D006F002D006F00630073002D00720032002E0063006F0073006D006F002E006C006F00630061006C000500160063006F0073006D006F002E006C006F00630061006C000000000000000000
571 nt_resp: 8DC0C800AE76ECA606D2B9FBEBD04731
572 target_info raw: 02000A0043004F0053004D004F000100180043004F0053004D004F002D004F00430053002D00520032000400160063006F0073006D006F002E006C006F00630061006C000300300063006F0073006D006F002D006F00630073002D00720032002E0063006F0073006D006F002E006C006F00630061006C000500160063006F0073006D006F002E006C006F00630061006C0000000000
574 hi_response_version: 1
575 time: 59519A1727B9CA01 - Mon Mar 01 10:08:08 2010
576 client_challenge: D6AE875CB0FDAA41
577 MsvAvNbDomainName: COSMO
578 MsvAvNbComputerName: COSMO-OCS-R2
579 MsvAvDnsDomainName: cosmo.local
580 MsvAvDnsComputerName: cosmo-ocs-r2.cosmo.local
581 MsvAvDnsTreeName: cosmo.local
582 ----------- end of nt_resp v2 -----------
586 session_key: 31CB739E1CA80A498591E8AE797115E4
589 const char *request
=
590 "REGISTER sip:cosmo.local SIP/2.0\r\n"
591 "Via: SIP/2.0/TLS 192.168.172.6:12723\r\n"
592 "Max-Forwards: 70\r\n"
593 "From: <sip:user@cosmo.local>;tag=3e49177a52;epid=c8ca638a15\r\n"
594 "To: <sip:user@cosmo.local>\r\n"
595 "Call-ID: 4037df9284354df39065195bd57a4b14\r\n"
596 "CSeq: 3 REGISTER\r\n"
597 "Contact: <sip:192.168.172.6:12723;transport=tls;ms-opaque=fad3dfab32>;methods=\"INVITE, MESSAGE, INFO, OPTIONS, BYE, CANCEL, NOTIFY, ACK, REFER, BENOTIFY\";proxy=replace;+sip.instance=\"<urn:uuid:34D859DB-6585-5F91-A3B4-DE853C15347D>\"\r\n"
598 "User-Agent: UCCAPI/3.5.6907.0 OC/3.5.6907.0 (Microsoft Office Communicator 2007 R2)\r\n"
599 "Supported: gruu-10, adhoclist, msrtc-event-categories\r\n"
600 "Supported: ms-forking\r\n"
601 "ms-keep-alive: UAC;hop-hop=yes\r\n"
602 "Event: registration\r\n"
603 "Proxy-Authorization: NTLM qop=\"auth\", realm=\"SIP Communications Service\", opaque=\"2BDBAC9D\", targetname=\"cosmo-ocs-r2.cosmo.local\", version=4, gssapi-data=\"TlRMTVNTUAADAAAAGAAYAHIAAADGAMYAigAAAAoACgBIAAAACAAIAFIAAAAYABgAWgAAABAAEABQAQAAVYKYYgUCzg4AAAAPQwBPAFMATQBPAFUAcwBlAHIAQwBPAFMATQBPAC0ATwBDAFMALQBSADIAoeku/k4Hi/fFwASazGFmwtauh1yw/apBjcDIAK527KYG0rn769BHMQEBAAAAAAAAWVGaFye5ygHWrodcsP2qQQAAAAACAAoAQwBPAFMATQBPAAEAGABDAE8AUwBNAE8ALQBPAEMAUwAtAFIAMgAEABYAYwBvAHMAbQBvAC4AbABvAGMAYQBsAAMAMABjAG8AcwBtAG8ALQBvAGMAcwAtAHIAMgAuAGMAbwBzAG0AbwAuAGwAbwBjAGEAbAAFABYAYwBvAHMAbQBvAC4AbABvAGMAYQBsAAAAAAAAAAAAMctznhyoCkmFkeiueXEV5A==\", crand=\"13317733\", cnum=\"1\", response=\"0100000029618e9651b65a7764000000\"\r\n"
604 "Content-Length: 0\r\n"
607 const gchar
*request_sig
= "<NTLM><13317733><1><SIP Communications Service><cosmo-ocs-r2.cosmo.local><4037df9284354df39065195bd57a4b14><3><REGISTER><sip:user@cosmo.local><3e49177a52><sip:user@cosmo.local><><><><>";
609 //0100000029618e9651b65a7764000000
611 const char *response
=
613 "ms-keep-alive: UAS; tcp=no; hop-hop=yes; end-end=no; timeout=300\r\n"
614 "Authentication-Info: NTLM rspauth=\"01000000E615438A917661BE64000000\", srand=\"9616454F\", snum=\"1\", opaque=\"2BDBAC9D\", qop=\"auth\", targetname=\"cosmo-ocs-r2.cosmo.local\", realm=\"SIP Communications Service\"\r\n"
615 "From: \"User\"<sip:user@cosmo.local>;tag=3e49177a52;epid=c8ca638a15\r\n"
616 "To: <sip:user@cosmo.local>;tag=5E61CCD925D17E043D9A74835A88F664\r\n"
617 "Call-ID: 4037df9284354df39065195bd57a4b14\r\n"
618 "CSeq: 3 REGISTER\r\n"
619 "Via: SIP/2.0/TLS 192.168.172.6:12723;ms-received-port=12723;ms-received-cid=2600\r\n"
620 "Contact: <sip:192.168.172.6:12723;transport=tls;ms-opaque=fad3dfab32;ms-received-cid=2600>;expires=7200;+sip.instance=\"<urn:uuid:34d859db-6585-5f91-a3b4-de853c15347d>\";gruu=\"sip:user@cosmo.local;opaque=user:epid:21nYNIVlkV-jtN6FPBU0fQAA;gruu\"\r\n"
622 "presence-state: register-action=\"added\"\r\n"
623 "Allow-Events: vnd-microsoft-provisioning,vnd-microsoft-roaming-contacts,vnd-microsoft-roaming-ACL,presence,presence.wpending,vnd-microsoft-roaming-self,vnd-microsoft-provisioning-v2\r\n"
624 "Supported: adhoclist\r\n"
625 "Server: RTC/3.5\r\n"
626 "Supported: msrtc-event-categories\r\n"
627 "Content-Length: 0\r\n"
630 const gchar
*response_sig
= "<NTLM><9616454F><1><SIP Communications Service><cosmo-ocs-r2.cosmo.local><4037df9284354df39065195bd57a4b14><3><REGISTER><sip:user@cosmo.local><3e49177a52><sip:user@cosmo.local><5E61CCD925D17E043D9A74835A88F664><><><7200><200>";
632 //01000000E615438A917661BE64000000
636 | NTLMSSP_NEGOTIATE_UNICODE
637 | NTLMSSP_REQUEST_TARGET
638 | NTLMSSP_NEGOTIATE_SIGN
639 | NTLMSSP_NEGOTIATE_DATAGRAM
640 | NTLMSSP_NEGOTIATE_NTLM
641 | NTLMSSP_NEGOTIATE_ALWAYS_SIGN
642 | NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY
643 | NTLMSSP_NEGOTIATE_IDENTIFY
644 | NTLMSSP_NEGOTIATE_TARGET_INFO
645 | NTLMSSP_NEGOTIATE_VERSION
646 | NTLMSSP_NEGOTIATE_128
647 | NTLMSSP_NEGOTIATE_KEY_EXCH
;
650 test_version
.product_major_version
= 5;
651 test_version
.product_minor_version
= 2;
652 test_version
.product_build
= 3790;
653 test_version
.ntlm_revision_current
= 0x0F;
655 NTOWFv2 (password2
, user2
, domain2
, response_key_nt
);
656 NTOWFv2 (password2
, user2
, domain2
, response_key_lm
);
659 hex_str_to_buff("59519A1727B9CA01", &buff2
);
661 test_time_val
= GUINT64_FROM_LE(*((guint64
*)buff2
));
664 guint8
*target_info2
;
665 const int target_info2_len
= hex_str_to_buff("02000A0043004F0053004D004F000100180043004F0053004D004F002D004F00430053002D00520032000400160063006F0073006D006F002E006C006F00630061006C000300300063006F0073006D006F002D006F00630073002D00720032002E0063006F0073006D006F002E006C006F00630061006C000500160063006F0073006D006F002E006C006F00630061006C0000000000", &target_info2
);
668 hex_str_to_buff("DD1BAAF4E7E218D1", &nonce2
);
670 hex_str_to_buff("D6AE875CB0FDAA41", &buff2
);
672 memcpy(test_client_challenge
, buff2
, 8);
675 ntlmssp_nt_resp_len
= (16 + (32+target_info2_len
));
676 guchar nt_challenge_response_v2_2
[ntlmssp_nt_resp_len
];
678 printf ("\n\nTesting (NTLMv2 / OC 2007 R2) LM Response Generation\n");
679 printf ( "Testing (NTLMv2 / OC 2007 R2) NT Response Generation\n");
680 compute_response(flags
,
684 test_client_challenge
,
686 target_info2
, /* target_info */
687 target_info2_len
, /* target_info_len */
688 lm_challenge_response
, /* out */
689 nt_challenge_response_v2_2
, /* out */
690 session_base_key
); /* out */
692 g_free(target_info2
);
694 assert_equal("A1E92EFE4E078BF7C5C0049ACC6166C2D6AE875CB0FDAA41", lm_challenge_response
, 24, TRUE
);
695 assert_equal("8DC0C800AE76ECA606D2B9FBEBD04731", nt_challenge_response_v2_2
, 16, TRUE
);
696 /* the ref string is taken from binary dump of AUTHENTICATE_MESSAGE */
697 assert_equal("8DC0C800AE76ECA606D2B9FBEBD04731010100000000000059519A1727B9CA01D6AE875CB0FDAA410000000002000A0043004F0053004D004F000100180043004F0053004D004F002D004F00430053002D00520032000400160063006F0073006D006F002E006C006F00630061006C000300300063006F0073006D006F002D006F00630073002D00720032002E0063006F0073006D006F002E006C006F00630061006C000500160063006F0073006D006F002E006C006F00630061006C000000000000000000", nt_challenge_response_v2_2
, ntlmssp_nt_resp_len
, TRUE
);
699 KXKEY(flags
, session_base_key
, lm_challenge_response
, nonce2
, key_exchange_key
);
700 //as in the Type3 message
701 guint8
*encrypted_random_session_key2
;
702 hex_str_to_buff("31CB739E1CA80A498591E8AE797115E4", &encrypted_random_session_key2
);
703 /* Global buff - test_random_session_key */
704 //decoding exported_session_key
705 RC4K (key_exchange_key
, 16, encrypted_random_session_key2
, 16, test_random_session_key
);
706 g_free(encrypted_random_session_key2
);
708 guchar server_sign_key
[16];
709 guchar server_seal_key
[16];
710 SIGNKEY (test_random_session_key
, TRUE
, client_sign_key
);
711 SEALKEY (flags
, test_random_session_key
, TRUE
, client_seal_key
);
712 SIGNKEY (test_random_session_key
, FALSE
, server_sign_key
);
713 SEALKEY (flags
, test_random_session_key
, FALSE
, server_seal_key
);
715 printf ("\n\nTesting (NTLMv2 / OC 2007 R2) Message Parsing, Signing, and Verification\nClient request\n(Authentication Protocol version 4)\n");
716 msg
= sipmsg_parse_msg(request
);
718 sipmsg_breakdown_parse(&msgbd
, "SIP Communications Service", "cosmo-ocs-r2.cosmo.local");
719 msg_str
= sipmsg_breakdown_get_string(4, &msgbd
);
720 assert_equal (request_sig
, (guchar
*)msg_str
, strlen(request_sig
), FALSE
);
721 sig
= sip_sec_ntlm_sipe_signature_make (flags
, msg_str
, 0, client_sign_key
, client_seal_key
);
722 sipmsg_breakdown_free(&msgbd
);
723 assert_equal ("0100000029618e9651b65a7764000000", (guchar
*) sig
,32, FALSE
);
724 printf("purple_ntlm_verify_signature result = %i\n", sip_sec_ntlm_verify_signature (sig
, "0100000029618e9651b65a7764000000"));
726 printf ("\n\nTesting (NTLMv2 / OC 2007 R2) Message Parsing, Signing, and Verification\nServer response\n(Authentication Protocol version 4)\n");
727 msg
= sipmsg_parse_msg(response
);
729 sipmsg_breakdown_parse(&msgbd
, "SIP Communications Service", "cosmo-ocs-r2.cosmo.local");
730 msg_str
= sipmsg_breakdown_get_string(4, &msgbd
);
731 assert_equal (response_sig
, (guchar
*)msg_str
, strlen(response_sig
), FALSE
);
733 sig
= sip_sec_ntlm_sipe_signature_make (flags
, msg_str
, 0, server_sign_key
, server_seal_key
);
734 sipmsg_breakdown_free(&msgbd
);
735 assert_equal ("01000000E615438A917661BE64000000", (guchar
*) sig
,32, FALSE
);
736 printf("purple_ntlm_verify_signature result = %i\n", sip_sec_ntlm_verify_signature (sig
, "01000000E615438A917661BE64000000"));
738 printf ("\n\nTesting (NTLMv2 / OC 2007 R2) MAC - client signing\n");
739 mac
= MAC (flags
, (gchar
*)request_sig
,strlen(request_sig
), client_sign_key
,16, client_seal_key
,16, 0, 100);
740 assert_equal("0100000029618e9651b65a7764000000", (guchar
*)mac
, 32, FALSE
);
743 printf ("\n\nTesting (NTLMv2 / OC 2007 R2) MAC - server's verifying\n");
744 mac
= MAC (flags
, (gchar
*)response_sig
,strlen(response_sig
), server_sign_key
,16, server_seal_key
,16, 0, 100);
745 assert_equal("01000000E615438A917661BE64000000", (guchar
*)mac
, 32, FALSE
);
748 printf ("\n\nTesting (NTLMv2 / OC 2007 R2) Type3 generation test\n");
749 guchar
*client_sign_key2
;
750 guchar
*server_sign_key2
;
751 guchar
*client_seal_key2
;
752 guchar
*server_seal_key2
;
754 guchar
*server_challenge
= NULL
;
755 guint64 time_val2
= 0;
756 guchar
*target_info3
= NULL
;
757 int target_info3_len
= 0;
759 SipSecBuffer in_buff
;
760 SipSecBuffer out_buff
;
762 in_buff
.length
= hex_str_to_buff(type2_hex
, (guint8
**)&(in_buff
.value
));
764 sip_sec_ntlm_parse_challenge(in_buff
,
772 sip_sec_ntlm_gen_authenticate(&client_sign_key2
,
788 g_free(server_challenge
);
789 g_free(target_info3
);
791 assert_equal(type3_hex
, out_buff
.value
, out_buff
.length
, TRUE
);
793 ////// UUID tests ///////
794 /* begin tests from MS-SIPRE */
796 const char *testEpid
= "01010101";
797 const char *expectedUUID
= "4b1682a8-f968-5701-83fc-7c6741dc6697";
798 gchar
*calcUUID
= generateUUIDfromEPID(testEpid
);
800 printf("\n\nTesting MS-SIPRE UUID derivation\n");
802 assert_equal(expectedUUID
, (guchar
*) calcUUID
, strlen(expectedUUID
), FALSE
);
809 for (i
= 0,j
=0; i
< 6; i
++,j
+=2) {
810 g_sprintf(&nmac
[j
], "%02X", addr
[i
]);
813 printf("Mac: %s\n", g_strdup(nmac
));
815 /* end tests from MS-SIPRE */
817 printf ("\nFinished With Tests; %d successs %d failures\n", successes
, failures
);