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