test_pknistkdf.c revision 1.2.2.1
1/*	$NetBSD: test_pknistkdf.c,v 1.2.2.1 2014/08/10 06:47:30 tls Exp $	*/
2
3/*
4 * Copyright (c) 2008 Kungliga Tekniska H��gskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of KTH nor the names of its contributors may be
20 *    used to endorse or promote products derived from this software without
21 *    specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
34
35#include "krb5_locl.h"
36#include <krb5/pkinit_asn1.h>
37#include <err.h>
38#include <krb5/getarg.h>
39#include <krb5/hex.h>
40
41static int verbose_flag = 0;
42
43struct testcase {
44    const heim_oid *oid;
45    krb5_data Z;
46    const char *client;
47    const char *server;
48    krb5_enctype enctype;
49    krb5_data as_req;
50    krb5_data pk_as_rep;
51    krb5_data ticket;
52
53    krb5_data key;
54} tests[] = {
55    /* 0 */
56    {
57        NULL,                            /* AlgorithmIdentifier */
58	{ /* Z */
59	    256,
60	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
61	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
62	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
63	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
64	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
65	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
66	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
67	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
68	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
69	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
70	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
71	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
72	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
73	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
74	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
75	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
76	},
77	"lha@SU.SE", /* client, partyUInfo */
78	"krbtgt/SU.SE@SU.SE", /* server, partyVInfo */
79	ETYPE_AES256_CTS_HMAC_SHA1_96, /* enctype */
80	{ /* as_req */
81	    10,
82	    "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
83	},
84	{ /* pk_as_rep */
85	    9,
86	    "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"
87	},
88	{ /* ticket */
89	    55,
90	    "\x61\x35\x30\x33\xa0\x03\x02\x01\x05\xa1\x07\x1b\x05\x53\x55\x2e"
91	    "\x53\x45\xa2\x10\x30\x0e\xa0\x03\x02\x01\x01\xa1\x07\x30\x05\x1b"
92	    "\x03\x6c\x68\x61\xa3\x11\x30\x0f\xa0\x03\x02\x01\x12\xa2\x08\x04"
93	    "\x06\x68\x65\x6a\x68\x65\x6a"
94	},
95	{ /* key */
96	    32,
97	    "\xc7\x62\x89\xec\x4b\x28\xa6\x91\xff\xce\x80\xbb\xb7\xec\x82\x41"
98	    "\x52\x3f\x99\xb1\x90\xcf\x2d\x34\x8f\x54\xa8\x65\x81\x2c\x32\x73"
99	}
100    },
101    /* 1 */
102    {
103        NULL,                            /* AlgorithmIdentifier */
104	{ /* Z */
105	    256,
106	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
107	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
108	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
109	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
110	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
111	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
112	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
113	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
114	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
115	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
116	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
117	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
118	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
119	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
120	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
121	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
122	},
123	"lha@SU.SE", /* client, partyUInfo */
124	"krbtgt/SU.SE@SU.SE", /* server, partyVInfo */
125	ETYPE_AES256_CTS_HMAC_SHA1_96, /* enctype */
126	{ /* as_req */
127	    10,
128	    "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
129	},
130	{ /* pk_as_rep */
131	    9,
132	    "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"
133	},
134	{ /* ticket */
135	    55,
136	    "\x61\x35\x30\x33\xa0\x03\x02\x01\x05\xa1\x07\x1b\x05\x53\x55\x2e"
137	    "\x53\x45\xa2\x10\x30\x0e\xa0\x03\x02\x01\x01\xa1\x07\x30\x05\x1b"
138	    "\x03\x6c\x68\x61\xa3\x11\x30\x0f\xa0\x03\x02\x01\x12\xa2\x08\x04"
139	    "\x06\x68\x65\x6a\x68\x65\x6a"
140	},
141	{ /* key */
142	    32,
143	    "\x59\xf3\xca\x77\x5b\x20\x17\xe9\xad\x36\x3f\x47\xca\xbd\x43\xb8"
144	    "\x8c\xb8\x90\x35\x8d\xc6\x0d\x52\x0d\x11\x9f\xb0\xdc\x24\x0b\x61"
145	}
146    },
147    /* 2 */
148    {
149        NULL,                            /* AlgorithmIdentifier */
150	{ /* Z */
151	    256,
152	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
153	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
154	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
155	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
156	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
157	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
158	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
159	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
160	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
161	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
162	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
163	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
164	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
165	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
166	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
167	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
168	},
169	"lha@SU.SE", /* client, partyUInfo */
170	"krbtgt/SU.SE@SU.SE", /* server, partyVInfo */
171	ETYPE_AES256_CTS_HMAC_SHA1_96, /* enctype */
172	{ /* as_req */
173	    10,
174	    "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
175	},
176	{ /* pk_as_rep */
177	    9,
178	    "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"
179	},
180	{ /* ticket */
181	    55,
182	    "\x61\x35\x30\x33\xa0\x03\x02\x01\x05\xa1\x07\x1b\x05\x53\x55\x2e"
183	    "\x53\x45\xa2\x10\x30\x0e\xa0\x03\x02\x01\x01\xa1\x07\x30\x05\x1b"
184	    "\x03\x6c\x68\x61\xa3\x11\x30\x0f\xa0\x03\x02\x01\x12\xa2\x08\x04"
185	    "\x06\x68\x65\x6a\x68\x65\x6a"
186	},
187	{ /* key */
188	    32,
189	    "\x8a\x9a\xc5\x5f\x45\xda\x1a\x73\xd9\x1e\xe9\x88\x1f\xa9\x48\x81"
190	    "\xce\xac\x66\x2d\xb1\xd3\xb9\x0a\x9d\x0e\x52\x83\xdf\xe1\x84\x3d"
191	}
192    }
193};
194
195#ifdef MAKETICKET
196static void
197fooTicket(void)
198{
199    krb5_error_code ret;
200    krb5_data data;
201    size_t size;
202    Ticket t;
203
204    t.tkt_vno = 5;
205    t.realm = "SU.SE";
206    t.sname.name_type = KRB5_NT_PRINCIPAL;
207    t.sname.name_string.len = 1;
208    t.sname.name_string.val = ecalloc(1, sizeof(t.sname.name_string.val[0]));
209    t.sname.name_string.val[0] = estrdup("lha");
210    t.enc_part.etype = ETYPE_AES256_CTS_HMAC_SHA1_96;
211    t.enc_part.kvno = NULL;
212    t.enc_part.cipher.length = 6;
213    t.enc_part.cipher.data = "hejhej";
214
215    ASN1_MALLOC_ENCODE(Ticket, data.data, data.length, &t, &size, ret);
216    if (ret)
217	errx(1, "ASN1_MALLOC_ENCODE(Ticket)");
218
219    rk_dumpdata("foo", data.data, data.length);
220    free(data.data);
221}
222#endif
223
224static void
225test_dh2key(krb5_context context, int i, struct testcase *c)
226{
227    krb5_error_code ret;
228    krb5_keyblock key;
229    krb5_principal client, server;
230    Ticket ticket;
231    AlgorithmIdentifier ai;
232    size_t size;
233
234    memset(&ticket, 0, sizeof(ticket));
235
236    ai.algorithm = *c->oid;
237    ai.parameters = NULL;
238
239    ret = decode_Ticket(c->ticket.data, c->ticket.length, &ticket, &size);
240    if (ret)
241	krb5_errx(context, 1, "decode ticket: %d", ret);
242
243    ret = krb5_parse_name(context, c->client, &client);
244    if (ret)
245	krb5_err(context, 1, ret, "parse_name: %s", c->client);
246    ret = krb5_parse_name(context, c->server, &server);
247    if (ret)
248	krb5_err(context, 1, ret, "parse_name: %s", c->server);
249
250    if (verbose_flag) {
251	char *str;
252	hex_encode(c->Z.data, c->Z.length, &str);
253	printf("Z: %s\n", str);
254	free(str);
255	printf("client: %s\n", c->client);
256	printf("server: %s\n", c->server);
257	printf("enctype: %d\n", (int)c->enctype);
258	hex_encode(c->as_req.data, c->as_req.length, &str);
259	printf("as-req: %s\n", str);
260	free(str);
261	hex_encode(c->pk_as_rep.data, c->pk_as_rep.length, &str);
262	printf("pk-as-rep: %s\n", str);
263	free(str);
264	hex_encode(c->ticket.data, c->ticket.length, &str);
265	printf("ticket: %s\n", str);
266	free(str);
267    }
268
269    ret = _krb5_pk_kdf(context,
270		       &ai,
271		       c->Z.data,
272		       c->Z.length,
273		       client,
274		       server,
275		       c->enctype,
276		       &c->as_req,
277		       &c->pk_as_rep,
278		       &ticket,
279		       &key);
280    krb5_free_principal(context, client);
281    krb5_free_principal(context, server);
282    if (ret)
283	krb5_err(context, 1, ret, "_krb5_pk_kdf: %d", i);
284
285    if (verbose_flag) {
286	char *str;
287	hex_encode(key.keyvalue.data, key.keyvalue.length, &str);
288	printf("key: %s\n", str);
289	free(str);
290    }
291
292    if (key.keyvalue.length != c->key.length ||
293	memcmp(key.keyvalue.data, c->key.data, c->key.length) != 0)
294	krb5_errx(context, 1, "resulting key wrong: %d", i);
295
296    krb5_free_keyblock_contents(context, &key);
297    free_Ticket(&ticket);
298}
299
300
301
302
303static int version_flag = 0;
304static int help_flag	= 0;
305
306static struct getargs args[] = {
307    {"verbose",	0,	arg_flag,	&verbose_flag,
308     "verbose output", NULL },
309    {"version",	0,	arg_flag,	&version_flag,
310     "print version", NULL },
311    {"help",	0,	arg_flag,	&help_flag,
312     NULL, NULL }
313};
314
315static void
316usage (int ret)
317{
318    arg_printusage (args,
319		    sizeof(args)/sizeof(*args),
320		    NULL,
321		    "");
322    exit (ret);
323}
324
325
326int
327main(int argc, char **argv)
328{
329    krb5_context context;
330    krb5_error_code ret;
331    int i, optidx = 0;
332
333    setprogname(argv[0]);
334
335    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
336	usage(1);
337
338    if (help_flag)
339	usage (0);
340
341    if(version_flag){
342	print_version(NULL);
343	exit(0);
344    }
345
346    argc -= optidx;
347    argv += optidx;
348
349#ifdef MAKETICKET
350    fooTicket();
351#endif
352
353    ret = krb5_init_context(&context);
354    if (ret)
355	errx (1, "krb5_init_context failed: %d", ret);
356
357    tests[0].oid = &asn1_oid_id_pkinit_kdf_ah_sha1;
358    tests[1].oid = &asn1_oid_id_pkinit_kdf_ah_sha256;
359    tests[2].oid = &asn1_oid_id_pkinit_kdf_ah_sha512;
360
361    for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
362	test_dh2key(context, i, &tests[i]);
363
364    krb5_free_context(context);
365
366    return 0;
367}
368