test_pknistkdf.c revision 1.2
1/*	$NetBSD: test_pknistkdf.c,v 1.2 2014/03/27 16:10:46 apb 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	/* == &asn1_oid_id_pkinit_kdf_ah_sha1.  Addresses of exported
59         * symbols are not considered constant on all platforms
60         * (Windows).  So we set it in main() below. */
61
62	{ /* Z */
63	    256,
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	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
77	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
78	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
79	    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
80	},
81	"lha@SU.SE", /* client, partyUInfo */
82	"krbtgt/SU.SE@SU.SE", /* server, partyVInfo */
83	ETYPE_AES256_CTS_HMAC_SHA1_96, /* enctype */
84	{ /* as_req */
85	    10,
86	    "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
87	},
88	{ /* pk_as_rep */
89	    9,
90	    "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"
91	},
92	{ /* ticket */
93	    55,
94	    "\x61\x35\x30\x33\xa0\x03\x02\x01\x05\xa1\x07\x1b\x05\x53\x55\x2e"
95	    "\x53\x45\xa2\x10\x30\x0e\xa0\x03\x02\x01\x01\xa1\x07\x30\x05\x1b"
96	    "\x03\x6c\x68\x61\xa3\x11\x30\x0f\xa0\x03\x02\x01\x12\xa2\x08\x04"
97	    "\x06\x68\x65\x6a\x68\x65\x6a"
98	},
99	{ /* key */
100	    32,
101	    "\xc7\x62\x89\xec\x4b\x28\xa6\x91\xff\xce\x80\xbb\xb7\xec\x82\x41"
102	    "\x52\x3f\x99\xb1\x90\xcf\x2d\x34\x8f\x54\xa8\x65\x81\x2c\x32\x73"
103	}
104    }
105};
106
107#ifdef MAKETICKET
108static void
109fooTicket(void)
110{
111    krb5_error_code ret;
112    krb5_data data;
113    size_t size;
114    Ticket t;
115
116    t.tkt_vno = 5;
117    t.realm = "SU.SE";
118    t.sname.name_type = KRB5_NT_PRINCIPAL;
119    t.sname.name_string.len = 1;
120    t.sname.name_string.val = ecalloc(1, sizeof(t.sname.name_string.val[0]));
121    t.sname.name_string.val[0] = estrdup("lha");
122    t.enc_part.etype = ETYPE_AES256_CTS_HMAC_SHA1_96;
123    t.enc_part.kvno = NULL;
124    t.enc_part.cipher.length = 6;
125    t.enc_part.cipher.data = "hejhej";
126
127    ASN1_MALLOC_ENCODE(Ticket, data.data, data.length, &t, &size, ret);
128    if (ret)
129	errx(1, "ASN1_MALLOC_ENCODE(Ticket)");
130
131    rk_dumpdata("foo", data.data, data.length);
132    free(data.data);
133}
134#endif
135
136static void
137test_dh2key(krb5_context context, int i, struct testcase *c)
138{
139    krb5_error_code ret;
140    krb5_keyblock key;
141    krb5_principal client, server;
142    Ticket ticket;
143    AlgorithmIdentifier ai;
144    size_t size;
145
146    memset(&ticket, 0, sizeof(ticket));
147
148    ai.algorithm = *c->oid;
149    ai.parameters = NULL;
150
151    ret = decode_Ticket(c->ticket.data, c->ticket.length, &ticket, &size);
152    if (ret)
153	krb5_errx(context, 1, "decode ticket: %d", ret);
154
155    ret = krb5_parse_name(context, c->client, &client);
156    if (ret)
157	krb5_err(context, 1, ret, "parse_name: %s", c->client);
158    ret = krb5_parse_name(context, c->server, &server);
159    if (ret)
160	krb5_err(context, 1, ret, "parse_name: %s", c->server);
161
162    if (verbose_flag) {
163	char *str;
164	hex_encode(c->Z.data, c->Z.length, &str);
165	printf("Z: %s\n", str);
166	free(str);
167	printf("client: %s\n", c->client);
168	printf("server: %s\n", c->server);
169	printf("enctype: %d\n", (int)c->enctype);
170	hex_encode(c->as_req.data, c->as_req.length, &str);
171	printf("as-req: %s\n", str);
172	free(str);
173	hex_encode(c->pk_as_rep.data, c->pk_as_rep.length, &str);
174	printf("pk-as-rep: %s\n", str);
175	free(str);
176	hex_encode(c->ticket.data, c->ticket.length, &str);
177	printf("ticket: %s\n", str);
178	free(str);
179    }
180
181    ret = _krb5_pk_kdf(context,
182		       &ai,
183		       c->Z.data,
184		       c->Z.length,
185		       client,
186		       server,
187		       c->enctype,
188		       &c->as_req,
189		       &c->pk_as_rep,
190		       &ticket,
191		       &key);
192    krb5_free_principal(context, client);
193    krb5_free_principal(context, server);
194    if (ret)
195	krb5_err(context, 1, ret, "_krb5_pk_kdf: %d", i);
196
197    if (verbose_flag) {
198	char *str;
199	hex_encode(key.keyvalue.data, key.keyvalue.length, &str);
200	printf("key: %s\n", str);
201	free(str);
202    }
203
204    if (key.keyvalue.length != c->key.length ||
205	memcmp(key.keyvalue.data, c->key.data, c->key.length) != 0)
206	krb5_errx(context, 1, "resulting key wrong: %d", i);
207
208    krb5_free_keyblock_contents(context, &key);
209    free_Ticket(&ticket);
210}
211
212
213
214
215static int version_flag = 0;
216static int help_flag	= 0;
217
218static struct getargs args[] = {
219    {"verbose",	0,	arg_flag,	&verbose_flag,
220     "verbose output", NULL },
221    {"version",	0,	arg_flag,	&version_flag,
222     "print version", NULL },
223    {"help",	0,	arg_flag,	&help_flag,
224     NULL, NULL }
225};
226
227static void
228usage (int ret)
229{
230    arg_printusage (args,
231		    sizeof(args)/sizeof(*args),
232		    NULL,
233		    "");
234    exit (ret);
235}
236
237
238int
239main(int argc, char **argv)
240{
241    krb5_context context;
242    krb5_error_code ret;
243    int i, optidx = 0;
244
245    setprogname(argv[0]);
246
247    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
248	usage(1);
249
250    if (help_flag)
251	usage (0);
252
253    if(version_flag){
254	print_version(NULL);
255	exit(0);
256    }
257
258    argc -= optidx;
259    argv += optidx;
260
261#ifdef MAKETICKET
262    fooTicket();
263#endif
264
265    ret = krb5_init_context(&context);
266    if (ret)
267	errx (1, "krb5_init_context failed: %d", ret);
268
269    tests[0].oid = &asn1_oid_id_pkinit_kdf_ah_sha1;
270
271    for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
272	test_dh2key(context, i, &tests[i]);
273
274    krb5_free_context(context);
275
276    return 0;
277}
278