1*1c9681d1Schristos /*	$NetBSD: test_ntlm.c,v 1.2 2017/01/28 21:31:49 christos Exp $	*/
2f59d82ffSelric 
3f59d82ffSelric /*
4f59d82ffSelric  * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
5f59d82ffSelric  * (Royal Institute of Technology, Stockholm, Sweden).
6f59d82ffSelric  * All rights reserved.
7f59d82ffSelric  *
8f59d82ffSelric  * Redistribution and use in source and binary forms, with or without
9f59d82ffSelric  * modification, are permitted provided that the following conditions
10f59d82ffSelric  * are met:
11f59d82ffSelric  *
12f59d82ffSelric  * 1. Redistributions of source code must retain the above copyright
13f59d82ffSelric  *    notice, this list of conditions and the following disclaimer.
14f59d82ffSelric  *
15f59d82ffSelric  * 2. Redistributions in binary form must reproduce the above copyright
16f59d82ffSelric  *    notice, this list of conditions and the following disclaimer in the
17f59d82ffSelric  *    documentation and/or other materials provided with the distribution.
18f59d82ffSelric  *
19f59d82ffSelric  * 3. Neither the name of KTH nor the names of its contributors may be
20f59d82ffSelric  *    used to endorse or promote products derived from this software without
21f59d82ffSelric  *    specific prior written permission.
22f59d82ffSelric  *
23f59d82ffSelric  * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
24f59d82ffSelric  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25f59d82ffSelric  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26f59d82ffSelric  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
27f59d82ffSelric  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28f59d82ffSelric  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29f59d82ffSelric  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30f59d82ffSelric  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31f59d82ffSelric  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32f59d82ffSelric  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33f59d82ffSelric  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34f59d82ffSelric  */
35f59d82ffSelric 
36f59d82ffSelric #include "config.h"
37f59d82ffSelric 
38f59d82ffSelric #include <stdio.h>
39f59d82ffSelric #include <err.h>
40f59d82ffSelric #include <krb5/roken.h>
41f59d82ffSelric #include <krb5/getarg.h>
42f59d82ffSelric 
43f59d82ffSelric #include <krb5/krb5-types.h> /* or <inttypes.h> */
44f59d82ffSelric #include <krb5/heimntlm.h>
45f59d82ffSelric 
46e0895134Schristos static int dumpdata_flag;
47e0895134Schristos 
48f59d82ffSelric static int
test_parse(void)49f59d82ffSelric test_parse(void)
50f59d82ffSelric {
51f59d82ffSelric     const char *user = "foo",
52f59d82ffSelric 	*domain = "mydomain",
53e0895134Schristos 	*hostname = "myhostname",
54f59d82ffSelric 	*password = "digestpassword",
55f59d82ffSelric 	*target = "DOMAIN";
56f59d82ffSelric     struct ntlm_type1 type1;
57f59d82ffSelric     struct ntlm_type2 type2;
58f59d82ffSelric     struct ntlm_type3 type3;
59f59d82ffSelric     struct ntlm_buf data;
60f59d82ffSelric     int ret, flags;
61f59d82ffSelric 
62f59d82ffSelric     memset(&type1, 0, sizeof(type1));
63f59d82ffSelric 
64e0895134Schristos     type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_TARGET|NTLM_NEG_NTLM|NTLM_NEG_VERSION;
65f59d82ffSelric     type1.domain = rk_UNCONST(domain);
66e0895134Schristos     type1.hostname = rk_UNCONST(hostname);
67f59d82ffSelric     type1.os[0] = 0;
68f59d82ffSelric     type1.os[1] = 0;
69f59d82ffSelric 
70f59d82ffSelric     ret = heim_ntlm_encode_type1(&type1, &data);
71f59d82ffSelric     if (ret)
72f59d82ffSelric 	errx(1, "heim_ntlm_encode_type1");
73f59d82ffSelric 
74f59d82ffSelric     memset(&type1, 0, sizeof(type1));
75f59d82ffSelric 
76e0895134Schristos     if (dumpdata_flag)
77e0895134Schristos 	rk_dumpdata("ntlm-type1", data.data, data.length);
78e0895134Schristos 
79f59d82ffSelric     ret = heim_ntlm_decode_type1(&data, &type1);
80f59d82ffSelric     free(data.data);
81f59d82ffSelric     if (ret)
82f59d82ffSelric 	errx(1, "heim_ntlm_encode_type1");
83f59d82ffSelric 
84e0895134Schristos     if (strcmp(type1.domain, domain) != 0)
85e0895134Schristos 	errx(1, "parser got domain wrong: %s", type1.domain);
86e0895134Schristos 
87e0895134Schristos     if (strcmp(type1.hostname, hostname) != 0)
88e0895134Schristos 	errx(1, "parser got hostname wrong: %s", type1.hostname);
89e0895134Schristos 
90f59d82ffSelric     heim_ntlm_free_type1(&type1);
91f59d82ffSelric 
92f59d82ffSelric     /*
93f59d82ffSelric      *
94f59d82ffSelric      */
95f59d82ffSelric 
96f59d82ffSelric     memset(&type2, 0, sizeof(type2));
97f59d82ffSelric 
98f59d82ffSelric     flags = NTLM_NEG_UNICODE | NTLM_NEG_NTLM | NTLM_TARGET_DOMAIN;
99f59d82ffSelric     type2.flags = flags;
100f59d82ffSelric 
101f59d82ffSelric     memset(type2.challenge, 0x7f, sizeof(type2.challenge));
102f59d82ffSelric     type2.targetname = rk_UNCONST(target);
103f59d82ffSelric     type2.targetinfo.data = NULL;
104f59d82ffSelric     type2.targetinfo.length = 0;
105f59d82ffSelric 
106f59d82ffSelric     ret = heim_ntlm_encode_type2(&type2, &data);
107f59d82ffSelric     if (ret)
108f59d82ffSelric 	errx(1, "heim_ntlm_encode_type2");
109f59d82ffSelric 
110f59d82ffSelric     memset(&type2, 0, sizeof(type2));
111f59d82ffSelric 
112e0895134Schristos     if (dumpdata_flag)
113e0895134Schristos 	rk_dumpdata("ntlm-type2", data.data, data.length);
114e0895134Schristos 
115f59d82ffSelric     ret = heim_ntlm_decode_type2(&data, &type2);
116f59d82ffSelric     free(data.data);
117f59d82ffSelric     if (ret)
118f59d82ffSelric 	errx(1, "heim_ntlm_decode_type2");
119f59d82ffSelric 
120f59d82ffSelric     heim_ntlm_free_type2(&type2);
121f59d82ffSelric 
122f59d82ffSelric     /*
123f59d82ffSelric      *
124f59d82ffSelric      */
125f59d82ffSelric 
126f59d82ffSelric     memset(&type3, 0, sizeof(type3));
127f59d82ffSelric 
128f59d82ffSelric     type3.flags = flags;
129f59d82ffSelric     type3.username = rk_UNCONST(user);
130f59d82ffSelric     type3.targetname = rk_UNCONST(target);
131f59d82ffSelric     type3.ws = rk_UNCONST("workstation");
132f59d82ffSelric 
133f59d82ffSelric     {
134f59d82ffSelric 	struct ntlm_buf key;
135f59d82ffSelric 	heim_ntlm_nt_key(password, &key);
136f59d82ffSelric 
137f59d82ffSelric 	heim_ntlm_calculate_ntlm1(key.data, key.length,
138f59d82ffSelric 				  type2.challenge,
139f59d82ffSelric 				  &type3.ntlm);
140f59d82ffSelric 	free(key.data);
141f59d82ffSelric     }
142f59d82ffSelric 
143e0895134Schristos     ret = heim_ntlm_encode_type3(&type3, &data, NULL);
144f59d82ffSelric     if (ret)
145f59d82ffSelric 	errx(1, "heim_ntlm_encode_type3");
146f59d82ffSelric 
147f59d82ffSelric     free(type3.ntlm.data);
148f59d82ffSelric 
149f59d82ffSelric     memset(&type3, 0, sizeof(type3));
150f59d82ffSelric 
151e0895134Schristos     if (dumpdata_flag)
152e0895134Schristos 	rk_dumpdata("ntlm-type3", data.data, data.length);
153e0895134Schristos 
154f59d82ffSelric     ret = heim_ntlm_decode_type3(&data, 1, &type3);
155f59d82ffSelric     free(data.data);
156f59d82ffSelric     if (ret)
157f59d82ffSelric 	errx(1, "heim_ntlm_decode_type3");
158f59d82ffSelric 
159f59d82ffSelric     if (strcmp("workstation", type3.ws) != 0)
160f59d82ffSelric 	errx(1, "type3 ws wrong");
161f59d82ffSelric 
162f59d82ffSelric     if (strcmp(target, type3.targetname) != 0)
163f59d82ffSelric 	errx(1, "type3 targetname wrong");
164f59d82ffSelric 
165f59d82ffSelric     if (strcmp(user, type3.username) != 0)
166f59d82ffSelric 	errx(1, "type3 username wrong");
167f59d82ffSelric 
168f59d82ffSelric 
169f59d82ffSelric     heim_ntlm_free_type3(&type3);
170f59d82ffSelric 
171f59d82ffSelric     /*
172f59d82ffSelric      * NTLMv2
173f59d82ffSelric      */
174f59d82ffSelric 
175f59d82ffSelric     memset(&type2, 0, sizeof(type2));
176f59d82ffSelric 
177f59d82ffSelric     flags = NTLM_NEG_UNICODE | NTLM_NEG_NTLM | NTLM_TARGET_DOMAIN;
178f59d82ffSelric     type2.flags = flags;
179f59d82ffSelric 
180f59d82ffSelric     memset(type2.challenge, 0x7f, sizeof(type2.challenge));
181f59d82ffSelric     type2.targetname = rk_UNCONST(target);
182f59d82ffSelric     type2.targetinfo.data = "\x00\x00";
183f59d82ffSelric     type2.targetinfo.length = 2;
184f59d82ffSelric 
185f59d82ffSelric     ret = heim_ntlm_encode_type2(&type2, &data);
186f59d82ffSelric     if (ret)
187f59d82ffSelric 	errx(1, "heim_ntlm_encode_type2");
188f59d82ffSelric 
189f59d82ffSelric     memset(&type2, 0, sizeof(type2));
190f59d82ffSelric 
191f59d82ffSelric     ret = heim_ntlm_decode_type2(&data, &type2);
192f59d82ffSelric     free(data.data);
193f59d82ffSelric     if (ret)
194f59d82ffSelric 	errx(1, "heim_ntlm_decode_type2");
195f59d82ffSelric 
196f59d82ffSelric     heim_ntlm_free_type2(&type2);
197f59d82ffSelric 
198f59d82ffSelric     return 0;
199f59d82ffSelric }
200f59d82ffSelric 
201f59d82ffSelric static int
test_keys(void)202f59d82ffSelric test_keys(void)
203f59d82ffSelric {
204f59d82ffSelric     const char
205f59d82ffSelric 	*username = "test",
206f59d82ffSelric 	*password = "test1234",
207f59d82ffSelric 	*target = "TESTNT";
208f59d82ffSelric     const unsigned char
209f59d82ffSelric 	serverchallenge[8] = "\x67\x7f\x1c\x55\x7a\x5e\xe9\x6c";
210f59d82ffSelric     struct ntlm_buf infotarget, infotarget2, answer, key;
211f59d82ffSelric     unsigned char ntlmv2[16], ntlmv2_1[16];
212f59d82ffSelric     int ret;
213f59d82ffSelric 
214f59d82ffSelric     infotarget.length = 70;
215f59d82ffSelric     infotarget.data =
216f59d82ffSelric 	"\x02\x00\x0c\x00\x54\x00\x45\x00\x53\x00\x54\x00\x4e\x00\x54\x00"
217f59d82ffSelric 	"\x01\x00\x0c\x00\x4d\x00\x45\x00\x4d\x00\x42\x00\x45\x00\x52\x00"
218f59d82ffSelric 	"\x03\x00\x1e\x00\x6d\x00\x65\x00\x6d\x00\x62\x00\x65\x00\x72\x00"
219f59d82ffSelric 	    "\x2e\x00\x74\x00\x65\x00\x73\x00\x74\x00\x2e\x00\x63\x00\x6f"
220f59d82ffSelric 	    "\x00\x6d\x00"
221f59d82ffSelric 	"\x00\x00\x00\x00";
222f59d82ffSelric 
223f59d82ffSelric     answer.length = 0;
224f59d82ffSelric     answer.data = NULL;
225f59d82ffSelric 
226f59d82ffSelric     heim_ntlm_nt_key(password, &key);
227f59d82ffSelric 
228f59d82ffSelric     ret = heim_ntlm_calculate_ntlm2(key.data,
229f59d82ffSelric 				    key.length,
230f59d82ffSelric 				    username,
231f59d82ffSelric 				    target,
232f59d82ffSelric 				    serverchallenge,
233f59d82ffSelric 				    &infotarget,
234f59d82ffSelric 				    ntlmv2,
235f59d82ffSelric 				    &answer);
236f59d82ffSelric     if (ret)
237f59d82ffSelric 	errx(1, "heim_ntlm_calculate_ntlm2");
238f59d82ffSelric 
239f59d82ffSelric     ret = heim_ntlm_verify_ntlm2(key.data,
240f59d82ffSelric 				 key.length,
241f59d82ffSelric 				 username,
242f59d82ffSelric 				 target,
243f59d82ffSelric 				 0,
244f59d82ffSelric 				 serverchallenge,
245f59d82ffSelric 				 &answer,
246f59d82ffSelric 				 &infotarget2,
247f59d82ffSelric 				 ntlmv2_1);
248f59d82ffSelric     if (ret)
249f59d82ffSelric 	errx(1, "heim_ntlm_verify_ntlm2");
250f59d82ffSelric 
251f59d82ffSelric     if (memcmp(ntlmv2, ntlmv2_1, sizeof(ntlmv2)) != 0)
252f59d82ffSelric 	errx(1, "ntlm master key not same");
253f59d82ffSelric 
254f59d82ffSelric     if (infotarget.length > infotarget2.length)
255f59d82ffSelric 	errx(1, "infotarget length");
256f59d82ffSelric 
257f59d82ffSelric     if (memcmp(infotarget.data, infotarget2.data, infotarget.length) != 0)
258f59d82ffSelric 	errx(1, "infotarget not the same");
259f59d82ffSelric 
260f59d82ffSelric     free(key.data);
261f59d82ffSelric     free(answer.data);
262f59d82ffSelric     free(infotarget2.data);
263f59d82ffSelric 
264f59d82ffSelric     return 0;
265f59d82ffSelric }
266f59d82ffSelric 
267f59d82ffSelric static int
test_ntlm2_session_resp(void)268f59d82ffSelric test_ntlm2_session_resp(void)
269f59d82ffSelric {
270f59d82ffSelric     int ret;
271f59d82ffSelric     struct ntlm_buf lm, ntlm;
272f59d82ffSelric 
273f59d82ffSelric     const unsigned char lm_resp[24] =
274f59d82ffSelric 	"\xff\xff\xff\x00\x11\x22\x33\x44"
275f59d82ffSelric 	"\x00\x00\x00\x00\x00\x00\x00\x00"
276f59d82ffSelric 	"\x00\x00\x00\x00\x00\x00\x00\x00";
277f59d82ffSelric     const unsigned char ntlm2_sess_resp[24] =
278f59d82ffSelric 	"\x10\xd5\x50\x83\x2d\x12\xb2\xcc"
279f59d82ffSelric 	"\xb7\x9d\x5a\xd1\xf4\xee\xd3\xdf"
280f59d82ffSelric 	"\x82\xac\xa4\xc3\x68\x1d\xd4\x55";
281f59d82ffSelric 
282f59d82ffSelric     const unsigned char client_nonce[8] =
283f59d82ffSelric 	"\xff\xff\xff\x00\x11\x22\x33\x44";
284f59d82ffSelric     const unsigned char server_challenge[8] =
285f59d82ffSelric 	"\x01\x23\x45\x67\x89\xab\xcd\xef";
286f59d82ffSelric 
287f59d82ffSelric     const unsigned char ntlm_hash[16] =
288f59d82ffSelric 	"\xcd\x06\xca\x7c\x7e\x10\xc9\x9b"
289f59d82ffSelric 	"\x1d\x33\xb7\x48\x5a\x2e\xd8\x08";
290f59d82ffSelric 
291f59d82ffSelric     ret = heim_ntlm_calculate_ntlm2_sess(client_nonce,
292f59d82ffSelric 					 server_challenge,
293f59d82ffSelric 					 ntlm_hash,
294f59d82ffSelric 					 &lm,
295f59d82ffSelric 					 &ntlm);
296f59d82ffSelric     if (ret)
297f59d82ffSelric 	errx(1, "heim_ntlm_calculate_ntlm2_sess_resp");
298f59d82ffSelric 
299f59d82ffSelric     if (lm.length != 24 || memcmp(lm.data, lm_resp, 24) != 0)
300f59d82ffSelric 	errx(1, "lm_resp wrong");
301f59d82ffSelric     if (ntlm.length != 24 || memcmp(ntlm.data, ntlm2_sess_resp, 24) != 0)
302f59d82ffSelric 	errx(1, "ntlm2_sess_resp wrong");
303f59d82ffSelric 
304f59d82ffSelric     free(lm.data);
305f59d82ffSelric     free(ntlm.data);
306f59d82ffSelric 
307f59d82ffSelric 
308f59d82ffSelric     return 0;
309f59d82ffSelric }
310f59d82ffSelric 
311f59d82ffSelric static int
test_ntlmv2(void)312e0895134Schristos test_ntlmv2(void)
313e0895134Schristos {
314e0895134Schristos     unsigned char type3[413] =
315e0895134Schristos 	"\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00"
316e0895134Schristos 	"\x80\x00\x00\x00\x9e\x00\x9e\x00\x98\x00\x00\x00\x14\x00\x14\x00"
317e0895134Schristos 	"\x48\x00\x00\x00\x10\x00\x10\x00\x5c\x00\x00\x00\x14\x00\x14\x00"
318e0895134Schristos 	"\x6c\x00\x00\x00\x00\x00\x00\x00\x36\x01\x00\x00\x05\x82\x88\xa2"
319e0895134Schristos 	"\x05\x01\x28\x0a\x00\x00\x00\x0f\x43\x00\x4f\x00\x4c\x00\x4c\x00"
320e0895134Schristos 	"\x45\x00\x59\x00\x2d\x00\x58\x00\x50\x00\x34\x00\x54\x00\x45\x00"
321e0895134Schristos 	"\x53\x00\x54\x00\x55\x00\x53\x00\x45\x00\x52\x00\x43\x00\x4f\x00"
322e0895134Schristos 	"\x4c\x00\x4c\x00\x45\x00\x59\x00\x2d\x00\x58\x00\x50\x00\x34\x00"
323e0895134Schristos 	"\x2f\x96\xec\x0a\xf7\x9f\x2e\x24\xba\x09\x48\x10\xa5\x22\xd4\xe1"
324e0895134Schristos 	"\x16\x6a\xca\x58\x74\x9a\xc1\x4f\x54\x6f\xee\x40\x96\xce\x43\x6e"
325e0895134Schristos 	"\xdf\x99\x20\x71\x6c\x9a\xda\x2a\x01\x01\x00\x00\x00\x00\x00\x00"
326e0895134Schristos 	"\x8d\xc0\x57\xc9\x79\x5e\xcb\x01\x16\x6a\xca\x58\x74\x9a\xc1\x4f"
327e0895134Schristos 	"\x00\x00\x00\x00\x02\x00\x14\x00\x4e\x00\x55\x00\x54\x00\x43\x00"
328e0895134Schristos 	"\x52\x00\x41\x00\x43\x00\x4b\x00\x45\x00\x52\x00\x01\x00\x14\x00"
329e0895134Schristos 	"\x4e\x00\x55\x00\x54\x00\x43\x00\x52\x00\x41\x00\x43\x00\x4b\x00"
330e0895134Schristos 	"\x45\x00\x52\x00\x04\x00\x12\x00\x61\x00\x70\x00\x70\x00\x6c\x00"
331e0895134Schristos 	"\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x03\x00\x20\x00\x68\x00"
332e0895134Schristos 	"\x75\x00\x6d\x00\x6d\x00\x65\x00\x6c\x00\x2e\x00\x61\x00\x70\x00"
333e0895134Schristos 	"\x70\x00\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x00\x00"
334e0895134Schristos 	"\x00\x00\x00\x00\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f"
335e0895134Schristos 	"\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20"
336e0895134Schristos 	"\x00\x53\x00\x65\x00\x72\x00\x76\x00\x69\x00\x63\x00\x65\x00\x20"
337e0895134Schristos 	"\x00\x50\x00\x61\x00\x63\x00\x6b\x00\x20\x00\x33\x00\x20\x00\x32"
338e0895134Schristos 	"\x00\x36\x00\x30\x00\x30\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64"
339e0895134Schristos 	"\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32"
340e0895134Schristos 	"\x00\x20\x00\x35\x00\x2e\x00\x31\x00\x00\x00\x00\x00";
341e0895134Schristos     const unsigned char challenge[8] =
342e0895134Schristos 	"\xe4\x9c\x6a\x12\xe1\xbd\xde\x6a";
343e0895134Schristos     unsigned char sessionkey[16];
344e0895134Schristos 
345e0895134Schristos     const char key[16] = "\xD1\x83\x98\x3E\xAE\xA7\xBE\x99\x59\xC8\xF4\xC1\x98\xED\x0E\x68";
346e0895134Schristos 
347e0895134Schristos     struct ntlm_buf data;
348e0895134Schristos     struct ntlm_type3 t3;
349e0895134Schristos     int ret;
350e0895134Schristos 
351e0895134Schristos     struct ntlm_targetinfo ti;
352e0895134Schristos 
353e0895134Schristos     unsigned char timsg[114] =
354e0895134Schristos 	"\002\000\024\000N\000U\000T\000C\000R\000A\000C\000K\000E\000R\000\001\000\024\000N\000U\000T\000C\000R\000A\000C\000K\000E\000R\000\004\000\022\000a\000p\000p\000l\000e\000.\000c\000o\000m\000\003\000 \000h\000u\000m\000m\000e\000l\000.\000a\000p\000p\000l\000e\000.\000c\000o\000m\000\000\000\000\000\000\000\000";
355e0895134Schristos 
356e0895134Schristos 
357e0895134Schristos     data.data = type3;
358e0895134Schristos     data.length = sizeof(type3);
359e0895134Schristos 
360e0895134Schristos     ret = heim_ntlm_decode_type3(&data, 1, &t3);
361e0895134Schristos     if (ret)
362e0895134Schristos 	errx(1, "heim_ntlm_decode_type3");
363e0895134Schristos 
364e0895134Schristos     memset(&ti, 0, sizeof(ti));
365e0895134Schristos 
366e0895134Schristos     data.data = timsg;
367e0895134Schristos     data.length = sizeof(timsg);
368e0895134Schristos 
369e0895134Schristos     ret = heim_ntlm_decode_targetinfo(&data, 1, &ti);
370e0895134Schristos     if (ret)
371e0895134Schristos 	return ret;
372e0895134Schristos 
373e0895134Schristos     ret = heim_ntlm_verify_ntlm2(key, sizeof(key),
374e0895134Schristos 				 t3.username,
375e0895134Schristos 				 t3.targetname,
376e0895134Schristos 				 1285615547,
377e0895134Schristos 				 challenge,
378e0895134Schristos 				 &t3.ntlm,
379e0895134Schristos 				 &data,
380e0895134Schristos 				 sessionkey);
381e0895134Schristos     if (ret)
382e0895134Schristos 	errx(1, "verify_ntlmv2");
383e0895134Schristos 
384e0895134Schristos     if (sizeof(timsg) != data.length || memcmp(timsg, data.data, sizeof(timsg)) != 0)
385e0895134Schristos 	errx(1, "target info wrong: %d != %d",
386e0895134Schristos 	     (int)sizeof(timsg), (int)data.length);
387e0895134Schristos 
388e0895134Schristos     heim_ntlm_free_type3(&t3);
389e0895134Schristos     heim_ntlm_free_targetinfo(&ti);
390e0895134Schristos 
391e0895134Schristos     return 0;
392e0895134Schristos }
393e0895134Schristos 
394e0895134Schristos static int
test_targetinfo(void)395f59d82ffSelric test_targetinfo(void)
396f59d82ffSelric {
397f59d82ffSelric     struct ntlm_targetinfo ti;
398f59d82ffSelric     struct ntlm_buf buf;
399f59d82ffSelric     const char *dnsservername = "dnsservername";
400e0895134Schristos     const char *targetname = "targetname";
401e0895134Schristos     const char z16[16] = { 0 };
402f59d82ffSelric     int ret;
403f59d82ffSelric 
404f59d82ffSelric     memset(&ti, 0, sizeof(ti));
405f59d82ffSelric 
406f59d82ffSelric     ti.dnsservername = rk_UNCONST(dnsservername);
407f59d82ffSelric     ti.avflags = 1;
408e0895134Schristos     ti.targetname = rk_UNCONST(targetname);
409e0895134Schristos     ti.channel_bindings.data = rk_UNCONST(z16);
410e0895134Schristos     ti.channel_bindings.length = sizeof(z16);
411e0895134Schristos 
412f59d82ffSelric     ret = heim_ntlm_encode_targetinfo(&ti, 1, &buf);
413f59d82ffSelric     if (ret)
414f59d82ffSelric 	return ret;
415f59d82ffSelric 
416f59d82ffSelric     memset(&ti, 0, sizeof(ti));
417f59d82ffSelric 
418f59d82ffSelric     ret = heim_ntlm_decode_targetinfo(&buf, 1, &ti);
419f59d82ffSelric     if (ret)
420f59d82ffSelric 	return ret;
421f59d82ffSelric 
422f59d82ffSelric     if (ti.dnsservername == NULL ||
423f59d82ffSelric 	strcmp(ti.dnsservername, dnsservername) != 0)
424f59d82ffSelric 	errx(1, "ti.dnshostname != %s", dnsservername);
425f59d82ffSelric     if (ti.avflags != 1)
426f59d82ffSelric 	errx(1, "ti.avflags != 1");
427e0895134Schristos     if (ti.targetname == NULL ||
428e0895134Schristos 	strcmp(ti.targetname, targetname) != 0)
429e0895134Schristos 	errx(1, "ti.targetname != %s", targetname);
430e0895134Schristos 
431e0895134Schristos     if (ti.channel_bindings.length != sizeof(z16) ||
432e0895134Schristos 	memcmp(ti.channel_bindings.data, z16, sizeof(z16)) != 0)
433e0895134Schristos 	errx(1, "ti.channel_bindings != Z(16)");
434f59d82ffSelric 
435f59d82ffSelric     heim_ntlm_free_targetinfo(&ti);
436f59d82ffSelric 
437f59d82ffSelric     return 0;
438f59d82ffSelric }
439f59d82ffSelric 
440e0895134Schristos static int
test_string2key(void)441e0895134Schristos test_string2key(void)
442e0895134Schristos {
443e0895134Schristos     const char *pw = "山田";
444e0895134Schristos     struct ntlm_buf buf;
445e0895134Schristos 
446e0895134Schristos     unsigned char key[16] = {
447e0895134Schristos 	0xc6, 0x5d, 0xc7, 0x61, 0xa1, 0x34, 0x17, 0xa1,
448e0895134Schristos 	0x17, 0x08, 0x9c, 0x1b, 0xb0, 0x0d, 0x0f, 0x19
449e0895134Schristos     };
450e0895134Schristos 
451e0895134Schristos     if (heim_ntlm_nt_key(pw, &buf) != 0)
452e0895134Schristos 	errx(1, "heim_ntlmv_nt_key(jp)");
453e0895134Schristos 
454e0895134Schristos     if (buf.length != 16 || memcmp(buf.data, key, 16) != 0)
455e0895134Schristos 	errx(1, "compare failed");
456e0895134Schristos 
457e0895134Schristos     heim_ntlm_free_buf(&buf);
458e0895134Schristos 
459e0895134Schristos     return 0;
460e0895134Schristos }
461e0895134Schristos 
462e0895134Schristos static int
test_jp(void)463e0895134Schristos test_jp(void)
464e0895134Schristos {
465e0895134Schristos     char buf2[220] =
466e0895134Schristos 	"\x4e\x54\x4c\x4d\x53\x53\x50\x00\x02\x00\x00\x00\x06\x00\x06\x00"
467e0895134Schristos 	"\x38\x00\x00\x00\x05\x02\x89\x62\x62\x94\xb1\xf3\x56\x80\xb0\xf9"
468e0895134Schristos 	"\x00\x00\x00\x00\x00\x00\x00\x00\x9e\x00\x9e\x00\x3e\x00\x00\x00"
469e0895134Schristos 	"\x06\x01\xb0\x1d\x00\x00\x00\x0f\x43\x00\x4f\x00\x53\x00\x02\x00"
470e0895134Schristos 	"\x06\x00\x43\x00\x4f\x00\x53\x00\x01\x00\x12\x00\x43\x00\x4f\x00"
471e0895134Schristos 	"\x53\x00\x57\x00\x49\x00\x4e\x00\x37\x00\x4a\x00\x50\x00\x04\x00"
472e0895134Schristos 	"\x1a\x00\x63\x00\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00"
473e0895134Schristos 	"\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x03\x00\x2e\x00"
474e0895134Schristos 	"\x63\x00\x6f\x00\x73\x00\x77\x00\x69\x00\x6e\x00\x37\x00\x6a\x00"
475e0895134Schristos 	"\x70\x00\x2e\x00\x63\x00\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00"
476e0895134Schristos 	"\x70\x00\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x05\x00"
477e0895134Schristos 	"\x1a\x00\x63\x00\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00"
478e0895134Schristos 	"\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x07\x00\x08\x00"
479e0895134Schristos 	"\x94\x51\xf0\xbd\xdc\x61\xcb\x01\x00\x00\x00\x00";
480e0895134Schristos 
481e0895134Schristos     char buf3[362] =
482e0895134Schristos 	"\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00"
483e0895134Schristos 	"\x74\x00\x00\x00\xce\x00\xce\x00\x8c\x00\x00\x00\x1a\x00\x1a\x00"
484e0895134Schristos 	"\x40\x00\x00\x00\x04\x00\x04\x00\x5a\x00\x00\x00\x16\x00\x16\x00"
485e0895134Schristos 	"\x5e\x00\x00\x00\x10\x00\x10\x00\x5a\x01\x00\x00\x05\x02\x89\x62"
486e0895134Schristos 	"\x31\x00\x37\x00\x2e\x00\x32\x00\x30\x00\x31\x00\x2e\x00\x35\x00"
487e0895134Schristos 	"\x37\x00\x2e\x00\x31\x00\x32\x00\x31\x00\x71\x5c\x30\x75\x77\x00"
488e0895134Schristos 	"\x6f\x00\x72\x00\x6b\x00\x73\x00\x74\x00\x61\x00\x74\x00\x69\x00"
489e0895134Schristos 	"\x6f\x00\x6e\x00\xab\xad\xeb\x72\x01\xd4\x5f\xdf\x59\x07\x5f\xa9"
490e0895134Schristos 	"\xfd\x54\x98\x2d\xfa\x17\xbb\xf1\x3c\x8f\xf5\x20\xe6\x8f\xd7\x0a"
491e0895134Schristos 	"\xc9\x19\x3e\x94\x61\x31\xdb\x0f\x55\xe8\xe2\x53\x01\x01\x00\x00"
492e0895134Schristos 	"\x00\x00\x00\x00\x00\x06\x3e\x30\xe4\x61\xcb\x01\x71\x98\x10\x6b"
493e0895134Schristos 	"\x4c\x82\xec\xb3\x00\x00\x00\x00\x02\x00\x06\x00\x43\x00\x4f\x00"
494e0895134Schristos 	"\x53\x00\x01\x00\x12\x00\x43\x00\x4f\x00\x53\x00\x57\x00\x49\x00"
495e0895134Schristos 	"\x4e\x00\x37\x00\x4a\x00\x50\x00\x04\x00\x1a\x00\x63\x00\x6f\x00"
496e0895134Schristos 	"\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00\x6c\x00\x65\x00\x2e\x00"
497e0895134Schristos 	"\x63\x00\x6f\x00\x6d\x00\x03\x00\x2e\x00\x63\x00\x6f\x00\x73\x00"
498e0895134Schristos 	"\x77\x00\x69\x00\x6e\x00\x37\x00\x6a\x00\x70\x00\x2e\x00\x63\x00"
499e0895134Schristos 	"\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00\x6c\x00\x65\x00"
500e0895134Schristos 	"\x2e\x00\x63\x00\x6f\x00\x6d\x00\x05\x00\x1a\x00\x63\x00\x6f\x00"
501e0895134Schristos 	"\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00\x6c\x00\x65\x00\x2e\x00"
502e0895134Schristos 	"\x63\x00\x6f\x00\x6d\x00\x07\x00\x08\x00\xab\xec\xcc\x30\xe4\x61"
503e0895134Schristos 	"\xcb\x01\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x2e\xba\x3f\xd1\xb1"
504e0895134Schristos 	"\xa7\x70\x00\x9d\x55\xa0\x59\x74\x2b\x78";
505e0895134Schristos 
506e0895134Schristos 
507e0895134Schristos     struct ntlm_type2 type2;
508e0895134Schristos     struct ntlm_type3 type3;
509e0895134Schristos     struct ntlm_buf data;
510e0895134Schristos     int ret;
511e0895134Schristos 
512e0895134Schristos     data.length = sizeof(buf2);
513e0895134Schristos     data.data = buf2;
514e0895134Schristos 
515e0895134Schristos     memset(&type2, 0, sizeof(type2));
516e0895134Schristos 
517e0895134Schristos     ret = heim_ntlm_decode_type2(&data, &type2);
518e0895134Schristos     if (ret)
519e0895134Schristos 	errx(1, "heim_ntlm_decode_type2(jp): %d", ret);
520e0895134Schristos 
521e0895134Schristos     data.data = NULL;
522e0895134Schristos     data.length = 0;
523e0895134Schristos 
524e0895134Schristos     ret = heim_ntlm_encode_type2(&type2, &data);
525e0895134Schristos     if (ret)
526e0895134Schristos 	errx(1, "heim_ntlm_encode_type2(jp): %d", ret);
527e0895134Schristos 
528e0895134Schristos     heim_ntlm_free_type2(&type2);
529e0895134Schristos     heim_ntlm_free_buf(&data);
530e0895134Schristos 
531e0895134Schristos     data.length = sizeof(buf3);
532e0895134Schristos     data.data = buf3;
533e0895134Schristos 
534e0895134Schristos     memset(&type3, 0, sizeof(type3));
535e0895134Schristos 
536e0895134Schristos     ret = heim_ntlm_decode_type3(&data, 1, &type3);
537e0895134Schristos     if (ret)
538e0895134Schristos 	errx(1, "heim_ntlm_decode_type2(jp): %d", ret);
539e0895134Schristos 
540e0895134Schristos     data.data = NULL;
541e0895134Schristos     data.length = 0;
542e0895134Schristos 
543e0895134Schristos     ret = heim_ntlm_encode_type3(&type3, &data, NULL);
544e0895134Schristos     if (ret)
545e0895134Schristos 	errx(1, "heim_ntlm_decode_type2(jp): %d", ret);
546e0895134Schristos 
547e0895134Schristos     heim_ntlm_free_type3(&type3);
548e0895134Schristos     heim_ntlm_free_buf(&data);
549e0895134Schristos 
550e0895134Schristos     return 0;
551e0895134Schristos }
552e0895134Schristos 
553e0895134Schristos 
554f59d82ffSelric static int verbose_flag = 0;
555f59d82ffSelric static int version_flag = 0;
556f59d82ffSelric static int help_flag	= 0;
557f59d82ffSelric 
558f59d82ffSelric static struct getargs args[] = {
559f59d82ffSelric     {"verbose",	0,	arg_flag,	&verbose_flag, "verbose printing", NULL },
560f59d82ffSelric     {"version",	0,	arg_flag,	&version_flag, "print version", NULL },
561f59d82ffSelric     {"help",	0,	arg_flag,	&help_flag,  NULL, NULL }
562f59d82ffSelric };
563f59d82ffSelric 
564f59d82ffSelric static void
usage(int ret)565f59d82ffSelric usage (int ret)
566f59d82ffSelric {
567f59d82ffSelric     arg_printusage (args, sizeof(args)/sizeof(*args),
568f59d82ffSelric 		    NULL, "");
569f59d82ffSelric     exit (ret);
570f59d82ffSelric }
571f59d82ffSelric 
572f59d82ffSelric int
main(int argc,char ** argv)573f59d82ffSelric main(int argc, char **argv)
574f59d82ffSelric {
575e0895134Schristos     int ret = 0, optidx = 0;
576f59d82ffSelric 
577f59d82ffSelric     setprogname(argv[0]);
578f59d82ffSelric 
579e0895134Schristos     if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
580f59d82ffSelric 	usage(1);
581f59d82ffSelric 
582f59d82ffSelric     if (help_flag)
583f59d82ffSelric 	usage (0);
584f59d82ffSelric 
585f59d82ffSelric     if(version_flag){
586f59d82ffSelric 	print_version(NULL);
587f59d82ffSelric 	exit(0);
588f59d82ffSelric     }
589f59d82ffSelric 
590f59d82ffSelric     if (verbose_flag)
591f59d82ffSelric 	printf("test_parse\n");
592e0895134Schristos     ret |= test_parse();
593f59d82ffSelric 
594f59d82ffSelric     if (verbose_flag)
595f59d82ffSelric 	printf("test_keys\n");
596e0895134Schristos     ret |= test_keys();
597f59d82ffSelric 
598f59d82ffSelric     if (verbose_flag)
599f59d82ffSelric 	printf("test_ntlm2_session_resp\n");
600e0895134Schristos     ret |= test_ntlm2_session_resp();
601f59d82ffSelric 
602f59d82ffSelric     if (verbose_flag)
603f59d82ffSelric 	printf("test_targetinfo\n");
604e0895134Schristos     ret |= test_targetinfo();
605e0895134Schristos 
606e0895134Schristos     if (verbose_flag)
607e0895134Schristos 	printf("test_ntlmv2\n");
608e0895134Schristos     ret |= test_ntlmv2();
609e0895134Schristos 
610e0895134Schristos     if (verbose_flag)
611e0895134Schristos 	printf("test_string2key\n");
612e0895134Schristos     ret |= test_string2key();
613e0895134Schristos 
614e0895134Schristos     if (verbose_flag)
615e0895134Schristos 	printf("test_jp\n");
616e0895134Schristos     ret |= test_jp();
617f59d82ffSelric 
618f59d82ffSelric     return ret;
619f59d82ffSelric }
620