1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * src/lib/krb5/asn.1/asn1_k_decode.c 8 * 9 * Copyright 1994 by the Massachusetts Institute of Technology. 10 * All Rights Reserved. 11 * 12 * Export of this software from the United States of America may 13 * require a specific license from the United States Government. 14 * It is the responsibility of any person or organization contemplating 15 * export to obtain such a license before exporting. 16 * 17 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 18 * distribute this software and its documentation for any purpose and 19 * without fee is hereby granted, provided that the above copyright 20 * notice appear in all copies and that both that copyright notice and 21 * this permission notice appear in supporting documentation, and that 22 * the name of M.I.T. not be used in advertising or publicity pertaining 23 * to distribution of the software without specific, written prior 24 * permission. Furthermore if you modify this software you must label 25 * your software as modified software and not distribute it in such a 26 * fashion that it might be confused with the original M.I.T. software. 27 * M.I.T. makes no representations about the suitability of 28 * this software for any purpose. It is provided "as is" without express 29 * or implied warranty. 30 */ 31 32 #include "asn1_k_decode.h" 33 #include "asn1_decode.h" 34 #include "asn1_get.h" 35 #include "asn1_misc.h" 36 37 /* Declare useful decoder variables. */ 38 #define setup() \ 39 asn1_error_code retval; \ 40 asn1_class asn1class; \ 41 asn1_construction construction; \ 42 asn1_tagnum tagnum; \ 43 unsigned int length, taglen 44 45 #define unused_var(x) if (0) { x = 0; x = x - x; } 46 47 /* This is used for prefetch of next tag in sequence. */ 48 #define next_tag() \ 49 { taginfo t2; \ 50 retval = asn1_get_tag_2(&subbuf, &t2); \ 51 if (retval) return retval; \ 52 /* Copy out to match previous functionality, until better integrated. */ \ 53 asn1class = t2.asn1class; \ 54 construction = t2.construction; \ 55 tagnum = t2.tagnum; \ 56 taglen = t2.length; \ 57 indef = t2.indef; \ 58 } 59 60 /* Force check for EOC tag. */ 61 #define get_eoc() \ 62 { \ 63 taginfo t3; \ 64 retval = asn1_get_tag_2(&subbuf, &t3); \ 65 if(retval) return retval; \ 66 if (t3.asn1class != UNIVERSAL || t3.tagnum || t3.indef) \ 67 return ASN1_MISSING_EOC; \ 68 /* Copy out to match previous functionality, until better integrated. */ \ 69 asn1class = t3.asn1class; \ 70 construction = t3.construction; \ 71 tagnum = t3.tagnum; \ 72 taglen = t3.length; \ 73 indef = t3.indef; \ 74 } 75 76 #define alloc_field(var, type) \ 77 var = (type*)calloc(1, sizeof(type)); \ 78 if ((var) == NULL) return ENOMEM 79 80 /* Fetch an expected APPLICATION class tag and verify. */ 81 #define apptag(tagexpect) \ 82 { \ 83 taginfo t1; \ 84 retval = asn1_get_tag_2(buf, &t1); \ 85 if (retval) return retval; \ 86 if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED || \ 87 t1.tagnum != (tagexpect)) return ASN1_BAD_ID; \ 88 /* Copy out to match previous functionality, until better integrated. */ \ 89 asn1class = t1.asn1class; \ 90 construction = t1.construction; \ 91 tagnum = t1.tagnum; \ 92 applen = t1.length; \ 93 } 94 95 /**** normal fields ****/ 96 97 /* 98 * get_field_body 99 * 100 * Get bare field. This also prefetches the next tag. The call to 101 * get_eoc() assumes that any values fetched by this macro are 102 * enclosed in a context-specific tag. 103 */ 104 #define get_field_body(var, decoder) \ 105 retval = decoder(&subbuf, &(var)); \ 106 if (retval) return retval; \ 107 if (!taglen && indef) { get_eoc(); } \ 108 next_tag() 109 110 /* 111 * get_field 112 * 113 * Get field having an expected context specific tag. This assumes 114 * that context-specific tags are monotonically increasing in its 115 * verification of tag numbers. 116 */ 117 #define get_field(var, tagexpect, decoder) \ 118 if (tagnum > (tagexpect)) return ASN1_MISSING_FIELD; \ 119 if (tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD; \ 120 if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ 121 && (tagnum || taglen || asn1class != UNIVERSAL)) \ 122 return ASN1_BAD_ID; \ 123 get_field_body(var,decoder) 124 125 /* 126 * opt_field 127 * 128 * Get an optional field with an expected context specific tag. 129 * Assumes that OPTVAL will have the default value, thus failing to 130 * distinguish between absent optional values and present optional 131 * values that happen to have the value of OPTVAL. 132 */ 133 #define opt_field(var, tagexpect, decoder, optvalue) \ 134 if (asn1buf_remains(&subbuf, seqindef)) { \ 135 if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ 136 && (tagnum || taglen || asn1class != UNIVERSAL)) \ 137 return ASN1_BAD_ID; \ 138 if (tagnum == (tagexpect)) { \ 139 get_field_body(var, decoder); \ 140 } else var = optvalue; \ 141 } 142 143 /**** fields w/ length ****/ 144 145 /* similar to get_field_body */ 146 #define get_lenfield_body(len, var, decoder) \ 147 retval = decoder(&subbuf, &(len), &(var)); \ 148 if (retval) return retval; \ 149 if (!taglen && indef) { get_eoc(); } \ 150 next_tag() 151 152 /* similar to get_field_body */ 153 #define get_lenfield(len, var, tagexpect, decoder) \ 154 if (tagnum > (tagexpect)) return ASN1_MISSING_FIELD; \ 155 if (tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD; \ 156 if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ 157 && (tagnum || taglen || asn1class != UNIVERSAL)) \ 158 return ASN1_BAD_ID; \ 159 get_lenfield_body(len, var, decoder) 160 161 /* similar to opt_field */ 162 #define opt_lenfield(len, var, tagexpect, decoder) \ 163 if (tagnum == (tagexpect)) { \ 164 get_lenfield_body(len, var, decoder); \ 165 } else { len = 0; var = 0; } 166 167 /* 168 * Deal with implicitly tagged fields 169 */ 170 #define get_implicit_octet_string(len, var, tagexpect) \ 171 if (tagnum != (tagexpect)) return ASN1_MISSING_FIELD; \ 172 if (asn1class != CONTEXT_SPECIFIC || construction != PRIMITIVE) \ 173 return ASN1_BAD_ID; \ 174 retval = asn1buf_remove_octetstring(&subbuf, taglen, &(var)); \ 175 if (retval) return retval; \ 176 (len) = taglen; \ 177 next_tag() 178 179 #define opt_implicit_octet_string(len, var, tagexpect) \ 180 if (tagnum == (tagexpect)) { \ 181 if (asn1class != CONTEXT_SPECIFIC || construction != PRIMITIVE) \ 182 return ASN1_BAD_ID; \ 183 retval = asn1buf_remove_octetstring(&subbuf, taglen, &(var)); \ 184 if (retval) return retval; \ 185 (len) = taglen; \ 186 next_tag(); \ 187 } else { (len) = 0; (var) = NULL; } 188 189 /* 190 * begin_structure 191 * 192 * Declares some variables for decoding SEQUENCE types. This is meant 193 * to be called in an inner block that ends with a call to 194 * end_structure(). 195 */ 196 #define begin_structure() \ 197 asn1buf subbuf; \ 198 int seqindef; \ 199 int indef; \ 200 retval = asn1_get_sequence(buf, &length, &seqindef); \ 201 if (retval) return retval; \ 202 retval = asn1buf_imbed(&subbuf, buf, length, seqindef); \ 203 if (retval) return retval; \ 204 next_tag() 205 206 /* 207 * This is used for structures which have no tagging. 208 * It is the same as begin_structure() except next_tag() 209 * is not called. 210 */ 211 #define begin_structure_no_tag() \ 212 asn1buf subbuf; \ 213 int seqindef; \ 214 int indef; \ 215 retval = asn1_get_sequence(buf, &length, &seqindef); \ 216 if (retval) return retval; \ 217 retval = asn1buf_imbed(&subbuf, buf, length, seqindef); \ 218 if (retval) return retval 219 220 /* skip trailing garbage */ 221 #define end_structure() \ 222 retval = asn1buf_sync(buf, &subbuf, asn1class, tagnum, \ 223 length, indef, seqindef); \ 224 if (retval) return retval 225 226 /* 227 * begin_choice 228 * 229 * Declares some variables for decoding CHOICE types. This is meant 230 * to be called in an inner block that ends with a call to 231 * end_choice(). 232 */ 233 #define begin_choice() \ 234 asn1buf subbuf; \ 235 int seqindef; \ 236 int indef; \ 237 taginfo t; \ 238 retval = asn1_get_tag_2(buf, &t); \ 239 if (retval) return retval; \ 240 tagnum = t.tagnum; \ 241 taglen = t.length; \ 242 indef = t.indef; \ 243 length = t.length; \ 244 seqindef = t.indef; \ 245 asn1class = t.asn1class; \ 246 construction = t.construction; \ 247 retval = asn1buf_imbed(&subbuf, buf, length, seqindef); \ 248 if (retval) return retval 249 250 /* skip trailing garbage */ 251 #define end_choice() \ 252 length -= t.length; \ 253 retval = asn1buf_sync(buf, &subbuf, t.asn1class, t.tagnum, \ 254 length, t.indef, seqindef); \ 255 if (retval) return retval 256 257 /* 258 * sequence_of 259 * 260 * Declares some variables for decoding SEQUENCE OF types. This is 261 * meant to be called in an inner block that ends with a call to 262 * end_sequence_of(). 263 */ 264 #define sequence_of(buf) \ 265 unsigned int length, taglen; \ 266 asn1_class asn1class; \ 267 asn1_construction construction; \ 268 asn1_tagnum tagnum; \ 269 int indef; \ 270 sequence_of_common(buf) 271 272 /* 273 * sequence_of_no_tagvars 274 * 275 * This is meant for use inside decoder functions that have an outer 276 * sequence structure and thus declares variables of different names 277 * than does sequence_of() to avoid shadowing. 278 */ 279 #define sequence_of_no_tagvars(buf) \ 280 asn1_class eseqclass; \ 281 asn1_construction eseqconstr; \ 282 asn1_tagnum eseqnum; \ 283 unsigned int eseqlen; \ 284 int eseqindef; \ 285 sequence_of_common(buf) 286 287 /* 288 * sequence_of_common 289 * 290 * Fetches the outer SEQUENCE OF length info into {length,seqofindef} 291 * and imbeds an inner buffer seqbuf. Unlike begin_structure(), it 292 * does not prefetch the next tag. 293 */ 294 #define sequence_of_common(buf) \ 295 int size = 0; \ 296 asn1buf seqbuf; \ 297 int seqofindef; \ 298 retval = asn1_get_sequence(buf, &length, &seqofindef); \ 299 if (retval) return retval; \ 300 retval = asn1buf_imbed(&seqbuf, buf, length, seqofindef); \ 301 if (retval) return retval 302 303 /* 304 * end_sequence_of 305 * 306 * Attempts to fetch an EOC tag, if any, and to sync over trailing 307 * garbage, if any. 308 */ 309 #define end_sequence_of(buf) \ 310 { \ 311 taginfo t4; \ 312 retval = asn1_get_tag_2(&seqbuf, &t4); \ 313 if (retval) return retval; \ 314 /* Copy out to match previous functionality, until better integrated. */ \ 315 asn1class = t4.asn1class; \ 316 construction = t4.construction; \ 317 tagnum = t4.tagnum; \ 318 taglen = t4.length; \ 319 indef = t4.indef; \ 320 } \ 321 retval = asn1buf_sync(buf, &seqbuf, asn1class, tagnum, \ 322 length, indef, seqofindef); \ 323 if (retval) return retval; 324 325 /* 326 * end_sequence_of_no_tagvars 327 * 328 * Like end_sequence_of(), but uses the different (non-shadowing) 329 * variable names. 330 */ 331 #define end_sequence_of_no_tagvars(buf) \ 332 { \ 333 taginfo t5; \ 334 retval = asn1_get_tag_2(&seqbuf, &t5); \ 335 if (retval) return retval; \ 336 /* Copy out to match previous functionality, until better integrated. */ \ 337 eseqclass = t5.asn1class; \ 338 eseqconstr = t5.construction; \ 339 eseqnum = t5.tagnum; \ 340 eseqlen = t5.length; \ 341 eseqindef = t5.indef; \ 342 } \ 343 retval = asn1buf_sync(buf, &seqbuf, eseqclass, eseqnum, \ 344 eseqlen, eseqindef, seqofindef); \ 345 if (retval) return retval; 346 347 #define cleanup() \ 348 return 0 349 350 /* scalars */ 351 asn1_error_code asn1_decode_kerberos_time(asn1buf *buf, krb5_timestamp *val) 352 { 353 time_t t; 354 asn1_error_code retval; 355 356 retval = asn1_decode_generaltime(buf,&t); 357 if (retval) 358 return retval; 359 360 *val = t; 361 return 0; 362 } 363 364 #define integer_convert(fname,ktype)\ 365 asn1_error_code fname(asn1buf * buf, ktype * val)\ 366 {\ 367 asn1_error_code retval;\ 368 long n;\ 369 retval = asn1_decode_integer(buf,&n);\ 370 if(retval) return retval;\ 371 *val = (ktype)n;\ 372 return 0;\ 373 } 374 #define unsigned_integer_convert(fname,ktype)\ 375 asn1_error_code fname(asn1buf * buf, ktype * val)\ 376 {\ 377 asn1_error_code retval;\ 378 unsigned long n;\ 379 retval = asn1_decode_unsigned_integer(buf,&n);\ 380 if(retval) return retval;\ 381 *val = (ktype)n;\ 382 return 0;\ 383 } 384 integer_convert(asn1_decode_int,int) 385 integer_convert(asn1_decode_int32,krb5_int32) 386 integer_convert(asn1_decode_kvno,krb5_kvno) 387 integer_convert(asn1_decode_enctype,krb5_enctype) 388 integer_convert(asn1_decode_cksumtype,krb5_cksumtype) 389 integer_convert(asn1_decode_octet,krb5_octet) 390 integer_convert(asn1_decode_addrtype,krb5_addrtype) 391 integer_convert(asn1_decode_authdatatype,krb5_authdatatype) 392 unsigned_integer_convert(asn1_decode_ui_2,krb5_ui_2) 393 unsigned_integer_convert(asn1_decode_ui_4,krb5_ui_4) 394 395 asn1_error_code asn1_decode_seqnum(asn1buf *buf, krb5_ui_4 *val) 396 { 397 asn1_error_code retval; 398 unsigned long n; 399 400 retval = asn1_decode_maybe_unsigned(buf, &n); 401 if (retval) return retval; 402 *val = (krb5_ui_4)n & 0xffffffff; 403 return 0; 404 } 405 406 asn1_error_code asn1_decode_msgtype(asn1buf *buf, krb5_msgtype *val) 407 { 408 asn1_error_code retval; 409 unsigned long n; 410 411 retval = asn1_decode_unsigned_integer(buf,&n); 412 if(retval) return retval; 413 414 *val = (krb5_msgtype) n; 415 return 0; 416 } 417 418 419 /* structures */ 420 asn1_error_code asn1_decode_realm(asn1buf *buf, krb5_principal *val) 421 { 422 return asn1_decode_generalstring(buf, 423 &((*val)->realm.length), 424 &((*val)->realm.data)); 425 } 426 427 asn1_error_code asn1_decode_principal_name(asn1buf *buf, krb5_principal *val) 428 { 429 setup(); 430 { begin_structure(); 431 get_field((*val)->type,0,asn1_decode_int32); 432 433 { sequence_of_no_tagvars(&subbuf); 434 while(asn1buf_remains(&seqbuf,seqofindef) > 0){ 435 size++; 436 if ((*val)->data == NULL) 437 (*val)->data = (krb5_data*)malloc(size*sizeof(krb5_data)); 438 else 439 (*val)->data = (krb5_data*)realloc((*val)->data, 440 size*sizeof(krb5_data)); 441 if((*val)->data == NULL) return ENOMEM; 442 retval = asn1_decode_generalstring(&seqbuf, 443 &((*val)->data[size-1].length), 444 &((*val)->data[size-1].data)); 445 if(retval) return retval; 446 } 447 (*val)->length = size; 448 end_sequence_of_no_tagvars(&subbuf); 449 } 450 if (indef) { 451 get_eoc(); 452 } 453 next_tag(); 454 end_structure(); 455 (*val)->magic = KV5M_PRINCIPAL; 456 } 457 cleanup(); 458 } 459 460 asn1_error_code asn1_decode_checksum(asn1buf *buf, krb5_checksum *val) 461 { 462 setup(); 463 { begin_structure(); 464 get_field(val->checksum_type,0,asn1_decode_cksumtype); 465 get_lenfield(val->length,val->contents,1,asn1_decode_octetstring); 466 end_structure(); 467 val->magic = KV5M_CHECKSUM; 468 } 469 cleanup(); 470 } 471 472 asn1_error_code asn1_decode_encryption_key(asn1buf *buf, krb5_keyblock *val) 473 { 474 setup(); 475 { begin_structure(); 476 get_field(val->enctype,0,asn1_decode_enctype); 477 get_lenfield(val->length,val->contents,1,asn1_decode_octetstring); 478 end_structure(); 479 val->magic = KV5M_KEYBLOCK; 480 } 481 cleanup(); 482 } 483 484 asn1_error_code asn1_decode_encrypted_data(asn1buf *buf, krb5_enc_data *val) 485 { 486 setup(); 487 { begin_structure(); 488 get_field(val->enctype,0,asn1_decode_enctype); 489 opt_field(val->kvno,1,asn1_decode_kvno,0); 490 get_lenfield(val->ciphertext.length,val->ciphertext.data,2,asn1_decode_charstring); 491 end_structure(); 492 val->magic = KV5M_ENC_DATA; 493 } 494 cleanup(); 495 } 496 497 asn1_error_code asn1_decode_krb5_flags(asn1buf *buf, krb5_flags *val) 498 { 499 asn1_error_code retval; 500 asn1_octet unused, o; 501 taginfo t; 502 int i; 503 krb5_flags f=0; 504 unsigned int length; 505 506 retval = asn1_get_tag_2(buf, &t); 507 if (retval) return retval; 508 if (t.asn1class != UNIVERSAL || t.construction != PRIMITIVE || 509 t.tagnum != ASN1_BITSTRING) 510 return ASN1_BAD_ID; 511 length = t.length; 512 513 retval = asn1buf_remove_octet(buf,&unused); /* # of padding bits */ 514 if(retval) return retval; 515 516 /* Number of unused bits must be between 0 and 7. */ 517 if (unused > 7) return ASN1_BAD_FORMAT; 518 length--; 519 520 for(i = 0; i < length; i++) { 521 retval = asn1buf_remove_octet(buf,&o); 522 if(retval) return retval; 523 /* ignore bits past number 31 */ 524 if (i < 4) 525 f = (f<<8) | ((krb5_flags)o&0xFF); 526 } 527 if (length <= 4) { 528 /* Mask out unused bits, but only if necessary. */ 529 f &= ~(krb5_flags)0 << unused; 530 } 531 /* left-justify */ 532 if (length < 4) 533 f <<= (4 - length) * 8; 534 *val = f; 535 return 0; 536 } 537 538 asn1_error_code asn1_decode_ticket_flags(asn1buf *buf, krb5_flags *val) 539 { return asn1_decode_krb5_flags(buf,val); } 540 541 asn1_error_code asn1_decode_ap_options(asn1buf *buf, krb5_flags *val) 542 { return asn1_decode_krb5_flags(buf,val); } 543 544 asn1_error_code asn1_decode_kdc_options(asn1buf *buf, krb5_flags *val) 545 { return asn1_decode_krb5_flags(buf,val); } 546 547 asn1_error_code asn1_decode_transited_encoding(asn1buf *buf, krb5_transited *val) 548 { 549 setup(); 550 { begin_structure(); 551 get_field(val->tr_type,0,asn1_decode_octet); 552 get_lenfield(val->tr_contents.length,val->tr_contents.data,1,asn1_decode_charstring); 553 end_structure(); 554 val->magic = KV5M_TRANSITED; 555 } 556 cleanup(); 557 } 558 559 asn1_error_code asn1_decode_enc_kdc_rep_part(asn1buf *buf, krb5_enc_kdc_rep_part *val) 560 { 561 setup(); 562 { begin_structure(); 563 alloc_field(val->session,krb5_keyblock); 564 get_field(*(val->session),0,asn1_decode_encryption_key); 565 get_field(val->last_req,1,asn1_decode_last_req); 566 get_field(val->nonce,2,asn1_decode_int32); 567 opt_field(val->key_exp,3,asn1_decode_kerberos_time,0); 568 get_field(val->flags,4,asn1_decode_ticket_flags); 569 get_field(val->times.authtime,5,asn1_decode_kerberos_time); 570 /* Set to authtime if missing */ 571 opt_field(val->times.starttime,6,asn1_decode_kerberos_time,val->times.authtime); 572 get_field(val->times.endtime,7,asn1_decode_kerberos_time); 573 opt_field(val->times.renew_till,8,asn1_decode_kerberos_time,0); 574 alloc_field(val->server,krb5_principal_data); 575 get_field(val->server,9,asn1_decode_realm); 576 get_field(val->server,10,asn1_decode_principal_name); 577 opt_field(val->caddrs,11,asn1_decode_host_addresses,NULL); 578 end_structure(); 579 val->magic = KV5M_ENC_KDC_REP_PART; 580 } 581 cleanup(); 582 } 583 584 asn1_error_code asn1_decode_ticket(asn1buf *buf, krb5_ticket *val) 585 { 586 setup(); 587 unsigned int applen; 588 apptag(1); 589 { begin_structure(); 590 { krb5_kvno vno; 591 get_field(vno,0,asn1_decode_kvno); 592 if(vno != KVNO) return KRB5KDC_ERR_BAD_PVNO; } 593 alloc_field(val->server,krb5_principal_data); 594 get_field(val->server,1,asn1_decode_realm); 595 get_field(val->server,2,asn1_decode_principal_name); 596 get_field(val->enc_part,3,asn1_decode_encrypted_data); 597 end_structure(); 598 val->magic = KV5M_TICKET; 599 } 600 if (!applen) { 601 taginfo t; 602 retval = asn1_get_tag_2(buf, &t); 603 if (retval) return retval; 604 } 605 cleanup(); 606 } 607 608 asn1_error_code asn1_decode_kdc_req(asn1buf *buf, krb5_kdc_req *val) 609 { 610 setup(); 611 { begin_structure(); 612 { krb5_kvno kvno; 613 get_field(kvno,1,asn1_decode_kvno); 614 if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; } 615 get_field(val->msg_type,2,asn1_decode_msgtype); 616 opt_field(val->padata,3,asn1_decode_sequence_of_pa_data,NULL); 617 get_field(*val,4,asn1_decode_kdc_req_body); 618 end_structure(); 619 val->magic = KV5M_KDC_REQ; 620 } 621 cleanup(); 622 } 623 624 asn1_error_code asn1_decode_kdc_req_body(asn1buf *buf, krb5_kdc_req *val) 625 { 626 setup(); 627 { 628 krb5_principal psave; 629 begin_structure(); 630 get_field(val->kdc_options,0,asn1_decode_kdc_options); 631 if(tagnum == 1){ alloc_field(val->client,krb5_principal_data); } 632 opt_field(val->client,1,asn1_decode_principal_name,NULL); 633 alloc_field(val->server,krb5_principal_data); 634 get_field(val->server,2,asn1_decode_realm); 635 if(val->client != NULL){ 636 retval = asn1_krb5_realm_copy(val->client,val->server); 637 if(retval) return retval; } 638 639 /* If opt_field server is missing, memory reference to server is 640 lost and results in memory leak */ 641 psave = val->server; 642 opt_field(val->server,3,asn1_decode_principal_name,NULL); 643 if(val->server == NULL){ 644 if(psave->realm.data) { 645 free(psave->realm.data); 646 psave->realm.data = NULL; 647 psave->realm.length=0; 648 } 649 free(psave); 650 } 651 opt_field(val->from,4,asn1_decode_kerberos_time,0); 652 get_field(val->till,5,asn1_decode_kerberos_time); 653 opt_field(val->rtime,6,asn1_decode_kerberos_time,0); 654 get_field(val->nonce,7,asn1_decode_int32); 655 get_lenfield(val->nktypes,val->ktype,8,asn1_decode_sequence_of_enctype); 656 opt_field(val->addresses,9,asn1_decode_host_addresses,0); 657 if(tagnum == 10){ 658 get_field(val->authorization_data,10,asn1_decode_encrypted_data); } 659 else{ 660 val->authorization_data.magic = KV5M_ENC_DATA; 661 val->authorization_data.enctype = 0; 662 val->authorization_data.kvno = 0; 663 val->authorization_data.ciphertext.data = NULL; 664 val->authorization_data.ciphertext.length = 0; 665 } 666 opt_field(val->second_ticket,11,asn1_decode_sequence_of_ticket,NULL); 667 end_structure(); 668 val->magic = KV5M_KDC_REQ; 669 } 670 cleanup(); 671 } 672 673 asn1_error_code asn1_decode_krb_safe_body(asn1buf *buf, krb5_safe *val) 674 { 675 setup(); 676 { begin_structure(); 677 get_lenfield(val->user_data.length,val->user_data.data,0,asn1_decode_charstring); 678 opt_field(val->timestamp,1,asn1_decode_kerberos_time,0); 679 opt_field(val->usec,2,asn1_decode_int32,0); 680 opt_field(val->seq_number,3,asn1_decode_seqnum,0); 681 alloc_field(val->s_address,krb5_address); 682 get_field(*(val->s_address),4,asn1_decode_host_address); 683 if(tagnum == 5){ 684 alloc_field(val->r_address,krb5_address); 685 get_field(*(val->r_address),5,asn1_decode_host_address); 686 } else val->r_address = NULL; 687 end_structure(); 688 val->magic = KV5M_SAFE; 689 } 690 cleanup(); 691 } 692 693 asn1_error_code asn1_decode_host_address(asn1buf *buf, krb5_address *val) 694 { 695 setup(); 696 { begin_structure(); 697 get_field(val->addrtype,0,asn1_decode_addrtype); 698 get_lenfield(val->length,val->contents,1,asn1_decode_octetstring); 699 end_structure(); 700 val->magic = KV5M_ADDRESS; 701 } 702 cleanup(); 703 } 704 705 asn1_error_code asn1_decode_kdc_rep(asn1buf *buf, krb5_kdc_rep *val) 706 { 707 setup(); 708 { begin_structure(); 709 { krb5_kvno pvno; 710 get_field(pvno,0,asn1_decode_kvno); 711 if(pvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; } 712 get_field(val->msg_type,1,asn1_decode_msgtype); 713 opt_field(val->padata,2,asn1_decode_sequence_of_pa_data,NULL); 714 alloc_field(val->client,krb5_principal_data); 715 get_field(val->client,3,asn1_decode_realm); 716 get_field(val->client,4,asn1_decode_principal_name); 717 alloc_field(val->ticket,krb5_ticket); 718 get_field(*(val->ticket),5,asn1_decode_ticket); 719 get_field(val->enc_part,6,asn1_decode_encrypted_data); 720 end_structure(); 721 val->magic = KV5M_KDC_REP; 722 } 723 cleanup(); 724 } 725 726 727 /* arrays */ 728 #define get_element(element,decoder)\ 729 retval = decoder(&seqbuf,element);\ 730 if(retval) return retval 731 732 #define array_append(array,size,element,type)\ 733 size++;\ 734 if (*(array) == NULL)\ 735 *(array) = (type**)malloc((size+1)*sizeof(type*));\ 736 else\ 737 *(array) = (type**)realloc(*(array),\ 738 (size+1)*sizeof(type*));\ 739 if(*(array) == NULL) return ENOMEM;\ 740 (*(array))[(size)-1] = elt 741 742 #define decode_array_body(type,decoder)\ 743 asn1_error_code retval;\ 744 type *elt;\ 745 \ 746 { sequence_of(buf);\ 747 while(asn1buf_remains(&seqbuf,seqofindef) > 0){\ 748 alloc_field(elt,type);\ 749 get_element(elt,decoder);\ 750 array_append(val,size,elt,type);\ 751 }\ 752 if (*val == NULL)\ 753 *val = (type **)malloc(sizeof(type*));\ 754 (*val)[size] = NULL;\ 755 end_sequence_of(buf);\ 756 }\ 757 cleanup() 758 759 760 asn1_error_code asn1_decode_authorization_data(asn1buf *buf, krb5_authdata ***val) 761 { 762 decode_array_body(krb5_authdata,asn1_decode_authdata_elt); 763 } 764 765 asn1_error_code asn1_decode_authdata_elt(asn1buf *buf, krb5_authdata *val) 766 { 767 setup(); 768 { begin_structure(); 769 get_field(val->ad_type,0,asn1_decode_authdatatype); 770 get_lenfield(val->length,val->contents,1,asn1_decode_octetstring); 771 end_structure(); 772 val->magic = KV5M_AUTHDATA; 773 } 774 cleanup(); 775 } 776 777 asn1_error_code asn1_decode_host_addresses(asn1buf *buf, krb5_address ***val) 778 { 779 decode_array_body(krb5_address,asn1_decode_host_address); 780 } 781 782 asn1_error_code asn1_decode_sequence_of_ticket(asn1buf *buf, krb5_ticket ***val) 783 { 784 decode_array_body(krb5_ticket,asn1_decode_ticket); 785 } 786 787 asn1_error_code asn1_decode_sequence_of_krb_cred_info(asn1buf *buf, krb5_cred_info ***val) 788 { 789 decode_array_body(krb5_cred_info,asn1_decode_krb_cred_info); 790 } 791 792 asn1_error_code asn1_decode_krb_cred_info(asn1buf *buf, krb5_cred_info *val) 793 { 794 setup(); 795 { begin_structure(); 796 alloc_field(val->session,krb5_keyblock); 797 get_field(*(val->session),0,asn1_decode_encryption_key); 798 if(tagnum == 1){ 799 alloc_field(val->client,krb5_principal_data); 800 opt_field(val->client,1,asn1_decode_realm,NULL); 801 opt_field(val->client,2,asn1_decode_principal_name,NULL); } 802 opt_field(val->flags,3,asn1_decode_ticket_flags,0); 803 opt_field(val->times.authtime,4,asn1_decode_kerberos_time,0); 804 opt_field(val->times.starttime,5,asn1_decode_kerberos_time,0); 805 opt_field(val->times.endtime,6,asn1_decode_kerberos_time,0); 806 opt_field(val->times.renew_till,7,asn1_decode_kerberos_time,0); 807 if(tagnum == 8){ 808 alloc_field(val->server,krb5_principal_data); 809 opt_field(val->server,8,asn1_decode_realm,NULL); 810 opt_field(val->server,9,asn1_decode_principal_name,NULL); } 811 opt_field(val->caddrs,10,asn1_decode_host_addresses,NULL); 812 end_structure(); 813 val->magic = KV5M_CRED_INFO; 814 } 815 cleanup(); 816 } 817 818 asn1_error_code asn1_decode_sequence_of_pa_data(asn1buf *buf, krb5_pa_data ***val) 819 { 820 decode_array_body(krb5_pa_data,asn1_decode_pa_data); 821 } 822 823 asn1_error_code asn1_decode_pa_data(asn1buf *buf, krb5_pa_data *val) 824 { 825 setup(); 826 { begin_structure(); 827 get_field(val->pa_type,1,asn1_decode_int32); 828 get_lenfield(val->length,val->contents,2,asn1_decode_octetstring); 829 end_structure(); 830 val->magic = KV5M_PA_DATA; 831 } 832 cleanup(); 833 } 834 835 asn1_error_code asn1_decode_last_req(asn1buf *buf, krb5_last_req_entry ***val) 836 { 837 decode_array_body(krb5_last_req_entry,asn1_decode_last_req_entry); 838 } 839 840 asn1_error_code asn1_decode_last_req_entry(asn1buf *buf, krb5_last_req_entry *val) 841 { 842 setup(); 843 { begin_structure(); 844 get_field(val->lr_type,0,asn1_decode_int32); 845 get_field(val->value,1,asn1_decode_kerberos_time); 846 end_structure(); 847 val->magic = KV5M_LAST_REQ_ENTRY; 848 #ifdef KRB5_GENEROUS_LR_TYPE 849 /* If we are only a single byte wide and negative - fill in the 850 other bits */ 851 if((val->lr_type & 0xffffff80U) == 0x80) val->lr_type |= 0xffffff00U; 852 #endif 853 } 854 cleanup(); 855 } 856 857 asn1_error_code asn1_decode_sequence_of_enctype(asn1buf *buf, int *num, krb5_enctype **val) 858 { 859 asn1_error_code retval; 860 { sequence_of(buf); 861 while(asn1buf_remains(&seqbuf,seqofindef) > 0){ 862 size++; 863 if (*val == NULL) 864 *val = (krb5_enctype*)malloc(size*sizeof(krb5_enctype)); 865 else 866 *val = (krb5_enctype*)realloc(*val,size*sizeof(krb5_enctype)); 867 if(*val == NULL) return ENOMEM; 868 retval = asn1_decode_enctype(&seqbuf,&((*val)[size-1])); 869 if(retval) return retval; 870 } 871 *num = size; 872 end_sequence_of(buf); 873 } 874 cleanup(); 875 } 876 877 asn1_error_code asn1_decode_sequence_of_checksum(asn1buf *buf, krb5_checksum ***val) 878 { 879 decode_array_body(krb5_checksum, asn1_decode_checksum); 880 } 881 882 static asn1_error_code asn1_decode_etype_info2_entry(asn1buf *buf, krb5_etype_info_entry *val ) 883 { 884 /* 885 * Solaris Kerberos: 886 * Use a temporary char* (tmpp) in place of val->salt when calling 887 * get_lenfield(). val->salt cannot be cast to a char* as casting will not 888 * produce an lvalue. Use the new value pointed to by tmpp as the value for 889 * val->salt. 890 */ 891 char *tmpp; 892 setup(); 893 { begin_structure(); 894 get_field(val->etype,0,asn1_decode_enctype); 895 if (tagnum == 1) { 896 get_lenfield(val->length,tmpp,1,asn1_decode_generalstring); 897 val->salt = (krb5_octet*)tmpp; /* SUNW14resync hack */ 898 } else { 899 val->length = KRB5_ETYPE_NO_SALT; 900 val->salt = 0; 901 } 902 if ( tagnum ==2) { 903 krb5_octet *params ; 904 get_lenfield( val->s2kparams.length, params, 905 2, asn1_decode_octetstring); 906 val->s2kparams.data = ( char *) params; 907 } else { 908 val->s2kparams.data = NULL; 909 val->s2kparams.length = 0; 910 } 911 end_structure(); 912 val->magic = KV5M_ETYPE_INFO_ENTRY; 913 } 914 cleanup(); 915 } 916 917 static asn1_error_code asn1_decode_etype_info2_entry_1_3(asn1buf *buf, krb5_etype_info_entry *val ) 918 { 919 setup(); 920 { begin_structure(); 921 get_field(val->etype,0,asn1_decode_enctype); 922 if (tagnum == 1) { 923 get_lenfield(val->length,val->salt,1,asn1_decode_octetstring); 924 } else { 925 val->length = KRB5_ETYPE_NO_SALT; 926 val->salt = 0; 927 } 928 if ( tagnum ==2) { 929 krb5_octet *params ; 930 get_lenfield( val->s2kparams.length, params, 931 2, asn1_decode_octetstring); 932 val->s2kparams.data = ( char *) params; 933 } else { 934 val->s2kparams.data = NULL; 935 val->s2kparams.length = 0; 936 } 937 end_structure(); 938 val->magic = KV5M_ETYPE_INFO_ENTRY; 939 } 940 cleanup(); 941 } 942 943 944 static asn1_error_code asn1_decode_etype_info_entry(asn1buf *buf, krb5_etype_info_entry *val ) 945 { 946 setup(); 947 { begin_structure(); 948 get_field(val->etype,0,asn1_decode_enctype); 949 if (tagnum == 1) { 950 get_lenfield(val->length,val->salt,1,asn1_decode_octetstring); 951 } else { 952 val->length = KRB5_ETYPE_NO_SALT; 953 val->salt = 0; 954 } 955 val->s2kparams.data = NULL; 956 val->s2kparams.length = 0; 957 958 end_structure(); 959 val->magic = KV5M_ETYPE_INFO_ENTRY; 960 } 961 cleanup(); 962 } 963 964 asn1_error_code asn1_decode_etype_info(asn1buf *buf, krb5_etype_info_entry ***val ) 965 { 966 decode_array_body(krb5_etype_info_entry,asn1_decode_etype_info_entry); 967 } 968 969 asn1_error_code asn1_decode_etype_info2(asn1buf *buf, krb5_etype_info_entry ***val , 970 krb5_boolean v1_3_behavior) 971 { 972 if (v1_3_behavior) { 973 decode_array_body(krb5_etype_info_entry, 974 asn1_decode_etype_info2_entry_1_3); 975 } else { 976 decode_array_body(krb5_etype_info_entry, 977 asn1_decode_etype_info2_entry); 978 } 979 } 980 981 asn1_error_code asn1_decode_passwdsequence(asn1buf *buf, passwd_phrase_element *val) 982 { 983 setup(); 984 { begin_structure(); 985 alloc_field(val->passwd,krb5_data); 986 get_lenfield(val->passwd->length,val->passwd->data, 987 0,asn1_decode_charstring); 988 val->passwd->magic = KV5M_DATA; 989 alloc_field(val->phrase,krb5_data); 990 get_lenfield(val->phrase->length,val->phrase->data, 991 1,asn1_decode_charstring); 992 val->phrase->magic = KV5M_DATA; 993 end_structure(); 994 val->magic = KV5M_PASSWD_PHRASE_ELEMENT; 995 } 996 cleanup(); 997 } 998 999 asn1_error_code asn1_decode_sequence_of_passwdsequence(asn1buf *buf, passwd_phrase_element ***val) 1000 { 1001 decode_array_body(passwd_phrase_element,asn1_decode_passwdsequence); 1002 } 1003 1004 asn1_error_code asn1_decode_sam_flags(asn1buf *buf, krb5_flags *val) 1005 { return asn1_decode_krb5_flags(buf,val); } 1006 1007 #define opt_string(val,n,fn) opt_lenfield((val).length,(val).data,n,fn) 1008 #define opt_cksum(var,tagexpect,decoder)\ 1009 if(tagnum == (tagexpect)){\ 1010 get_field_body(var,decoder); }\ 1011 else var.length = 0 1012 1013 asn1_error_code asn1_decode_sam_challenge(asn1buf *buf, krb5_sam_challenge *val) 1014 { 1015 setup(); 1016 { begin_structure(); 1017 get_field(val->sam_type,0,asn1_decode_int32); 1018 get_field(val->sam_flags,1,asn1_decode_sam_flags); 1019 opt_string(val->sam_type_name,2,asn1_decode_charstring); 1020 opt_string(val->sam_track_id,3,asn1_decode_charstring); 1021 opt_string(val->sam_challenge_label,4,asn1_decode_charstring); 1022 opt_string(val->sam_challenge,5,asn1_decode_charstring); 1023 opt_string(val->sam_response_prompt,6,asn1_decode_charstring); 1024 opt_string(val->sam_pk_for_sad,7,asn1_decode_charstring); 1025 opt_field(val->sam_nonce,8,asn1_decode_int32,0); 1026 opt_cksum(val->sam_cksum,9,asn1_decode_checksum); 1027 end_structure(); 1028 val->magic = KV5M_SAM_CHALLENGE; 1029 } 1030 cleanup(); 1031 } 1032 asn1_error_code asn1_decode_sam_challenge_2(asn1buf *buf, krb5_sam_challenge_2 *val) 1033 { 1034 setup(); 1035 { char *save, *end; 1036 size_t alloclen; 1037 begin_structure(); 1038 if (tagnum != 0) return ASN1_MISSING_FIELD; 1039 if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) 1040 return ASN1_BAD_ID; 1041 save = subbuf.next; 1042 { sequence_of_no_tagvars(&subbuf); 1043 unused_var(size); 1044 end_sequence_of_no_tagvars(&subbuf); 1045 } 1046 end = subbuf.next; 1047 alloclen = end - save; 1048 if ((val->sam_challenge_2_body.data = (char *) malloc(alloclen)) == NULL) 1049 return ENOMEM; 1050 val->sam_challenge_2_body.length = alloclen; 1051 memcpy(val->sam_challenge_2_body.data, save, alloclen); 1052 next_tag(); 1053 get_field(val->sam_cksum, 1, asn1_decode_sequence_of_checksum); 1054 end_structure(); 1055 } 1056 cleanup(); 1057 } 1058 asn1_error_code asn1_decode_sam_challenge_2_body(asn1buf *buf, krb5_sam_challenge_2_body *val) 1059 { 1060 setup(); 1061 { begin_structure(); 1062 get_field(val->sam_type,0,asn1_decode_int32); 1063 get_field(val->sam_flags,1,asn1_decode_sam_flags); 1064 opt_string(val->sam_type_name,2,asn1_decode_charstring); 1065 opt_string(val->sam_track_id,3,asn1_decode_charstring); 1066 opt_string(val->sam_challenge_label,4,asn1_decode_charstring); 1067 opt_string(val->sam_challenge,5,asn1_decode_charstring); 1068 opt_string(val->sam_response_prompt,6,asn1_decode_charstring); 1069 opt_string(val->sam_pk_for_sad,7,asn1_decode_charstring); 1070 get_field(val->sam_nonce,8,asn1_decode_int32); 1071 get_field(val->sam_etype, 9, asn1_decode_int32); 1072 end_structure(); 1073 val->magic = KV5M_SAM_CHALLENGE; 1074 } 1075 cleanup(); 1076 } 1077 asn1_error_code asn1_decode_enc_sam_key(asn1buf *buf, krb5_sam_key *val) 1078 { 1079 setup(); 1080 { begin_structure(); 1081 /* alloc_field(val->sam_key,krb5_keyblock); */ 1082 get_field(val->sam_key,0,asn1_decode_encryption_key); 1083 end_structure(); 1084 val->magic = KV5M_SAM_KEY; 1085 } 1086 cleanup(); 1087 } 1088 1089 asn1_error_code asn1_decode_enc_sam_response_enc(asn1buf *buf, krb5_enc_sam_response_enc *val) 1090 { 1091 setup(); 1092 { begin_structure(); 1093 opt_field(val->sam_nonce,0,asn1_decode_int32,0); 1094 opt_field(val->sam_timestamp,1,asn1_decode_kerberos_time,0); 1095 opt_field(val->sam_usec,2,asn1_decode_int32,0); 1096 opt_string(val->sam_sad,3,asn1_decode_charstring); 1097 end_structure(); 1098 val->magic = KV5M_ENC_SAM_RESPONSE_ENC; 1099 } 1100 cleanup(); 1101 } 1102 1103 asn1_error_code asn1_decode_enc_sam_response_enc_2(asn1buf *buf, krb5_enc_sam_response_enc_2 *val) 1104 { 1105 setup(); 1106 { begin_structure(); 1107 get_field(val->sam_nonce,0,asn1_decode_int32); 1108 opt_string(val->sam_sad,1,asn1_decode_charstring); 1109 end_structure(); 1110 val->magic = KV5M_ENC_SAM_RESPONSE_ENC_2; 1111 } 1112 cleanup(); 1113 } 1114 1115 #define opt_encfield(fld,tag,fn) \ 1116 if(tagnum == tag){ \ 1117 get_field(fld,tag,fn); } \ 1118 else{\ 1119 fld.magic = 0;\ 1120 fld.enctype = 0;\ 1121 fld.kvno = 0;\ 1122 fld.ciphertext.data = NULL;\ 1123 fld.ciphertext.length = 0;\ 1124 } 1125 1126 asn1_error_code asn1_decode_sam_response(asn1buf *buf, krb5_sam_response *val) 1127 { 1128 setup(); 1129 { begin_structure(); 1130 get_field(val->sam_type,0,asn1_decode_int32); 1131 get_field(val->sam_flags,1,asn1_decode_sam_flags); 1132 opt_string(val->sam_track_id,2,asn1_decode_charstring); 1133 opt_encfield(val->sam_enc_key,3,asn1_decode_encrypted_data); 1134 get_field(val->sam_enc_nonce_or_ts,4,asn1_decode_encrypted_data); 1135 opt_field(val->sam_nonce,5,asn1_decode_int32,0); 1136 opt_field(val->sam_patimestamp,6,asn1_decode_kerberos_time,0); 1137 end_structure(); 1138 val->magic = KV5M_SAM_RESPONSE; 1139 } 1140 cleanup(); 1141 } 1142 1143 asn1_error_code asn1_decode_sam_response_2(asn1buf *buf, krb5_sam_response_2 *val) 1144 { 1145 setup(); 1146 { begin_structure(); 1147 get_field(val->sam_type,0,asn1_decode_int32); 1148 get_field(val->sam_flags,1,asn1_decode_sam_flags); 1149 opt_string(val->sam_track_id,2,asn1_decode_charstring); 1150 get_field(val->sam_enc_nonce_or_sad,3,asn1_decode_encrypted_data); 1151 get_field(val->sam_nonce,4,asn1_decode_int32); 1152 end_structure(); 1153 val->magic = KV5M_SAM_RESPONSE; 1154 } 1155 cleanup(); 1156 } 1157 1158 1159 asn1_error_code asn1_decode_predicted_sam_response(asn1buf *buf, krb5_predicted_sam_response *val) 1160 { 1161 setup(); 1162 { begin_structure(); 1163 get_field(val->sam_key,0,asn1_decode_encryption_key); 1164 get_field(val->sam_flags,1,asn1_decode_sam_flags); 1165 get_field(val->stime,2,asn1_decode_kerberos_time); 1166 get_field(val->susec,3,asn1_decode_int32); 1167 alloc_field(val->client,krb5_principal_data); 1168 get_field(val->client,4,asn1_decode_realm); 1169 get_field(val->client,5,asn1_decode_principal_name); 1170 opt_string(val->msd,6,asn1_decode_charstring); /* should be octet */ 1171 end_structure(); 1172 val->magic = KV5M_PREDICTED_SAM_RESPONSE; 1173 } 1174 cleanup(); 1175 } 1176 1177 /* PKINIT */ 1178 1179 asn1_error_code asn1_decode_external_principal_identifier(asn1buf *buf, krb5_external_principal_identifier *val) 1180 { 1181 setup(); 1182 { 1183 begin_structure(); 1184 opt_implicit_octet_string(val->subjectName.length, val->subjectName.data, 0); 1185 opt_implicit_octet_string(val->issuerAndSerialNumber.length, val->issuerAndSerialNumber.data, 1); 1186 opt_implicit_octet_string(val->subjectKeyIdentifier.length, val->subjectKeyIdentifier.data, 2); 1187 end_structure(); 1188 } 1189 cleanup(); 1190 } 1191 1192 asn1_error_code asn1_decode_sequence_of_external_principal_identifier(asn1buf *buf, krb5_external_principal_identifier ***val) 1193 { 1194 decode_array_body(krb5_external_principal_identifier,asn1_decode_external_principal_identifier); 1195 } 1196 1197 asn1_error_code asn1_decode_pa_pk_as_req(asn1buf *buf, krb5_pa_pk_as_req *val) 1198 { 1199 setup(); 1200 { 1201 begin_structure(); 1202 get_implicit_octet_string(val->signedAuthPack.length, val->signedAuthPack.data, 0); 1203 opt_field(val->trustedCertifiers, 1, asn1_decode_sequence_of_external_principal_identifier, NULL); 1204 opt_implicit_octet_string(val->kdcPkId.length, val->kdcPkId.data, 2); 1205 end_structure(); 1206 } 1207 cleanup(); 1208 } 1209 1210 #if 0 /* XXX This needs to be tested!!! XXX */ 1211 asn1_error_code asn1_decode_trusted_ca(asn1buf *buf, krb5_trusted_ca *val) 1212 { 1213 setup(); 1214 { 1215 char *start, *end; 1216 size_t alloclen; 1217 1218 begin_explicit_choice(); 1219 if (t.tagnum == choice_trusted_cas_principalName) { 1220 val->choice = choice_trusted_cas_principalName; 1221 } else if (t.tagnum == choice_trusted_cas_caName) { 1222 val->choice = choice_trusted_cas_caName; 1223 start = subbuf.next; 1224 { 1225 sequence_of_no_tagvars(&subbuf); 1226 unused_var(size); 1227 end_sequence_of_no_tagvars(&subbuf); 1228 } 1229 end = subbuf.next; 1230 alloclen = end - start; 1231 val->u.caName.data = malloc(alloclen); 1232 if (val->u.caName.data == NULL) 1233 return ENOMEM; 1234 memcpy(val->u.caName.data, start, alloclen); 1235 val->u.caName.length = alloclen; 1236 next_tag(); 1237 } else if (t.tagnum == choice_trusted_cas_issuerAndSerial) { 1238 val->choice = choice_trusted_cas_issuerAndSerial; 1239 start = subbuf.next; 1240 { 1241 sequence_of_no_tagvars(&subbuf); 1242 unused_var(size); 1243 end_sequence_of_no_tagvars(&subbuf); 1244 } 1245 end = subbuf.next; 1246 alloclen = end - start; 1247 val->u.issuerAndSerial.data = malloc(alloclen); 1248 if (val->u.issuerAndSerial.data == NULL) 1249 return ENOMEM; 1250 memcpy(val->u.issuerAndSerial.data, start, alloclen); 1251 val->u.issuerAndSerial.length = alloclen; 1252 next_tag(); 1253 } else return ASN1_BAD_ID; 1254 end_explicit_choice(); 1255 } 1256 cleanup(); 1257 } 1258 #else 1259 asn1_error_code asn1_decode_trusted_ca(asn1buf *buf, krb5_trusted_ca *val) 1260 { 1261 setup(); 1262 { begin_choice(); 1263 if (tagnum == choice_trusted_cas_principalName) { 1264 val->choice = choice_trusted_cas_principalName; 1265 asn1_decode_krb5_principal_name(&subbuf, &(val->u.principalName)); 1266 } else if (tagnum == choice_trusted_cas_caName) { 1267 val->choice = choice_trusted_cas_caName; 1268 get_implicit_octet_string(val->u.caName.length, val->u.caName.data, choice_trusted_cas_caName); 1269 } else if (tagnum == choice_trusted_cas_issuerAndSerial) { 1270 val->choice = choice_trusted_cas_issuerAndSerial; 1271 get_implicit_octet_string(val->u.issuerAndSerial.length, val->u.issuerAndSerial.data, 1272 choice_trusted_cas_issuerAndSerial); 1273 } else return ASN1_BAD_ID; 1274 end_choice(); 1275 } 1276 cleanup(); 1277 } 1278 #endif 1279 1280 asn1_error_code asn1_decode_sequence_of_trusted_ca(asn1buf *buf, krb5_trusted_ca ***val) 1281 { 1282 decode_array_body(krb5_trusted_ca, asn1_decode_trusted_ca); 1283 } 1284 1285 asn1_error_code asn1_decode_pa_pk_as_req_draft9(asn1buf *buf, krb5_pa_pk_as_req_draft9 *val) 1286 { 1287 setup(); 1288 { begin_structure(); 1289 get_implicit_octet_string(val->signedAuthPack.length, val->signedAuthPack.data, 0); 1290 opt_field(val->trustedCertifiers, 1, asn1_decode_sequence_of_trusted_ca, NULL); 1291 opt_lenfield(val->kdcCert.length, val->kdcCert.data, 2, asn1_decode_octetstring); 1292 opt_lenfield(val->encryptionCert.length, val->encryptionCert.data, 2, asn1_decode_octetstring); 1293 end_structure(); 1294 } 1295 cleanup(); 1296 } 1297 1298 asn1_error_code asn1_decode_dh_rep_info(asn1buf *buf, krb5_dh_rep_info *val) 1299 { 1300 setup(); 1301 { begin_structure(); 1302 get_implicit_octet_string(val->dhSignedData.length, val->dhSignedData.data, 0); 1303 1304 opt_lenfield(val->serverDHNonce.length, val->serverDHNonce.data, 1, asn1_decode_octetstring); 1305 end_structure(); 1306 } 1307 cleanup(); 1308 } 1309 1310 asn1_error_code asn1_decode_pk_authenticator(asn1buf *buf, krb5_pk_authenticator *val) 1311 { 1312 setup(); 1313 { begin_structure(); 1314 get_field(val->cusec, 0, asn1_decode_int32); 1315 get_field(val->ctime, 1, asn1_decode_kerberos_time); 1316 get_field(val->nonce, 2, asn1_decode_int32); 1317 opt_lenfield(val->paChecksum.length, val->paChecksum.contents, 3, asn1_decode_octetstring); 1318 end_structure(); 1319 } 1320 cleanup(); 1321 } 1322 1323 asn1_error_code asn1_decode_pk_authenticator_draft9(asn1buf *buf, krb5_pk_authenticator_draft9 *val) 1324 { 1325 setup(); 1326 { begin_structure(); 1327 alloc_field(val->kdcName,krb5_principal_data); 1328 get_field(val->kdcName, 0, asn1_decode_principal_name); 1329 get_field(val->kdcName, 1, asn1_decode_realm); 1330 get_field(val->cusec, 2, asn1_decode_int32); 1331 get_field(val->ctime, 3, asn1_decode_kerberos_time); 1332 get_field(val->nonce, 4, asn1_decode_int32); 1333 end_structure(); 1334 } 1335 cleanup(); 1336 } 1337 1338 asn1_error_code asn1_decode_algorithm_identifier(asn1buf *buf, krb5_algorithm_identifier *val) { 1339 1340 setup(); 1341 { begin_structure_no_tag(); 1342 /* 1343 * Forbid indefinite encoding because we don't read enough tag 1344 * information from the trailing octets ("ANY DEFINED BY") to 1345 * synchronize EOC tags, etc. 1346 */ 1347 if (seqindef) return ASN1_BAD_FORMAT; 1348 /* 1349 * Set up tag variables because we don't actually call anything 1350 * that fetches tag info for us; it's all buried in the decoder 1351 * primitives. 1352 */ 1353 tagnum = ASN1_TAGNUM_CEILING; 1354 asn1class = UNIVERSAL; 1355 construction = PRIMITIVE; 1356 taglen = 0; 1357 indef = 0; 1358 retval = asn1_decode_oid(&subbuf, &val->algorithm.length, 1359 &val->algorithm.data); 1360 if(retval) return retval; 1361 val->parameters.length = 0; 1362 val->parameters.data = NULL; 1363 1364 if(length > subbuf.next - subbuf.base) { 1365 unsigned int size = length - (subbuf.next - subbuf.base); 1366 retval = asn1buf_remove_octetstring(&subbuf, size, 1367 &val->parameters.data); 1368 if(retval) return retval; 1369 val->parameters.length = size; 1370 } 1371 1372 end_structure(); 1373 } 1374 cleanup(); 1375 } 1376 1377 asn1_error_code asn1_decode_subject_pk_info(asn1buf *buf, krb5_subject_pk_info *val) 1378 { 1379 asn1_octet unused; 1380 setup(); 1381 { begin_structure_no_tag(); 1382 1383 retval = asn1_decode_algorithm_identifier(&subbuf, &val->algorithm); 1384 if (retval) return retval; 1385 1386 /* SubjectPublicKey encoded as a BIT STRING */ 1387 next_tag(); 1388 if (asn1class != UNIVERSAL || construction != PRIMITIVE || 1389 tagnum != ASN1_BITSTRING) 1390 return ASN1_BAD_ID; 1391 1392 retval = asn1buf_remove_octet(&subbuf, &unused); 1393 if(retval) return retval; 1394 1395 /* Number of unused bits must be between 0 and 7. */ 1396 /* What to do if unused is not zero? */ 1397 if (unused > 7) return ASN1_BAD_FORMAT; 1398 taglen--; 1399 1400 val->subjectPublicKey.length = 0; 1401 val->subjectPublicKey.data = NULL; 1402 retval = asn1buf_remove_octetstring(&subbuf, taglen, 1403 &val->subjectPublicKey.data); 1404 if(retval) return retval; 1405 val->subjectPublicKey.length = taglen; 1406 /* 1407 * We didn't call any macro that does next_tag(); do so now to 1408 * preload tag of any trailing encodings. 1409 */ 1410 next_tag(); 1411 end_structure(); 1412 } 1413 cleanup(); 1414 } 1415 1416 asn1_error_code asn1_decode_sequence_of_algorithm_identifier(asn1buf *buf, krb5_algorithm_identifier ***val) 1417 { 1418 decode_array_body(krb5_algorithm_identifier, asn1_decode_algorithm_identifier); 1419 } 1420 1421 asn1_error_code asn1_decode_kdc_dh_key_info (asn1buf *buf, krb5_kdc_dh_key_info *val) 1422 { 1423 setup(); 1424 { begin_structure(); 1425 retval = asn1buf_remove_octetstring(&subbuf, taglen, &val->subjectPublicKey.data); 1426 if(retval) return retval; 1427 val->subjectPublicKey.length = taglen; 1428 next_tag(); 1429 get_field(val->nonce, 1, asn1_decode_int32); 1430 opt_field(val->dhKeyExpiration, 2, asn1_decode_kerberos_time, 0); 1431 end_structure(); 1432 } 1433 cleanup(); 1434 } 1435 1436 asn1_error_code asn1_decode_reply_key_pack (asn1buf *buf, krb5_reply_key_pack *val) 1437 { 1438 setup(); 1439 { begin_structure(); 1440 get_field(val->replyKey, 0, asn1_decode_encryption_key); 1441 get_field(val->asChecksum, 1, asn1_decode_checksum); 1442 end_structure(); 1443 } 1444 cleanup(); 1445 } 1446 1447 asn1_error_code asn1_decode_reply_key_pack_draft9 (asn1buf *buf, krb5_reply_key_pack_draft9 *val) 1448 { 1449 setup(); 1450 { begin_structure(); 1451 get_field(val->replyKey, 0, asn1_decode_encryption_key); 1452 get_field(val->nonce, 1, asn1_decode_int32); 1453 end_structure(); 1454 } 1455 cleanup(); 1456 } 1457 1458 1459 asn1_error_code asn1_decode_krb5_principal_name (asn1buf *buf, krb5_principal *val) 1460 { 1461 setup(); 1462 { begin_structure(); 1463 get_field(*val, 0, asn1_decode_realm); 1464 get_field(*val, 1, asn1_decode_principal_name); 1465 end_structure(); 1466 } 1467 cleanup(); 1468 } 1469 1470 asn1_error_code asn1_decode_auth_pack(asn1buf *buf, krb5_auth_pack *val) 1471 { 1472 setup(); 1473 { begin_structure(); 1474 get_field(val->pkAuthenticator, 0, asn1_decode_pk_authenticator); 1475 if (tagnum == 1) { alloc_field(val->clientPublicValue, krb5_subject_pk_info); } 1476 /* can't call opt_field because it does decoder(&subbuf, &(val)); */ 1477 if (asn1buf_remains(&subbuf, seqindef)) { 1478 if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) 1479 && (tagnum || taglen || asn1class != UNIVERSAL)) 1480 return ASN1_BAD_ID; 1481 if (tagnum == 1) { 1482 retval = asn1_decode_subject_pk_info(&subbuf, 1483 val->clientPublicValue); 1484 if (!taglen && indef) { get_eoc(); } 1485 next_tag(); 1486 } else val->clientPublicValue = NULL; 1487 } 1488 /* can't call opt_field because it does decoder(&subbuf, &(val)); */ 1489 if (asn1buf_remains(&subbuf, seqindef)) { 1490 if (tagnum == 2) { 1491 asn1_decode_sequence_of_algorithm_identifier(&subbuf, &val->supportedCMSTypes); 1492 if (!taglen && indef) { get_eoc(); } 1493 next_tag(); 1494 } else val->supportedCMSTypes = NULL; 1495 } 1496 opt_lenfield(val->clientDHNonce.length, val->clientDHNonce.data, 3, asn1_decode_octetstring); 1497 end_structure(); 1498 } 1499 cleanup(); 1500 } 1501 1502 asn1_error_code asn1_decode_auth_pack_draft9(asn1buf *buf, krb5_auth_pack_draft9 *val) 1503 { 1504 setup(); 1505 { begin_structure(); 1506 get_field(val->pkAuthenticator, 0, asn1_decode_pk_authenticator_draft9); 1507 if (tagnum == 1) { 1508 alloc_field(val->clientPublicValue, krb5_subject_pk_info); 1509 /* can't call opt_field because it does decoder(&subbuf, &(val)); */ 1510 if (asn1buf_remains(&subbuf, seqindef)) { 1511 if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) 1512 && (tagnum || taglen || asn1class != UNIVERSAL)) 1513 return ASN1_BAD_ID; 1514 if (tagnum == 1) { 1515 retval = asn1_decode_subject_pk_info(&subbuf, 1516 val->clientPublicValue); 1517 if (!taglen && indef) { get_eoc(); } 1518 next_tag(); 1519 } else val->clientPublicValue = NULL; 1520 } 1521 } 1522 end_structure(); 1523 } 1524 cleanup(); 1525 } 1526 1527 asn1_error_code asn1_decode_pa_pk_as_rep(asn1buf *buf, krb5_pa_pk_as_rep *val) 1528 { 1529 setup(); 1530 { begin_choice(); 1531 if (tagnum == choice_pa_pk_as_rep_dhInfo) { 1532 val->choice = choice_pa_pk_as_rep_dhInfo; 1533 get_field_body(val->u.dh_Info, asn1_decode_dh_rep_info); 1534 } else if (tagnum == choice_pa_pk_as_rep_encKeyPack) { 1535 val->choice = choice_pa_pk_as_rep_encKeyPack; 1536 get_implicit_octet_string(val->u.encKeyPack.length, val->u.encKeyPack.data, 1537 choice_pa_pk_as_rep_encKeyPack); 1538 } else { 1539 val->choice = choice_pa_pk_as_rep_UNKNOWN; 1540 } 1541 end_choice(); 1542 } 1543 cleanup(); 1544 } 1545 1546 asn1_error_code asn1_decode_pa_pk_as_rep_draft9(asn1buf *buf, krb5_pa_pk_as_rep_draft9 *val) 1547 { 1548 setup(); 1549 { begin_structure(); 1550 if (tagnum == choice_pa_pk_as_rep_draft9_dhSignedData) { 1551 val->choice = choice_pa_pk_as_rep_draft9_dhSignedData; 1552 get_lenfield(val->u.dhSignedData.length, val->u.dhSignedData.data, 1553 choice_pa_pk_as_rep_draft9_dhSignedData, asn1_decode_octetstring); 1554 } else if (tagnum == choice_pa_pk_as_rep_draft9_encKeyPack) { 1555 val->choice = choice_pa_pk_as_rep_draft9_encKeyPack; 1556 get_lenfield(val->u.encKeyPack.length, val->u.encKeyPack.data, 1557 choice_pa_pk_as_rep_draft9_encKeyPack, asn1_decode_octetstring); 1558 } else { 1559 val->choice = choice_pa_pk_as_rep_draft9_UNKNOWN; 1560 } 1561 end_structure(); 1562 } 1563 cleanup(); 1564 } 1565 1566 asn1_error_code asn1_decode_sequence_of_typed_data(asn1buf *buf, krb5_typed_data ***val) 1567 { 1568 decode_array_body(krb5_typed_data,asn1_decode_typed_data); 1569 } 1570 1571 asn1_error_code asn1_decode_typed_data(asn1buf *buf, krb5_typed_data *val) 1572 { 1573 setup(); 1574 { begin_structure(); 1575 get_field(val->type,0,asn1_decode_int32); 1576 get_lenfield(val->length,val->data,1,asn1_decode_octetstring); 1577 end_structure(); 1578 } 1579 cleanup(); 1580 } 1581