1 /*	$NetBSD: test_pknistkdf.c,v 1.1.1.1 2011/04/13 18:15:38 elric 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 
41 static int verbose_flag = 0;
42 
43 struct 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
108 static void
109 fooTicket(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 
136 static void
137 test_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 
215 static int version_flag = 0;
216 static int help_flag	= 0;
217 
218 static 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 
227 static void
228 usage (int ret)
229 {
230     arg_printusage (args,
231 		    sizeof(args)/sizeof(*args),
232 		    NULL,
233 		    "");
234     exit (ret);
235 }
236 
237 
238 int
239 main(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