6 * Copyright (C) 2008 Novell, Inc.
8 * Implemented with reference to the follow documentation:
9 * - http://davenport.sourceforge.net/ntlm.html
10 * - MS-NLMP: http://msdn.microsoft.com/en-us/library/cc207842.aspx
11 * - MS-SIP : http://msdn.microsoft.com/en-us/library/cc246115.aspx
13 * Build and run with `make tests`
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "sip-internal.h"
35 #include "sipe-sign.h"
38 static int successes
= 0;
39 static int failures
= 0;
41 void assert_equal(char * expected
, char * got
, int len
, gboolean stringify
)
48 for (i
= 0, j
= 0; i
< len
; i
++, j
+=2) {
49 g_sprintf(&to_str
[j
], "%02X", (got
[i
]&0xff));
55 printf("expected: %s\n", expected
);
56 printf("received: %s\n", res
);
58 if (strncmp(expected
, res
, len
) == 0) {
69 printf ("Starting Tests\n");
71 // Initialization that Pidgin would normally do
73 purple_signals_init();
77 purple_ciphers_init();
79 /* These tests are from the MS-SIPE document */
81 char * password
= "Password";
83 char * domain
= "Domain";
84 char nonce
[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
85 char exported_session_key
[] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
87 printf ("\nTesting LMOWFv1()\n");
88 char response_key_lm
[16];
89 LMOWFv1 (password
, user
, domain
, response_key_lm
);
90 assert_equal("E52CAC67419A9A224A3B108F3FA6CB6D", response_key_lm
, 16, TRUE
);
92 printf ("\nTesting LM Response Generation\n");
93 char lm_challenge_response
[24];
94 DESL (response_key_lm
, nonce
, lm_challenge_response
);
95 assert_equal("98DEF7B87F88AA5DAFE2DF779688A172DEF11C7D5CCDEF13", lm_challenge_response
, 24, TRUE
);
97 printf ("\n\nTesting NTOWFv1()\n");
98 char response_key_nt
[16];
99 NTOWFv1 (password
, user
, domain
, response_key_nt
);
100 assert_equal("A4F49C406510BDCAB6824EE7C30FD852", response_key_nt
, 16, TRUE
);
102 printf ("\nTesting NT Response Generation\n");
103 char nt_challenge_response
[24];
104 DESL (response_key_nt
, nonce
, nt_challenge_response
);
105 assert_equal("67C43011F30298A2AD35ECE64F16331C44BDBED927841F94", nt_challenge_response
, 24, TRUE
);
107 printf ("\n\nTesting Session Base Key and Key Exchange Generation\n");
108 char session_base_key
[16];
109 MD4(response_key_nt
, 16, session_base_key
);
110 char key_exchange_key
[16];
111 KXKEY(session_base_key
, lm_challenge_response
, key_exchange_key
);
112 assert_equal("D87262B0CDE4B1CB7499BECCCDF10784", session_base_key
, 16, TRUE
);
113 assert_equal("D87262B0CDE4B1CB7499BECCCDF10784", key_exchange_key
, 16, TRUE
);
115 printf ("\n\nTesting Encrypted Session Key Generation\n");
116 char encrypted_random_session_key
[16];
117 RC4K (key_exchange_key
, exported_session_key
, encrypted_random_session_key
);
118 assert_equal("518822B1B3F350C8958682ECBB3E3CB7", encrypted_random_session_key
, 16, TRUE
);
120 /* End tests from the MS-SIPE document */
122 // Test from http://davenport.sourceforge.net/ntlm.html#ntlm1Signing
123 printf ("\n\nTesting Signature Algorithm\n");
124 char sk
[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0xe5, 0x38, 0xb0};
126 "0100000078010900397420FE0E5A0F89",
127 purple_ntlm_gen_signature ("jCIFS", sk
, 0x00090178, 0, 8),
131 // Verify signature of SIPE message received from OCS 2007 after authenticating with pidgin-sipe
132 printf ("\n\nTesting MS-SIPE Example Message Signing\n");
133 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>";
134 char exported_session_key2
[] = { 0x5F, 0x02, 0x91, 0x53, 0xBC, 0x02, 0x50, 0x58, 0x96, 0x95, 0x48, 0x61, 0x5E, 0x70, 0x99, 0xBA };
136 "0100000000000000BF2E52667DDF6DED",
137 purple_ntlm_gen_signature(msg1
, exported_session_key2
, 0, 100, 16),
141 // Verify parsing of message and signature verification
142 printf ("\n\nTesting MS-SIPE Example Message Parsing, Signing, and Verification\n");
143 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";
144 struct sipmsg
* msg
= sipmsg_parse_msg(msg2
);
145 struct sipmsg_breakdown msgbd
;
147 sipmsg_breakdown_parse(&msgbd
, "SIP Communications Service", "ocs1.ocs.provo.novell.com");
148 gchar
* msg_str
= sipmsg_breakdown_get_string(&msgbd
);
149 gchar
* sig
= purple_ntlm_sipe_signature_make (msg_str
, exported_session_key2
);
150 sipmsg_breakdown_free(&msgbd
);
151 assert_equal ("0100000000000000BF2E52667DDF6DED", sig
, 32, FALSE
);
152 printf("purple_ntlm_verify_signature result = %i\n", purple_ntlm_verify_signature (sig
, "0100000000000000BF2E52667DDF6DED"));
154 printf ("\nFinished With Tests; %d successs %d failures\n", successes
, failures
);