1 /* 2 * Copyright (c) 2006 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 the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "krb5_locl.h" 35 36 RCSID("$Id: test_pac.c 21934 2007-08-27 14:21:04Z lha $"); 37 38 /* 39 * This PAC and keys are copied (with permission) from Samba torture 40 * regression test suite, they where created by Andrew Bartlet. 41 */ 42 43 static const unsigned char saved_pac[] = { 44 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 45 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 46 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 47 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 48 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 49 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb, 50 0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 51 0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59, 52 0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00, 53 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 54 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 55 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00, 56 0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00, 57 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00, 59 0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 60 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 63 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 64 0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 65 0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 69 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 70 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00, 71 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00, 72 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00, 73 0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00, 74 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 75 0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc, 76 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 77 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 78 0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00, 79 0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00, 80 0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a, 81 0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe, 82 0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00 83 }; 84 85 static int type_1_length = 472; 86 87 static const krb5_keyblock kdc_keyblock = { 88 ETYPE_ARCFOUR_HMAC_MD5, 89 { 16, "\xB2\x86\x75\x71\x48\xAF\x7F\xD2\x52\xC5\x36\x03\xA1\x50\xB7\xE7" } 90 }; 91 92 static const krb5_keyblock member_keyblock = { 93 ETYPE_ARCFOUR_HMAC_MD5, 94 { 16, "\xD2\x17\xFA\xEA\xE5\xE6\xB5\xF9\x5C\xCC\x94\x07\x7A\xB8\xA5\xFC" } 95 }; 96 97 static time_t authtime = 1120440609; 98 static const char *user = "w2003final$@WIN2K3.THINKER.LOCAL"; 99 100 int 101 main(int argc, char **argv) 102 { 103 krb5_error_code ret; 104 krb5_context context; 105 krb5_pac pac; 106 krb5_data data; 107 krb5_principal p; 108 109 ret = krb5_init_context(&context); 110 if (ret) 111 errx(1, "krb5_init_contex"); 112 113 ret = krb5_parse_name(context, user, &p); 114 if (ret) 115 krb5_err(context, 1, ret, "krb5_parse_name"); 116 117 ret = krb5_pac_parse(context, saved_pac, sizeof(saved_pac), &pac); 118 if (ret) 119 krb5_err(context, 1, ret, "krb5_pac_parse"); 120 121 ret = krb5_pac_verify(context, pac, authtime, p, 122 &member_keyblock, &kdc_keyblock); 123 if (ret) 124 krb5_err(context, 1, ret, "krb5_pac_verify"); 125 126 ret = _krb5_pac_sign(context, pac, authtime, p, 127 &member_keyblock, &kdc_keyblock, &data); 128 if (ret) 129 krb5_err(context, 1, ret, "_krb5_pac_sign"); 130 131 krb5_pac_free(context, pac); 132 133 ret = krb5_pac_parse(context, data.data, data.length, &pac); 134 krb5_data_free(&data); 135 if (ret) 136 krb5_err(context, 1, ret, "krb5_pac_parse 2"); 137 138 ret = krb5_pac_verify(context, pac, authtime, p, 139 &member_keyblock, &kdc_keyblock); 140 if (ret) 141 krb5_err(context, 1, ret, "krb5_pac_verify 2"); 142 143 /* make a copy and try to reproduce it */ 144 { 145 uint32_t *list; 146 size_t len, i; 147 krb5_pac pac2; 148 149 ret = krb5_pac_init(context, &pac2); 150 if (ret) 151 krb5_err(context, 1, ret, "krb5_pac_init"); 152 153 /* our two user buffer plus the three "system" buffers */ 154 ret = krb5_pac_get_types(context, pac, &len, &list); 155 if (ret) 156 krb5_err(context, 1, ret, "krb5_pac_get_types"); 157 158 for (i = 0; i < len; i++) { 159 /* skip server_cksum, privsvr_cksum, and logon_name */ 160 if (list[i] == 6 || list[i] == 7 || list[i] == 10) 161 continue; 162 163 ret = krb5_pac_get_buffer(context, pac, list[i], &data); 164 if (ret) 165 krb5_err(context, 1, ret, "krb5_pac_get_buffer"); 166 167 if (list[i] == 1) { 168 if (type_1_length != data.length) 169 krb5_errx(context, 1, "type 1 have wrong length: %lu", 170 (unsigned long)data.length); 171 } else 172 krb5_errx(context, 1, "unknown type %lu", 173 (unsigned long)list[i]); 174 175 ret = krb5_pac_add_buffer(context, pac2, list[i], &data); 176 if (ret) 177 krb5_err(context, 1, ret, "krb5_pac_add_buffer"); 178 krb5_data_free(&data); 179 } 180 free(list); 181 182 ret = _krb5_pac_sign(context, pac2, authtime, p, 183 &member_keyblock, &kdc_keyblock, &data); 184 if (ret) 185 krb5_err(context, 1, ret, "_krb5_pac_sign 4"); 186 187 krb5_pac_free(context, pac2); 188 189 ret = krb5_pac_parse(context, data.data, data.length, &pac2); 190 if (ret) 191 krb5_err(context, 1, ret, "krb5_pac_parse 4"); 192 193 ret = krb5_pac_verify(context, pac2, authtime, p, 194 &member_keyblock, &kdc_keyblock); 195 if (ret) 196 krb5_err(context, 1, ret, "krb5_pac_verify 4"); 197 198 krb5_pac_free(context, pac2); 199 } 200 201 krb5_pac_free(context, pac); 202 203 /* 204 * Test empty free 205 */ 206 207 ret = krb5_pac_init(context, &pac); 208 if (ret) 209 krb5_err(context, 1, ret, "krb5_pac_init"); 210 krb5_pac_free(context, pac); 211 212 /* 213 * Test add remove buffer 214 */ 215 216 ret = krb5_pac_init(context, &pac); 217 if (ret) 218 krb5_err(context, 1, ret, "krb5_pac_init"); 219 220 { 221 const krb5_data cdata = { 2, "\x00\x01" } ; 222 223 ret = krb5_pac_add_buffer(context, pac, 1, &cdata); 224 if (ret) 225 krb5_err(context, 1, ret, "krb5_pac_add_buffer"); 226 } 227 { 228 ret = krb5_pac_get_buffer(context, pac, 1, &data); 229 if (ret) 230 krb5_err(context, 1, ret, "krb5_pac_get_buffer"); 231 if (data.length != 2 || memcmp(data.data, "\x00\x01", 2) != 0) 232 krb5_errx(context, 1, "krb5_pac_get_buffer data not the same"); 233 krb5_data_free(&data); 234 } 235 236 { 237 const krb5_data cdata = { 2, "\x02\x00" } ; 238 239 ret = krb5_pac_add_buffer(context, pac, 2, &cdata); 240 if (ret) 241 krb5_err(context, 1, ret, "krb5_pac_add_buffer"); 242 } 243 { 244 ret = krb5_pac_get_buffer(context, pac, 1, &data); 245 if (ret) 246 krb5_err(context, 1, ret, "krb5_pac_get_buffer"); 247 if (data.length != 2 || memcmp(data.data, "\x00\x01", 2) != 0) 248 krb5_errx(context, 1, "krb5_pac_get_buffer data not the same"); 249 krb5_data_free(&data); 250 /* */ 251 ret = krb5_pac_get_buffer(context, pac, 2, &data); 252 if (ret) 253 krb5_err(context, 1, ret, "krb5_pac_get_buffer"); 254 if (data.length != 2 || memcmp(data.data, "\x02\x00", 2) != 0) 255 krb5_errx(context, 1, "krb5_pac_get_buffer data not the same"); 256 krb5_data_free(&data); 257 } 258 259 ret = _krb5_pac_sign(context, pac, authtime, p, 260 &member_keyblock, &kdc_keyblock, &data); 261 if (ret) 262 krb5_err(context, 1, ret, "_krb5_pac_sign"); 263 264 krb5_pac_free(context, pac); 265 266 ret = krb5_pac_parse(context, data.data, data.length, &pac); 267 krb5_data_free(&data); 268 if (ret) 269 krb5_err(context, 1, ret, "krb5_pac_parse 3"); 270 271 ret = krb5_pac_verify(context, pac, authtime, p, 272 &member_keyblock, &kdc_keyblock); 273 if (ret) 274 krb5_err(context, 1, ret, "krb5_pac_verify 3"); 275 276 { 277 uint32_t *list; 278 size_t len; 279 280 /* our two user buffer plus the three "system" buffers */ 281 ret = krb5_pac_get_types(context, pac, &len, &list); 282 if (ret) 283 krb5_err(context, 1, ret, "krb5_pac_get_types"); 284 if (len != 5) 285 krb5_errx(context, 1, "list wrong length"); 286 free(list); 287 } 288 289 krb5_pac_free(context, pac); 290 291 krb5_free_principal(context, p); 292 krb5_free_context(context); 293 294 return 0; 295 } 296