1 /* 2 * src/lib/krb5/asn.1/krb5_decode.c 3 * 4 * Copyright 1994 by the Massachusetts Institute of Technology. 5 * All Rights Reserved. 6 * 7 * Export of this software from the United States of America may 8 * require a specific license from the United States Government. 9 * It is the responsibility of any person or organization contemplating 10 * export to obtain such a license before exporting. 11 * 12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 13 * distribute this software and its documentation for any purpose and 14 * without fee is hereby granted, provided that the above copyright 15 * notice appear in all copies and that both that copyright notice and 16 * this permission notice appear in supporting documentation, and that 17 * the name of M.I.T. not be used in advertising or publicity pertaining 18 * to distribution of the software without specific, written prior 19 * permission. Furthermore if you modify this software you must label 20 * your software as modified software and not distribute it in such a 21 * fashion that it might be confused with the original M.I.T. software. 22 * M.I.T. makes no representations about the suitability of 23 * this software for any purpose. It is provided "as is" without express 24 * or implied warranty. 25 */ 26 27 #include "k5-int.h" 28 #include "krbasn1.h" 29 #include "asn1_k_decode.h" 30 #include "asn1_decode.h" 31 #include "asn1_get.h" 32 33 /* setup *********************************************************/ 34 /* set up variables */ 35 /* the setup* macros can return, but are always used at function start 36 and thus need no malloc cleanup */ 37 #define setup_buf_only()\ 38 asn1_error_code retval;\ 39 asn1buf buf;\ 40 \ 41 retval = asn1buf_wrap_data(&buf,code);\ 42 if(retval) return retval 43 44 #define setup_no_tagnum()\ 45 asn1_class asn1class;\ 46 asn1_construction construction;\ 47 setup_buf_only() 48 49 #define setup_no_length()\ 50 asn1_tagnum tagnum;\ 51 setup_no_tagnum() 52 53 #define setup()\ 54 unsigned int length;\ 55 setup_no_length() 56 57 /* helper macros for cleanup */ 58 #define clean_return(val) { retval = val; goto error_out; } 59 60 /* alloc_field is the first thing to allocate storage that may need cleanup */ 61 #define alloc_field(var,type)\ 62 var = (type*)calloc(1,sizeof(type));\ 63 if((var) == NULL) clean_return(ENOMEM) 64 65 /* process encoding header ***************************************/ 66 /* decode tag and check that it == [APPLICATION tagnum] */ 67 #define check_apptag(tagexpect) \ 68 { \ 69 taginfo t1; \ 70 retval = asn1_get_tag_2(&buf, &t1); \ 71 if (retval) clean_return (retval); \ 72 if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED) \ 73 clean_return(ASN1_BAD_ID); \ 74 if (t1.tagnum != (tagexpect)) clean_return(KRB5_BADMSGTYPE); \ 75 asn1class = t1.asn1class; \ 76 construction = t1.construction; \ 77 tagnum = t1.tagnum; \ 78 } 79 80 81 82 /* process a structure *******************************************/ 83 84 /* decode an explicit tag and place the number in tagnum */ 85 #define next_tag() \ 86 { taginfo t2; \ 87 retval = asn1_get_tag_2(&subbuf, &t2); \ 88 if(retval) clean_return(retval); \ 89 asn1class = t2.asn1class; \ 90 construction = t2.construction; \ 91 tagnum = t2.tagnum; \ 92 indef = t2.indef; \ 93 taglen = t2.length; \ 94 } 95 96 #define get_eoc() \ 97 { \ 98 taginfo t3; \ 99 retval = asn1_get_tag_2(&subbuf, &t3); \ 100 if (retval) return retval; \ 101 if (t3.asn1class != UNIVERSAL || t3.tagnum || t3.indef) \ 102 return ASN1_MISSING_EOC; \ 103 asn1class = t3.asn1class; \ 104 construction = t3.construction; \ 105 tagnum = t3.tagnum; \ 106 indef = t3.indef; \ 107 } 108 109 /* decode sequence header and initialize tagnum with the first field */ 110 #define begin_structure()\ 111 unsigned int taglen;\ 112 asn1buf subbuf;\ 113 int seqindef;\ 114 int indef;\ 115 retval = asn1_get_sequence(&buf,&length,&seqindef);\ 116 if(retval) clean_return(retval);\ 117 retval = asn1buf_imbed(&subbuf,&buf,length,seqindef);\ 118 if(retval) clean_return(retval);\ 119 next_tag() 120 121 #define end_structure()\ 122 retval = asn1buf_sync(&buf,&subbuf,asn1class,tagnum,length,indef,seqindef);\ 123 if (retval) clean_return(retval) 124 125 /* process fields *******************************************/ 126 /* normal fields ************************/ 127 #define get_field_body(var,decoder)\ 128 retval = decoder(&subbuf,&(var));\ 129 if(retval) clean_return(retval);\ 130 if (indef) { get_eoc(); }\ 131 next_tag() 132 133 /* decode a field (<[UNIVERSAL id]> <length> <contents>) 134 check that the id number == tagexpect then 135 decode into var 136 get the next tag */ 137 #define get_field(var,tagexpect,decoder)\ 138 if(tagnum > (tagexpect)) clean_return(ASN1_MISSING_FIELD);\ 139 if(tagnum < (tagexpect)) clean_return(ASN1_MISPLACED_FIELD);\ 140 if(asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\ 141 clean_return(ASN1_BAD_ID);\ 142 get_field_body(var,decoder) 143 144 /* decode (or skip, if not present) an optional field */ 145 #define opt_field(var,tagexpect,decoder) \ 146 if (asn1buf_remains(&subbuf, seqindef)) { \ 147 if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ 148 clean_return(ASN1_BAD_ID); \ 149 if (tagnum == (tagexpect)) { \ 150 get_field_body(var,decoder); \ 151 } \ 152 } 153 154 /* field w/ accompanying length *********/ 155 #define get_lenfield_body(len,var,decoder)\ 156 retval = decoder(&subbuf,&(len),&(var));\ 157 if(retval) clean_return(retval);\ 158 if (indef) { get_eoc(); }\ 159 next_tag() 160 161 /* decode a field w/ its length (for string types) */ 162 #define get_lenfield(len,var,tagexpect,decoder)\ 163 if(tagnum > (tagexpect)) clean_return(ASN1_MISSING_FIELD);\ 164 if(tagnum < (tagexpect)) clean_return(ASN1_MISPLACED_FIELD);\ 165 if(asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)\ 166 clean_return(ASN1_BAD_ID);\ 167 get_lenfield_body(len,var,decoder) 168 169 /* decode an optional field w/ length */ 170 #define opt_lenfield(len,var,tagexpect,decoder) \ 171 if (asn1buf_remains(&subbuf, seqindef)) { \ 172 if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \ 173 clean_return(ASN1_BAD_ID); \ 174 if (tagnum == (tagexpect)) { \ 175 get_lenfield_body(len,var,decoder); \ 176 } \ 177 } 178 179 180 /* clean up ******************************************************/ 181 /* finish up */ 182 /* to make things less painful, assume the cleanup is passed rep */ 183 #define cleanup(cleanup_routine)\ 184 return 0; \ 185 error_out: \ 186 if (rep && *rep) { \ 187 cleanup_routine(*rep); \ 188 *rep = NULL; \ 189 } \ 190 return retval; 191 192 #define cleanup_none()\ 193 return 0; \ 194 error_out: \ 195 return retval; 196 197 #define cleanup_manual()\ 198 return 0; 199 200 #define free_field(rep,f) if ((rep)->f) free((rep)->f) 201 #define clear_field(rep,f) (*(rep))->f = 0 202 203 krb5_error_code decode_krb5_authenticator(const krb5_data *code, krb5_authenticator **rep) 204 { 205 setup(); 206 alloc_field(*rep,krb5_authenticator); 207 clear_field(rep,subkey); 208 clear_field(rep,checksum); 209 clear_field(rep,client); 210 211 check_apptag(2); 212 { begin_structure(); 213 { krb5_kvno kvno; 214 get_field(kvno,0,asn1_decode_kvno); 215 if(kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); } 216 alloc_field((*rep)->client,krb5_principal_data); 217 get_field((*rep)->client,1,asn1_decode_realm); 218 get_field((*rep)->client,2,asn1_decode_principal_name); 219 if(tagnum == 3){ 220 alloc_field((*rep)->checksum,krb5_checksum); 221 get_field(*((*rep)->checksum),3,asn1_decode_checksum); } 222 get_field((*rep)->cusec,4,asn1_decode_int32); 223 get_field((*rep)->ctime,5,asn1_decode_kerberos_time); 224 if(tagnum == 6){ alloc_field((*rep)->subkey,krb5_keyblock); } 225 opt_field(*((*rep)->subkey),6,asn1_decode_encryption_key); 226 opt_field((*rep)->seq_number,7,asn1_decode_seqnum); 227 opt_field((*rep)->authorization_data,8,asn1_decode_authorization_data); 228 (*rep)->magic = KV5M_AUTHENTICATOR; 229 end_structure(); 230 } 231 cleanup_manual(); 232 error_out: 233 if (rep && *rep) { 234 free_field(*rep,subkey); 235 free_field(*rep,checksum); 236 free_field(*rep,client); 237 free(*rep); 238 *rep = NULL; 239 } 240 return retval; 241 } 242 243 krb5_error_code 244 KRB5_CALLCONV 245 krb5_decode_ticket(const krb5_data *code, krb5_ticket **rep) 246 { 247 return decode_krb5_ticket(code, rep); 248 } 249 250 krb5_error_code decode_krb5_ticket(const krb5_data *code, krb5_ticket **rep) 251 { 252 setup(); 253 alloc_field(*rep,krb5_ticket); 254 clear_field(rep,server); 255 256 check_apptag(1); 257 { begin_structure(); 258 { krb5_kvno kvno; 259 get_field(kvno,0,asn1_decode_kvno); 260 if(kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); 261 } 262 alloc_field((*rep)->server,krb5_principal_data); 263 get_field((*rep)->server,1,asn1_decode_realm); 264 get_field((*rep)->server,2,asn1_decode_principal_name); 265 get_field((*rep)->enc_part,3,asn1_decode_encrypted_data); 266 (*rep)->magic = KV5M_TICKET; 267 end_structure(); 268 } 269 cleanup_manual(); 270 error_out: 271 if (rep && *rep) { 272 free_field(*rep,server); 273 free(*rep); 274 *rep = NULL; 275 } 276 return retval; 277 } 278 279 krb5_error_code decode_krb5_encryption_key(const krb5_data *code, krb5_keyblock **rep) 280 { 281 setup(); 282 alloc_field(*rep,krb5_keyblock); 283 284 { begin_structure(); 285 get_field((*rep)->enctype,0,asn1_decode_enctype); 286 get_lenfield((*rep)->length,(*rep)->contents,1,asn1_decode_octetstring); 287 end_structure(); 288 (*rep)->magic = KV5M_KEYBLOCK; 289 } 290 cleanup(free); 291 } 292 293 krb5_error_code decode_krb5_enc_tkt_part(const krb5_data *code, krb5_enc_tkt_part **rep) 294 { 295 setup(); 296 alloc_field(*rep,krb5_enc_tkt_part); 297 clear_field(rep,session); 298 clear_field(rep,client); 299 300 check_apptag(3); 301 { begin_structure(); 302 get_field((*rep)->flags,0,asn1_decode_ticket_flags); 303 alloc_field((*rep)->session,krb5_keyblock); 304 get_field(*((*rep)->session),1,asn1_decode_encryption_key); 305 alloc_field((*rep)->client,krb5_principal_data); 306 get_field((*rep)->client,2,asn1_decode_realm); 307 get_field((*rep)->client,3,asn1_decode_principal_name); 308 get_field((*rep)->transited,4,asn1_decode_transited_encoding); 309 get_field((*rep)->times.authtime,5,asn1_decode_kerberos_time); 310 if (tagnum == 6) 311 { get_field((*rep)->times.starttime,6,asn1_decode_kerberos_time); } 312 else 313 (*rep)->times.starttime=(*rep)->times.authtime; 314 get_field((*rep)->times.endtime,7,asn1_decode_kerberos_time); 315 opt_field((*rep)->times.renew_till,8,asn1_decode_kerberos_time); 316 opt_field((*rep)->caddrs,9,asn1_decode_host_addresses); 317 opt_field((*rep)->authorization_data,10,asn1_decode_authorization_data); 318 (*rep)->magic = KV5M_ENC_TKT_PART; 319 end_structure(); 320 } 321 cleanup_manual(); 322 error_out: 323 if (rep && *rep) { 324 free_field(*rep,session); 325 free_field(*rep,client); 326 free(*rep); 327 *rep = NULL; 328 } 329 return retval; 330 } 331 332 krb5_error_code decode_krb5_enc_kdc_rep_part(const krb5_data *code, krb5_enc_kdc_rep_part **rep) 333 { 334 taginfo t4; 335 setup_buf_only(); 336 alloc_field(*rep,krb5_enc_kdc_rep_part); 337 338 retval = asn1_get_tag_2(&buf, &t4); 339 if (retval) clean_return(retval); 340 if (t4.asn1class != APPLICATION || t4.construction != CONSTRUCTED) clean_return(ASN1_BAD_ID); 341 if (t4.tagnum == 25) (*rep)->msg_type = KRB5_AS_REP; 342 else if(t4.tagnum == 26) (*rep)->msg_type = KRB5_TGS_REP; 343 else clean_return(KRB5_BADMSGTYPE); 344 345 retval = asn1_decode_enc_kdc_rep_part(&buf,*rep); 346 if(retval) clean_return(retval); 347 348 cleanup(free); 349 } 350 351 krb5_error_code decode_krb5_as_rep(const krb5_data *code, krb5_kdc_rep **rep) 352 { 353 setup_no_length(); 354 alloc_field(*rep,krb5_kdc_rep); 355 356 check_apptag(11); 357 retval = asn1_decode_kdc_rep(&buf,*rep); 358 if(retval) clean_return(retval); 359 #ifdef KRB5_MSGTYPE_STRICT 360 if((*rep)->msg_type != KRB5_AS_REP) 361 clean_return(KRB5_BADMSGTYPE); 362 #endif 363 364 cleanup(free); 365 } 366 367 krb5_error_code decode_krb5_tgs_rep(const krb5_data *code, krb5_kdc_rep **rep) 368 { 369 setup_no_length(); 370 alloc_field(*rep,krb5_kdc_rep); 371 372 check_apptag(13); 373 retval = asn1_decode_kdc_rep(&buf,*rep); 374 if(retval) clean_return(retval); 375 #ifdef KRB5_MSGTYPE_STRICT 376 if((*rep)->msg_type != KRB5_TGS_REP) clean_return(KRB5_BADMSGTYPE); 377 #endif 378 379 cleanup(free); 380 } 381 382 krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep) 383 { 384 setup(); 385 alloc_field(*rep,krb5_ap_req); 386 clear_field(rep,ticket); 387 388 check_apptag(14); 389 { begin_structure(); 390 { krb5_kvno kvno; 391 get_field(kvno,0,asn1_decode_kvno); 392 if(kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); } 393 { krb5_msgtype msg_type; 394 get_field(msg_type,1,asn1_decode_msgtype); 395 #ifdef KRB5_MSGTYPE_STRICT 396 if(msg_type != KRB5_AP_REQ) clean_return(KRB5_BADMSGTYPE); 397 #endif 398 } 399 get_field((*rep)->ap_options,2,asn1_decode_ap_options); 400 alloc_field((*rep)->ticket,krb5_ticket); 401 get_field(*((*rep)->ticket),3,asn1_decode_ticket); 402 get_field((*rep)->authenticator,4,asn1_decode_encrypted_data); 403 end_structure(); 404 (*rep)->magic = KV5M_AP_REQ; 405 } 406 cleanup_manual(); 407 error_out: 408 if (rep && *rep) { 409 free_field(*rep,ticket); 410 free(*rep); 411 *rep = NULL; 412 } 413 return retval; 414 } 415 416 krb5_error_code decode_krb5_ap_rep(const krb5_data *code, krb5_ap_rep **rep) 417 { 418 setup(); 419 alloc_field(*rep,krb5_ap_rep); 420 421 check_apptag(15); 422 { begin_structure(); 423 { krb5_kvno kvno; 424 get_field(kvno,0,asn1_decode_kvno); 425 if(kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); } 426 { krb5_msgtype msg_type; 427 get_field(msg_type,1,asn1_decode_msgtype); 428 #ifdef KRB5_MSGTYPE_STRICT 429 if(msg_type != KRB5_AP_REP) clean_return(KRB5_BADMSGTYPE); 430 #endif 431 } 432 get_field((*rep)->enc_part,2,asn1_decode_encrypted_data); 433 end_structure(); 434 (*rep)->magic = KV5M_AP_REP; 435 } 436 cleanup(free); 437 } 438 439 krb5_error_code decode_krb5_ap_rep_enc_part(const krb5_data *code, krb5_ap_rep_enc_part **rep) 440 { 441 setup(); 442 alloc_field(*rep,krb5_ap_rep_enc_part); 443 clear_field(rep,subkey); 444 445 check_apptag(27); 446 { begin_structure(); 447 get_field((*rep)->ctime,0,asn1_decode_kerberos_time); 448 get_field((*rep)->cusec,1,asn1_decode_int32); 449 if(tagnum == 2){ alloc_field((*rep)->subkey,krb5_keyblock); } 450 opt_field(*((*rep)->subkey),2,asn1_decode_encryption_key); 451 opt_field((*rep)->seq_number,3,asn1_decode_seqnum); 452 end_structure(); 453 (*rep)->magic = KV5M_AP_REP_ENC_PART; 454 } 455 cleanup_manual(); 456 error_out: 457 if (rep && *rep) { 458 free_field(*rep,subkey); 459 free(*rep); 460 *rep = NULL; 461 } 462 return retval; 463 } 464 465 krb5_error_code decode_krb5_as_req(const krb5_data *code, krb5_kdc_req **rep) 466 { 467 setup_no_length(); 468 alloc_field(*rep,krb5_kdc_req); 469 470 check_apptag(10); 471 retval = asn1_decode_kdc_req(&buf,*rep); 472 if(retval) clean_return(retval); 473 #ifdef KRB5_MSGTYPE_STRICT 474 if((*rep)->msg_type != KRB5_AS_REQ) clean_return(KRB5_BADMSGTYPE); 475 #endif 476 477 cleanup(free); 478 } 479 480 krb5_error_code decode_krb5_tgs_req(const krb5_data *code, krb5_kdc_req **rep) 481 { 482 setup_no_length(); 483 alloc_field(*rep,krb5_kdc_req); 484 485 check_apptag(12); 486 retval = asn1_decode_kdc_req(&buf,*rep); 487 if(retval) clean_return(retval); 488 #ifdef KRB5_MSGTYPE_STRICT 489 if((*rep)->msg_type != KRB5_TGS_REQ) clean_return(KRB5_BADMSGTYPE); 490 #endif 491 492 cleanup(free); 493 } 494 495 krb5_error_code decode_krb5_kdc_req_body(const krb5_data *code, krb5_kdc_req **rep) 496 { 497 setup_buf_only(); 498 alloc_field(*rep,krb5_kdc_req); 499 500 retval = asn1_decode_kdc_req_body(&buf,*rep); 501 if(retval) clean_return(retval); 502 503 cleanup(free); 504 } 505 506 /* 507 * decode_krb5_safe_with_body 508 * 509 * Like decode_krb5_safe(), but grabs the encoding of the 510 * KRB-SAFE-BODY as well, in case re-encoding would produce a 511 * different encoding. (Yes, we're using DER, but there's this 512 * annoying problem with pre-1.3.x code using signed sequence numbers, 513 * which we permissively decode and cram into unsigned 32-bit numbers. 514 * When they're re-encoded, they're no longer negative if they started 515 * out negative, so checksum verification fails.) 516 * 517 * This does *not* perform any copying; the returned pointer to the 518 * encoded KRB-SAFE-BODY points into the input buffer. 519 */ 520 krb5_error_code decode_krb5_safe_with_body( 521 const krb5_data *code, 522 krb5_safe **rep, 523 krb5_data *body) 524 { 525 krb5_data tmpbody; 526 setup(); 527 alloc_field(*rep,krb5_safe); 528 clear_field(rep,checksum); 529 tmpbody.magic = 0; 530 531 check_apptag(20); 532 { begin_structure(); 533 { krb5_kvno kvno; 534 get_field(kvno,0,asn1_decode_kvno); 535 if(kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); } 536 { krb5_msgtype msg_type; 537 get_field(msg_type,1,asn1_decode_msgtype); 538 #ifdef KRB5_MSGTYPE_STRICT 539 if(msg_type != KRB5_SAFE) clean_return(KRB5_BADMSGTYPE); 540 #endif 541 } 542 /* 543 * Gross kludge to extract pointer to encoded safe-body. Relies 544 * on tag prefetch done by next_tag(). Don't handle indefinite 545 * encoding, as it's too much work. 546 */ 547 if (!indef) { 548 tmpbody.length = taglen; 549 tmpbody.data = subbuf.next; 550 } else { 551 tmpbody.length = 0; 552 tmpbody.data = NULL; 553 } 554 get_field(**rep,2,asn1_decode_krb_safe_body); 555 alloc_field((*rep)->checksum,krb5_checksum); 556 get_field(*((*rep)->checksum),3,asn1_decode_checksum); 557 (*rep)->magic = KV5M_SAFE; 558 end_structure(); 559 } 560 if (body != NULL) 561 *body = tmpbody; 562 cleanup_manual(); 563 error_out: 564 if (rep && *rep) { 565 free_field(*rep,checksum); 566 free(*rep); 567 *rep = NULL; 568 } 569 return retval; 570 } 571 572 krb5_error_code decode_krb5_safe(const krb5_data *code, krb5_safe **rep) 573 { 574 return decode_krb5_safe_with_body(code, rep, NULL); 575 } 576 577 krb5_error_code decode_krb5_priv(const krb5_data *code, krb5_priv **rep) 578 { 579 setup(); 580 alloc_field(*rep,krb5_priv); 581 582 check_apptag(21); 583 { begin_structure(); 584 { krb5_kvno kvno; 585 get_field(kvno,0,asn1_decode_kvno); 586 if(kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); } 587 { krb5_msgtype msg_type; 588 get_field(msg_type,1,asn1_decode_msgtype); 589 #ifdef KRB5_MSGTYPE_STRICT 590 if(msg_type != KRB5_PRIV) clean_return(KRB5_BADMSGTYPE); 591 #endif 592 } 593 get_field((*rep)->enc_part,3,asn1_decode_encrypted_data); 594 (*rep)->magic = KV5M_PRIV; 595 end_structure(); 596 } 597 cleanup(free); 598 } 599 600 krb5_error_code decode_krb5_enc_priv_part(const krb5_data *code, krb5_priv_enc_part **rep) 601 { 602 setup(); 603 alloc_field(*rep,krb5_priv_enc_part); 604 clear_field(rep,r_address); 605 clear_field(rep,s_address); 606 607 check_apptag(28); 608 { begin_structure(); 609 get_lenfield((*rep)->user_data.length,(*rep)->user_data.data,0,asn1_decode_charstring); 610 opt_field((*rep)->timestamp,1,asn1_decode_kerberos_time); 611 opt_field((*rep)->usec,2,asn1_decode_int32); 612 opt_field((*rep)->seq_number,3,asn1_decode_seqnum); 613 alloc_field((*rep)->s_address,krb5_address); 614 get_field(*((*rep)->s_address),4,asn1_decode_host_address); 615 if(tagnum == 5){ alloc_field((*rep)->r_address,krb5_address); } 616 opt_field(*((*rep)->r_address),5,asn1_decode_host_address); 617 (*rep)->magic = KV5M_PRIV_ENC_PART; 618 end_structure(); 619 } 620 cleanup_manual(); 621 error_out: 622 if (rep && *rep) { 623 free_field(*rep,r_address); 624 free_field(*rep,s_address); 625 free(*rep); 626 *rep = NULL; 627 } 628 return retval; 629 } 630 631 krb5_error_code decode_krb5_cred(const krb5_data *code, krb5_cred **rep) 632 { 633 setup(); 634 alloc_field(*rep,krb5_cred); 635 636 check_apptag(22); 637 { begin_structure(); 638 { krb5_kvno kvno; 639 get_field(kvno,0,asn1_decode_kvno); 640 if(kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); } 641 { krb5_msgtype msg_type; 642 get_field(msg_type,1,asn1_decode_msgtype); 643 #ifdef KRB5_MSGTYPE_STRICT 644 if(msg_type != KRB5_CRED) clean_return(KRB5_BADMSGTYPE); 645 #endif 646 } 647 get_field((*rep)->tickets,2,asn1_decode_sequence_of_ticket); 648 get_field((*rep)->enc_part,3,asn1_decode_encrypted_data); 649 (*rep)->magic = KV5M_CRED; 650 end_structure(); 651 } 652 cleanup(free); 653 } 654 655 krb5_error_code decode_krb5_enc_cred_part(const krb5_data *code, krb5_cred_enc_part **rep) 656 { 657 setup(); 658 alloc_field(*rep,krb5_cred_enc_part); 659 clear_field(rep,r_address); 660 clear_field(rep,s_address); 661 662 check_apptag(29); 663 { begin_structure(); 664 get_field((*rep)->ticket_info,0,asn1_decode_sequence_of_krb_cred_info); 665 opt_field((*rep)->nonce,1,asn1_decode_int32); 666 opt_field((*rep)->timestamp,2,asn1_decode_kerberos_time); 667 opt_field((*rep)->usec,3,asn1_decode_int32); 668 if(tagnum == 4){ alloc_field((*rep)->s_address,krb5_address); } 669 opt_field(*((*rep)->s_address),4,asn1_decode_host_address); 670 if(tagnum == 5){ alloc_field((*rep)->r_address,krb5_address); } 671 opt_field(*((*rep)->r_address),5,asn1_decode_host_address); 672 (*rep)->magic = KV5M_CRED_ENC_PART; 673 end_structure(); 674 } 675 cleanup_manual(); 676 error_out: 677 if (rep && *rep) { 678 free_field(*rep,r_address); 679 free_field(*rep,s_address); 680 free(*rep); 681 *rep = NULL; 682 } 683 return retval; 684 } 685 686 687 krb5_error_code decode_krb5_error(const krb5_data *code, krb5_error **rep) 688 { 689 setup(); 690 alloc_field(*rep,krb5_error); 691 clear_field(rep,server); 692 clear_field(rep,client); 693 694 check_apptag(30); 695 { begin_structure(); 696 { krb5_kvno kvno; 697 get_field(kvno,0,asn1_decode_kvno); 698 if(kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); } 699 { krb5_msgtype msg_type; 700 get_field(msg_type,1,asn1_decode_msgtype); 701 #ifdef KRB5_MSGTYPE_STRICT 702 if(msg_type != KRB5_ERROR) clean_return(KRB5_BADMSGTYPE); 703 #endif 704 } 705 opt_field((*rep)->ctime,2,asn1_decode_kerberos_time); 706 opt_field((*rep)->cusec,3,asn1_decode_int32); 707 get_field((*rep)->stime,4,asn1_decode_kerberos_time); 708 get_field((*rep)->susec,5,asn1_decode_int32); 709 get_field((*rep)->error,6,asn1_decode_ui_4); 710 if(tagnum == 7){ alloc_field((*rep)->client,krb5_principal_data); } 711 opt_field((*rep)->client,7,asn1_decode_realm); 712 opt_field((*rep)->client,8,asn1_decode_principal_name); 713 alloc_field((*rep)->server,krb5_principal_data); 714 get_field((*rep)->server,9,asn1_decode_realm); 715 get_field((*rep)->server,10,asn1_decode_principal_name); 716 opt_lenfield((*rep)->text.length,(*rep)->text.data,11,asn1_decode_generalstring); 717 opt_lenfield((*rep)->e_data.length,(*rep)->e_data.data,12,asn1_decode_charstring); 718 (*rep)->magic = KV5M_ERROR; 719 end_structure(); 720 } 721 cleanup_manual(); 722 error_out: 723 if (rep && *rep) { 724 free_field(*rep,server); 725 free_field(*rep,client); 726 free(*rep); 727 *rep = NULL; 728 } 729 return retval; 730 } 731 732 krb5_error_code decode_krb5_authdata(const krb5_data *code, krb5_authdata ***rep) 733 { 734 setup_buf_only(); 735 *rep = 0; 736 retval = asn1_decode_authorization_data(&buf,rep); 737 if(retval) clean_return(retval); 738 cleanup_none(); /* we're not allocating anything here... */ 739 } 740 741 krb5_error_code decode_krb5_pwd_sequence(const krb5_data *code, passwd_phrase_element **rep) 742 { 743 setup_buf_only(); 744 alloc_field(*rep,passwd_phrase_element); 745 retval = asn1_decode_passwdsequence(&buf,*rep); 746 if(retval) clean_return(retval); 747 cleanup(free); 748 } 749 750 krb5_error_code decode_krb5_pwd_data(const krb5_data *code, krb5_pwd_data **rep) 751 { 752 setup(); 753 alloc_field(*rep,krb5_pwd_data); 754 { begin_structure(); 755 get_field((*rep)->sequence_count,0,asn1_decode_int); 756 get_field((*rep)->element,1,asn1_decode_sequence_of_passwdsequence); 757 (*rep)->magic = KV5M_PWD_DATA; 758 end_structure (); } 759 cleanup(free); 760 } 761 762 krb5_error_code decode_krb5_padata_sequence(const krb5_data *code, krb5_pa_data ***rep) 763 { 764 setup_buf_only(); 765 *rep = 0; 766 retval = asn1_decode_sequence_of_pa_data(&buf,rep); 767 if(retval) clean_return(retval); 768 cleanup_none(); /* we're not allocating anything here */ 769 } 770 771 krb5_error_code decode_krb5_alt_method(const krb5_data *code, krb5_alt_method **rep) 772 { 773 setup(); 774 alloc_field(*rep,krb5_alt_method); 775 { begin_structure(); 776 get_field((*rep)->method,0,asn1_decode_int32); 777 if (tagnum == 1) { 778 get_lenfield((*rep)->length,(*rep)->data,1,asn1_decode_octetstring); 779 } else { 780 (*rep)->length = 0; 781 (*rep)->data = 0; 782 } 783 (*rep)->magic = KV5M_ALT_METHOD; 784 end_structure(); 785 } 786 cleanup(free); 787 } 788 789 krb5_error_code decode_krb5_etype_info(const krb5_data *code, krb5_etype_info_entry ***rep) 790 { 791 setup_buf_only(); 792 *rep = 0; 793 retval = asn1_decode_etype_info(&buf,rep); 794 if(retval) clean_return(retval); 795 cleanup_none(); /* we're not allocating anything here */ 796 } 797 798 krb5_error_code decode_krb5_etype_info2(const krb5_data *code, krb5_etype_info_entry ***rep) 799 { 800 setup_buf_only(); 801 *rep = 0; 802 retval = asn1_decode_etype_info2(&buf,rep, 0); 803 if (retval == ASN1_BAD_ID) { 804 retval = asn1buf_wrap_data(&buf,code); 805 if(retval) clean_return(retval); 806 retval = asn1_decode_etype_info2(&buf, rep, 1); 807 } 808 if(retval) clean_return(retval); 809 cleanup_none(); /* we're not allocating anything here */ 810 } 811 812 813 krb5_error_code decode_krb5_enc_data(const krb5_data *code, krb5_enc_data **rep) 814 { 815 setup_buf_only(); 816 alloc_field(*rep,krb5_enc_data); 817 818 retval = asn1_decode_encrypted_data(&buf,*rep); 819 if(retval) clean_return(retval); 820 821 cleanup(free); 822 } 823 824 krb5_error_code decode_krb5_pa_enc_ts(const krb5_data *code, krb5_pa_enc_ts **rep) 825 { 826 setup(); 827 alloc_field(*rep,krb5_pa_enc_ts); 828 { begin_structure(); 829 get_field((*rep)->patimestamp,0,asn1_decode_kerberos_time); 830 if (tagnum == 1) { 831 get_field((*rep)->pausec,1,asn1_decode_int32); 832 } else 833 (*rep)->pausec = 0; 834 end_structure (); } 835 cleanup(free); 836 } 837 838 krb5_error_code decode_krb5_sam_challenge(const krb5_data *code, krb5_sam_challenge **rep) 839 { 840 setup_buf_only(); 841 alloc_field(*rep,krb5_sam_challenge); 842 843 retval = asn1_decode_sam_challenge(&buf,*rep); 844 if(retval) clean_return(retval); 845 846 cleanup(free); 847 } 848 849 krb5_error_code decode_krb5_sam_challenge_2(const krb5_data *code, krb5_sam_challenge_2 **rep) 850 { 851 setup_buf_only(); 852 alloc_field(*rep,krb5_sam_challenge_2); 853 854 retval = asn1_decode_sam_challenge_2(&buf,*rep); 855 if(retval) clean_return(retval); 856 857 cleanup(free); 858 } 859 860 krb5_error_code decode_krb5_sam_challenge_2_body(const krb5_data *code, krb5_sam_challenge_2_body **rep) 861 { 862 setup_buf_only(); 863 alloc_field(*rep, krb5_sam_challenge_2_body); 864 865 retval = asn1_decode_sam_challenge_2_body(&buf, *rep); 866 if(retval) clean_return(retval); 867 868 cleanup(free); 869 } 870 871 krb5_error_code decode_krb5_enc_sam_key(const krb5_data *code, krb5_sam_key **rep) 872 { 873 setup_buf_only(); 874 alloc_field(*rep,krb5_sam_key); 875 876 retval = asn1_decode_enc_sam_key(&buf,*rep); 877 if(retval) clean_return(retval); 878 879 cleanup(free); 880 } 881 882 krb5_error_code decode_krb5_enc_sam_response_enc(const krb5_data *code, krb5_enc_sam_response_enc **rep) 883 { 884 setup_buf_only(); 885 alloc_field(*rep,krb5_enc_sam_response_enc); 886 887 retval = asn1_decode_enc_sam_response_enc(&buf,*rep); 888 if(retval) clean_return(retval); 889 890 cleanup(free); 891 } 892 893 krb5_error_code decode_krb5_enc_sam_response_enc_2(const krb5_data *code, krb5_enc_sam_response_enc_2 **rep) 894 { 895 setup_buf_only(); 896 alloc_field(*rep,krb5_enc_sam_response_enc_2); 897 898 retval = asn1_decode_enc_sam_response_enc_2(&buf,*rep); 899 if(retval) clean_return(retval); 900 901 cleanup(free); 902 } 903 904 krb5_error_code decode_krb5_sam_response(const krb5_data *code, krb5_sam_response **rep) 905 { 906 setup_buf_only(); 907 alloc_field(*rep,krb5_sam_response); 908 909 retval = asn1_decode_sam_response(&buf,*rep); 910 if(retval) clean_return(retval); 911 912 cleanup(free); 913 } 914 915 krb5_error_code decode_krb5_sam_response_2(const krb5_data *code, krb5_sam_response_2 **rep) 916 { 917 setup_buf_only(); 918 alloc_field(*rep,krb5_sam_response_2); 919 920 retval = asn1_decode_sam_response_2(&buf,*rep); 921 if(retval) clean_return(retval); 922 923 cleanup(free); 924 } 925 926 krb5_error_code decode_krb5_predicted_sam_response(const krb5_data *code, krb5_predicted_sam_response **rep) 927 { 928 setup_buf_only(); /* preallocated */ 929 alloc_field(*rep,krb5_predicted_sam_response); 930 931 retval = asn1_decode_predicted_sam_response(&buf,*rep); 932 if(retval) clean_return(retval); 933 934 cleanup(free); 935 } 936 937 krb5_error_code decode_krb5_pa_pk_as_req(const krb5_data *code, krb5_pa_pk_as_req **rep) 938 { 939 setup_buf_only(); 940 alloc_field(*rep, krb5_pa_pk_as_req); 941 942 retval = asn1_decode_pa_pk_as_req(&buf, *rep); 943 if (retval) clean_return(retval); 944 945 cleanup(free); 946 } 947 948 krb5_error_code decode_krb5_pa_pk_as_req_draft9(const krb5_data *code, krb5_pa_pk_as_req_draft9 **rep) 949 { 950 setup_buf_only(); 951 alloc_field(*rep, krb5_pa_pk_as_req_draft9); 952 953 retval = asn1_decode_pa_pk_as_req_draft9(&buf, *rep); 954 if (retval) clean_return(retval); 955 956 cleanup(free); 957 } 958 959 krb5_error_code decode_krb5_pa_pk_as_rep(const krb5_data *code, krb5_pa_pk_as_rep **rep) 960 { 961 setup_buf_only(); 962 alloc_field(*rep, krb5_pa_pk_as_rep); 963 964 retval = asn1_decode_pa_pk_as_rep(&buf, *rep); 965 if (retval) clean_return(retval); 966 967 cleanup(free); 968 } 969 970 krb5_error_code decode_krb5_pa_pk_as_rep_draft9(const krb5_data *code, krb5_pa_pk_as_rep_draft9 **rep) 971 { 972 setup_buf_only(); 973 alloc_field(*rep, krb5_pa_pk_as_rep_draft9); 974 975 retval = asn1_decode_pa_pk_as_rep_draft9(&buf, *rep); 976 if (retval) clean_return(retval); 977 978 cleanup(free); 979 } 980 981 krb5_error_code decode_krb5_auth_pack(const krb5_data *code, krb5_auth_pack **rep) 982 { 983 setup_buf_only(); 984 alloc_field(*rep, krb5_auth_pack); 985 986 retval = asn1_decode_auth_pack(&buf, *rep); 987 if (retval) clean_return(retval); 988 989 cleanup(free); 990 } 991 992 krb5_error_code decode_krb5_auth_pack_draft9(const krb5_data *code, krb5_auth_pack_draft9 **rep) 993 { 994 setup_buf_only(); 995 alloc_field(*rep, krb5_auth_pack_draft9); 996 997 retval = asn1_decode_auth_pack_draft9(&buf, *rep); 998 if (retval) clean_return(retval); 999 1000 cleanup(free); 1001 } 1002 1003 krb5_error_code decode_krb5_kdc_dh_key_info(const krb5_data *code, krb5_kdc_dh_key_info **rep) 1004 { 1005 setup_buf_only(); 1006 alloc_field(*rep, krb5_kdc_dh_key_info); 1007 1008 retval = asn1_decode_kdc_dh_key_info(&buf, *rep); 1009 if (retval) clean_return(retval); 1010 1011 cleanup(free); 1012 } 1013 1014 krb5_error_code decode_krb5_principal_name(const krb5_data *code, krb5_principal_data **rep) 1015 { 1016 setup_buf_only(); 1017 alloc_field(*rep, krb5_principal_data); 1018 1019 retval = asn1_decode_krb5_principal_name(&buf, rep); 1020 if (retval) clean_return(retval); 1021 1022 cleanup(free); 1023 } 1024 1025 krb5_error_code decode_krb5_reply_key_pack(const krb5_data *code, krb5_reply_key_pack **rep) 1026 { 1027 setup_buf_only(); 1028 alloc_field(*rep, krb5_reply_key_pack); 1029 1030 retval = asn1_decode_reply_key_pack(&buf, *rep); 1031 if (retval) 1032 goto error_out; 1033 1034 cleanup_manual(); 1035 error_out: 1036 if (rep && *rep) { 1037 if ((*rep)->replyKey.contents) 1038 free((*rep)->replyKey.contents); 1039 if ((*rep)->asChecksum.contents) 1040 free((*rep)->asChecksum.contents); 1041 free(*rep); 1042 *rep = NULL; 1043 } 1044 return retval; 1045 } 1046 1047 krb5_error_code decode_krb5_reply_key_pack_draft9(const krb5_data *code, krb5_reply_key_pack_draft9 **rep) 1048 { 1049 setup_buf_only(); 1050 alloc_field(*rep, krb5_reply_key_pack_draft9); 1051 1052 retval = asn1_decode_reply_key_pack_draft9(&buf, *rep); 1053 if (retval) clean_return(retval); 1054 1055 cleanup(free); 1056 } 1057 1058 krb5_error_code decode_krb5_typed_data(const krb5_data *code, krb5_typed_data ***rep) 1059 { 1060 setup_buf_only(); 1061 retval = asn1_decode_sequence_of_typed_data(&buf, rep); 1062 if (retval) clean_return(retval); 1063 1064 cleanup(free); 1065 } 1066 1067 krb5_error_code decode_krb5_td_trusted_certifiers(const krb5_data *code, krb5_external_principal_identifier ***rep) 1068 { 1069 setup_buf_only(); 1070 retval = asn1_decode_sequence_of_external_principal_identifier(&buf, rep); 1071 if (retval) clean_return(retval); 1072 1073 cleanup(free); 1074 } 1075 1076 krb5_error_code decode_krb5_td_dh_parameters(const krb5_data *code, krb5_algorithm_identifier ***rep) 1077 { 1078 setup_buf_only(); 1079 retval = asn1_decode_sequence_of_algorithm_identifier(&buf, rep); 1080 if (retval) clean_return(retval); 1081 1082 cleanup(free); 1083 } 1084