1 /* 2 * src/lib/krb5/asn.1/asn1_k_encode.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 "asn1_k_encode.h" 28 #include "asn1_make.h" 29 #include "asn1_encode.h" 30 #include <assert.h> 31 32 /**** asn1 macros ****/ 33 #if 0 34 How to write an asn1 encoder function using these macros: 35 36 asn1_error_code asn1_encode_krb5_substructure(asn1buf *buf, 37 const krb5_type *val, 38 int *retlen) 39 { 40 asn1_setup(); 41 42 asn1_addfield(val->last_field, n, asn1_type); 43 asn1_addfield(rep->next_to_last_field, n-1, asn1_type); 44 ... 45 46 /* for OPTIONAL fields */ 47 if(rep->field_i == should_not_be_omitted) 48 asn1_addfield(rep->field_i, i, asn1_type); 49 50 /* for string fields (these encoders take an additional argument, 51 the length of the string) */ 52 addlenfield(rep->field_length, rep->field, i-1, asn1_type); 53 54 /* if you really have to do things yourself... */ 55 retval = asn1_encode_asn1_type(buf,rep->field,&length); 56 if(retval) return retval; 57 sum += length; 58 retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, tag_number, length, 59 &length); 60 if(retval) return retval; 61 sum += length; 62 63 ... 64 asn1_addfield(rep->second_field, 1, asn1_type); 65 asn1_addfield(rep->first_field, 0, asn1_type); 66 asn1_makeseq(); 67 68 asn1_cleanup(); 69 } 70 #endif 71 72 /* setup() -- create and initialize bookkeeping variables 73 retval: stores error codes returned from subroutines 74 length: length of the most-recently produced encoding 75 sum: cumulative length of the entire encoding */ 76 #define asn1_setup()\ 77 asn1_error_code retval;\ 78 unsigned int length, sum=0 79 80 /* asn1_addfield -- add a field, or component, to the encoding */ 81 #define asn1_addfield(value,tag,encoder)\ 82 { retval = encoder(buf,value,&length);\ 83 if(retval){\ 84 asn1buf_destroy(&buf);\ 85 return retval; }\ 86 sum += length;\ 87 retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\ 88 if(retval){\ 89 asn1buf_destroy(&buf);\ 90 return retval; }\ 91 sum += length; } 92 93 /* asn1_addlenfield -- add a field whose length must be separately specified */ 94 #define asn1_addlenfield(len,value,tag,encoder)\ 95 { retval = encoder(buf,len,value,&length);\ 96 if(retval){\ 97 asn1buf_destroy(&buf);\ 98 return retval; }\ 99 sum += length;\ 100 retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\ 101 if(retval){\ 102 asn1buf_destroy(&buf);\ 103 return retval; }\ 104 sum += length; } 105 106 /* asn1_addfield_implicit -- add an implicitly tagged field, or component, to the encoding */ 107 #define asn1_addfield_implicit(value,tag,encoder)\ 108 { retval = encoder(buf,value,&length);\ 109 if(retval){\ 110 asn1buf_destroy(&buf);\ 111 return retval; }\ 112 sum += length;\ 113 retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,length,&length); \ 114 if(retval){\ 115 asn1buf_destroy(&buf);\ 116 return retval; }\ 117 sum += length; } 118 119 /* asn1_insert_implicit_octetstring -- add an octet string with implicit tagging */ 120 #define asn1_insert_implicit_octetstring(len,value,tag)\ 121 { retval = asn1buf_insert_octetstring(buf,len,value);\ 122 if(retval){\ 123 asn1buf_destroy(&buf);\ 124 return retval; }\ 125 sum += len;\ 126 retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,len,&length); \ 127 if(retval){\ 128 asn1buf_destroy(&buf);\ 129 return retval; }\ 130 sum += length; } 131 132 /* asn1_insert_implicit_bitstring -- add a bitstring with implicit tagging */ 133 #define asn1_insert_implicit_bitstring(len,value,tag)\ 134 { retval = asn1buf_insert_octetstring(buf,len,value);\ 135 if(retval){\ 136 asn1buf_destroy(&buf);\ 137 return retval; }\ 138 sum += len;\ 139 retval = asn1buf_insert_octet(buf, 0);\ 140 if(retval){\ 141 asn1buf_destroy(&buf);\ 142 return retval; }\ 143 sum++;\ 144 retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,tag,len+1,&length); \ 145 if(retval){\ 146 asn1buf_destroy(&buf);\ 147 return retval; }\ 148 sum += length; } 149 150 /* form a sequence (by adding a sequence header to the current encoding) */ 151 #define asn1_makeseq()\ 152 retval = asn1_make_sequence(buf,sum,&length);\ 153 if(retval){\ 154 asn1buf_destroy(&buf);\ 155 return retval; }\ 156 sum += length 157 158 /* add an APPLICATION class tag to the current encoding */ 159 #define asn1_apptag(num)\ 160 retval = asn1_make_etag(buf,APPLICATION,num,sum,&length);\ 161 if(retval){\ 162 asn1buf_destroy(&buf);\ 163 return retval; }\ 164 sum += length 165 166 /* produce the final output and clean up the workspace */ 167 #define asn1_cleanup()\ 168 *retlen = sum;\ 169 return 0 170 171 asn1_error_code asn1_encode_ui_4(asn1buf *buf, const krb5_ui_4 val, unsigned int *retlen) 172 { 173 return asn1_encode_unsigned_integer(buf,val,retlen); 174 } 175 176 177 asn1_error_code asn1_encode_realm(asn1buf *buf, const krb5_principal val, unsigned int *retlen) 178 { 179 if (val == NULL || 180 (val->realm.length && val->realm.data == NULL)) 181 return ASN1_MISSING_FIELD; 182 return asn1_encode_generalstring(buf,val->realm.length,val->realm.data, 183 retlen); 184 } 185 186 asn1_error_code asn1_encode_principal_name(asn1buf *buf, const krb5_principal val, unsigned int *retlen) 187 { 188 asn1_setup(); 189 int n; 190 191 if (val == NULL || val->data == NULL) return ASN1_MISSING_FIELD; 192 193 for(n = (int) ((val->length)-1); n >= 0; n--){ 194 if (val->data[n].length && 195 val->data[n].data == NULL) 196 return ASN1_MISSING_FIELD; 197 retval = asn1_encode_generalstring(buf, 198 (val->data)[n].length, 199 (val->data)[n].data, 200 &length); 201 if(retval) return retval; 202 sum += length; 203 } 204 asn1_makeseq(); 205 retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,1,sum,&length); 206 if(retval) return retval; 207 sum += length; 208 209 asn1_addfield(val->type,0,asn1_encode_integer); 210 211 asn1_makeseq(); 212 213 asn1_cleanup(); 214 } 215 216 asn1_error_code asn1_encode_kerberos_time(asn1buf *buf, const krb5_timestamp val, unsigned int *retlen) 217 { 218 return asn1_encode_generaltime(buf,val,retlen); 219 } 220 221 asn1_error_code asn1_encode_host_address(asn1buf *buf, const krb5_address *val, unsigned int *retlen) 222 { 223 asn1_setup(); 224 225 if (val == NULL || val->contents == NULL) return ASN1_MISSING_FIELD; 226 227 asn1_addlenfield(val->length,val->contents,1,asn1_encode_octetstring); 228 asn1_addfield(val->addrtype,0,asn1_encode_integer); 229 asn1_makeseq(); 230 231 asn1_cleanup(); 232 } 233 234 asn1_error_code asn1_encode_host_addresses(asn1buf *buf, const krb5_address **val, unsigned int *retlen) 235 { 236 asn1_setup(); 237 int i; 238 239 if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 240 241 for(i=0; val[i] != NULL; i++); /* go to end of array */ 242 for(i--; i>=0; i--){ 243 retval = asn1_encode_host_address(buf,val[i],&length); 244 if(retval) return retval; 245 sum += length; 246 } 247 asn1_makeseq(); 248 249 asn1_cleanup(); 250 } 251 252 asn1_error_code asn1_encode_encrypted_data(asn1buf *buf, const krb5_enc_data *val, unsigned int *retlen) 253 { 254 asn1_setup(); 255 256 if(val == NULL || 257 (val->ciphertext.length && val->ciphertext.data == NULL)) 258 return ASN1_MISSING_FIELD; 259 260 asn1_addlenfield(val->ciphertext.length,val->ciphertext.data,2,asn1_encode_charstring); 261 /* krb5_kvno should be int */ 262 if(val->kvno) 263 asn1_addfield((int) val->kvno,1,asn1_encode_integer); 264 asn1_addfield(val->enctype,0,asn1_encode_integer); 265 266 asn1_makeseq(); 267 268 asn1_cleanup(); 269 } 270 271 asn1_error_code asn1_encode_krb5_flags(asn1buf *buf, const krb5_flags val, unsigned int *retlen) 272 { 273 asn1_setup(); 274 krb5_flags valcopy = val; 275 int i; 276 277 for(i=0; i<4; i++){ 278 retval = asn1buf_insert_octet(buf,(asn1_octet) (valcopy&0xFF)); 279 if(retval) return retval; 280 valcopy >>= 8; 281 } 282 retval = asn1buf_insert_octet(buf,0); /* 0 padding bits */ 283 if(retval) return retval; 284 sum = 5; 285 286 retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_BITSTRING,sum, 287 &length); 288 if(retval) return retval; 289 sum += length; 290 291 *retlen = sum; 292 return 0; 293 } 294 295 asn1_error_code asn1_encode_ap_options(asn1buf *buf, const krb5_flags val, unsigned int *retlen) 296 { 297 return asn1_encode_krb5_flags(buf,val,retlen); 298 } 299 300 asn1_error_code asn1_encode_ticket_flags(asn1buf *buf, const krb5_flags val, unsigned int *retlen) 301 { 302 return asn1_encode_krb5_flags(buf,val,retlen); 303 } 304 305 asn1_error_code asn1_encode_kdc_options(asn1buf *buf, const krb5_flags val, unsigned int *retlen) 306 { 307 return asn1_encode_krb5_flags(buf,val,retlen); 308 } 309 310 asn1_error_code asn1_encode_authorization_data(asn1buf *buf, const krb5_authdata **val, unsigned int *retlen) 311 { 312 asn1_setup(); 313 int i; 314 315 if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 316 317 for(i=0; val[i] != NULL; i++); /* get to the end of the array */ 318 for(i--; i>=0; i--){ 319 retval = asn1_encode_krb5_authdata_elt(buf,val[i],&length); 320 if(retval) return retval; 321 sum += length; 322 } 323 asn1_makeseq(); 324 325 asn1_cleanup(); 326 } 327 328 asn1_error_code asn1_encode_krb5_authdata_elt(asn1buf *buf, const krb5_authdata *val, unsigned int *retlen) 329 { 330 asn1_setup(); 331 332 if (val == NULL || 333 (val->length && val->contents == NULL)) 334 return ASN1_MISSING_FIELD; 335 336 /* ad-data[1] OCTET STRING */ 337 asn1_addlenfield(val->length,val->contents,1,asn1_encode_octetstring); 338 /* ad-type[0] INTEGER */ 339 asn1_addfield(val->ad_type,0,asn1_encode_integer); 340 /* SEQUENCE */ 341 asn1_makeseq(); 342 343 asn1_cleanup(); 344 } 345 346 asn1_error_code asn1_encode_kdc_rep(int msg_type, asn1buf *buf, const krb5_kdc_rep *val, unsigned int *retlen) 347 { 348 asn1_setup(); 349 350 if(val == NULL) return ASN1_MISSING_FIELD; 351 352 asn1_addfield(&(val->enc_part),6,asn1_encode_encrypted_data); 353 asn1_addfield(val->ticket,5,asn1_encode_ticket); 354 asn1_addfield(val->client,4,asn1_encode_principal_name); 355 asn1_addfield(val->client,3,asn1_encode_realm); 356 if(val->padata != NULL && val->padata[0] != NULL) 357 asn1_addfield((const krb5_pa_data**)val->padata,2,asn1_encode_sequence_of_pa_data); 358 if (msg_type != KRB5_AS_REP && msg_type != KRB5_TGS_REP) 359 return KRB5_BADMSGTYPE; 360 asn1_addfield(msg_type,1,asn1_encode_integer); 361 asn1_addfield(KVNO,0,asn1_encode_integer); 362 asn1_makeseq(); 363 364 asn1_cleanup(); 365 } 366 367 asn1_error_code asn1_encode_enc_kdc_rep_part(asn1buf *buf, const krb5_enc_kdc_rep_part *val, unsigned int *retlen) 368 { 369 asn1_setup(); 370 371 if(val == NULL) return ASN1_MISSING_FIELD; 372 373 /* caddr[11] HostAddresses OPTIONAL */ 374 if(val->caddrs != NULL && val->caddrs[0] != NULL) 375 asn1_addfield((const krb5_address**)(val->caddrs),11,asn1_encode_host_addresses); 376 377 /* sname[10] PrincipalName */ 378 asn1_addfield(val->server,10,asn1_encode_principal_name); 379 380 /* srealm[9] Realm */ 381 asn1_addfield(val->server,9,asn1_encode_realm); 382 383 /* renew-till[8] KerberosTime OPTIONAL */ 384 if(val->flags & TKT_FLG_RENEWABLE) 385 asn1_addfield(val->times.renew_till,8,asn1_encode_kerberos_time); 386 387 /* endtime[7] KerberosTime */ 388 asn1_addfield(val->times.endtime,7,asn1_encode_kerberos_time); 389 390 /* starttime[6] KerberosTime OPTIONAL */ 391 if(val->times.starttime) 392 asn1_addfield(val->times.starttime,6,asn1_encode_kerberos_time); 393 394 /* authtime[5] KerberosTime */ 395 asn1_addfield(val->times.authtime,5,asn1_encode_kerberos_time); 396 397 /* flags[4] TicketFlags */ 398 asn1_addfield(val->flags,4,asn1_encode_ticket_flags); 399 400 /* key-expiration[3] KerberosTime OPTIONAL */ 401 if(val->key_exp) 402 asn1_addfield(val->key_exp,3,asn1_encode_kerberos_time); 403 404 /* nonce[2] INTEGER */ 405 asn1_addfield(val->nonce,2,asn1_encode_integer); 406 407 /* last-req[1] LastReq */ 408 asn1_addfield((const krb5_last_req_entry**)val->last_req,1,asn1_encode_last_req); 409 410 /* key[0] EncryptionKey */ 411 asn1_addfield(val->session,0,asn1_encode_encryption_key); 412 413 /* EncKDCRepPart ::= SEQUENCE */ 414 asn1_makeseq(); 415 416 asn1_cleanup(); 417 } 418 419 asn1_error_code asn1_encode_sequence_of_checksum(asn1buf *buf, const krb5_checksum ** val, unsigned int *retlen) 420 { 421 asn1_setup(); 422 int i; 423 424 if(val == NULL) return ASN1_MISSING_FIELD; 425 426 for (i=0; val[i] != NULL; i++); 427 for (i--; i>=0; i--){ 428 retval = asn1_encode_checksum(buf,val[i],&length); 429 if(retval) return retval; 430 sum += length; 431 } 432 asn1_makeseq(); 433 434 asn1_cleanup(); 435 } 436 437 asn1_error_code asn1_encode_kdc_req_body(asn1buf *buf, const krb5_kdc_req *rep, unsigned int *retlen) 438 { 439 asn1_setup(); 440 441 if(rep == NULL) return ASN1_MISSING_FIELD; 442 443 /* additional-tickets[11] SEQUENCE OF Ticket OPTIONAL */ 444 if(rep->second_ticket != NULL && rep->second_ticket[0] != NULL) 445 asn1_addfield((const krb5_ticket**)rep->second_ticket, 446 11,asn1_encode_sequence_of_ticket); 447 448 /* enc-authorization-data[10] EncryptedData OPTIONAL, */ 449 /* -- Encrypted AuthorizationData encoding */ 450 if(rep->authorization_data.ciphertext.data != NULL) 451 asn1_addfield(&(rep->authorization_data),10,asn1_encode_encrypted_data); 452 453 /* addresses[9] HostAddresses OPTIONAL, */ 454 if(rep->addresses != NULL && rep->addresses[0] != NULL) 455 asn1_addfield((const krb5_address**)rep->addresses,9,asn1_encode_host_addresses); 456 457 /* etype[8] SEQUENCE OF INTEGER, -- EncryptionType, */ 458 /* -- in preference order */ 459 asn1_addlenfield(rep->nktypes,rep->ktype,8,asn1_encode_sequence_of_enctype); 460 461 /* nonce[7] INTEGER, */ 462 asn1_addfield(rep->nonce,7,asn1_encode_integer); 463 464 /* rtime[6] KerberosTime OPTIONAL, */ 465 if(rep->rtime) 466 asn1_addfield(rep->rtime,6,asn1_encode_kerberos_time); 467 468 /* till[5] KerberosTime, */ 469 asn1_addfield(rep->till,5,asn1_encode_kerberos_time); 470 471 /* from[4] KerberosTime OPTIONAL, */ 472 if(rep->from) 473 asn1_addfield(rep->from,4,asn1_encode_kerberos_time); 474 475 /* sname[3] PrincipalName OPTIONAL, */ 476 if(rep->server != NULL) 477 asn1_addfield(rep->server,3,asn1_encode_principal_name); 478 479 /* realm[2] Realm, -- Server's realm */ 480 /* -- Also client's in AS-REQ */ 481 if(rep->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY){ 482 if(rep->second_ticket != NULL && rep->second_ticket[0] != NULL){ 483 asn1_addfield(rep->second_ticket[0]->server,2,asn1_encode_realm) 484 } else return ASN1_MISSING_FIELD; 485 }else if(rep->server != NULL){ 486 asn1_addfield(rep->server,2,asn1_encode_realm); 487 }else return ASN1_MISSING_FIELD; 488 489 /* cname[1] PrincipalName OPTIONAL, */ 490 /* -- Used only in AS-REQ */ 491 if(rep->client != NULL) 492 asn1_addfield(rep->client,1,asn1_encode_principal_name); 493 494 /* kdc-options[0] KDCOptions, */ 495 asn1_addfield(rep->kdc_options,0,asn1_encode_kdc_options); 496 497 /* KDC-REQ-BODY ::= SEQUENCE */ 498 asn1_makeseq(); 499 500 asn1_cleanup(); 501 } 502 503 asn1_error_code asn1_encode_encryption_key(asn1buf *buf, const krb5_keyblock *val, unsigned int *retlen) 504 { 505 asn1_setup(); 506 507 if (val == NULL || 508 (val->length && val->contents == NULL)) 509 return ASN1_MISSING_FIELD; 510 511 asn1_addlenfield(val->length,val->contents,1,asn1_encode_octetstring); 512 asn1_addfield(val->enctype,0,asn1_encode_integer); 513 asn1_makeseq(); 514 515 asn1_cleanup(); 516 } 517 518 asn1_error_code asn1_encode_checksum(asn1buf *buf, const krb5_checksum *val, unsigned int *retlen) 519 { 520 asn1_setup(); 521 522 if (val == NULL || 523 (val->length && val->contents == NULL)) 524 return ASN1_MISSING_FIELD; 525 526 asn1_addlenfield(val->length,val->contents,1,asn1_encode_octetstring); 527 asn1_addfield(val->checksum_type,0,asn1_encode_integer); 528 asn1_makeseq(); 529 530 asn1_cleanup(); 531 } 532 533 asn1_error_code asn1_encode_transited_encoding(asn1buf *buf, const krb5_transited *val, unsigned int *retlen) 534 { 535 asn1_setup(); 536 537 if(val == NULL || 538 (val->tr_contents.length != 0 && val->tr_contents.data == NULL)) 539 return ASN1_MISSING_FIELD; 540 541 asn1_addlenfield(val->tr_contents.length,val->tr_contents.data, 542 1,asn1_encode_charstring); 543 asn1_addfield(val->tr_type,0,asn1_encode_integer); 544 asn1_makeseq(); 545 546 asn1_cleanup(); 547 } 548 549 asn1_error_code asn1_encode_last_req(asn1buf *buf, const krb5_last_req_entry **val, unsigned int *retlen) 550 { 551 asn1_setup(); 552 int i; 553 554 if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 555 556 for(i=0; val[i] != NULL; i++); /* go to end of array */ 557 for(i--; i>=0; i--){ 558 retval = asn1_encode_last_req_entry(buf,val[i],&length); 559 if(retval) return retval; 560 sum += length; 561 } 562 asn1_makeseq(); 563 564 asn1_cleanup(); 565 } 566 567 asn1_error_code asn1_encode_last_req_entry(asn1buf *buf, const krb5_last_req_entry *val, unsigned int *retlen) 568 { 569 asn1_setup(); 570 571 if(val == NULL) return ASN1_MISSING_FIELD; 572 573 asn1_addfield(val->value,1,asn1_encode_kerberos_time); 574 asn1_addfield(val->lr_type,0,asn1_encode_integer); 575 asn1_makeseq(); 576 577 asn1_cleanup(); 578 } 579 580 asn1_error_code asn1_encode_sequence_of_pa_data(asn1buf *buf, const krb5_pa_data **val, unsigned int *retlen) 581 { 582 asn1_setup(); 583 int i; 584 585 if (val == NULL) return ASN1_MISSING_FIELD; 586 587 for(i=0; val[i] != NULL; i++); 588 for(i--; i>=0; i--){ 589 retval = asn1_encode_pa_data(buf,val[i],&length); 590 if(retval) return retval; 591 sum += length; 592 } 593 asn1_makeseq(); 594 595 asn1_cleanup(); 596 } 597 598 asn1_error_code asn1_encode_pa_data(asn1buf *buf, const krb5_pa_data *val, unsigned int *retlen) 599 { 600 asn1_setup(); 601 602 if(val == NULL || (val->length != 0 && val->contents == NULL)) 603 return ASN1_MISSING_FIELD; 604 605 asn1_addlenfield(val->length,val->contents,2,asn1_encode_octetstring); 606 asn1_addfield(val->pa_type,1,asn1_encode_integer); 607 asn1_makeseq(); 608 609 asn1_cleanup(); 610 } 611 612 asn1_error_code asn1_encode_sequence_of_ticket(asn1buf *buf, const krb5_ticket **val, unsigned int *retlen) 613 { 614 asn1_setup(); 615 int i; 616 617 if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 618 619 for(i=0; val[i] != NULL; i++); 620 for(i--; i>=0; i--){ 621 retval = asn1_encode_ticket(buf,val[i],&length); 622 if(retval) return retval; 623 sum += length; 624 } 625 asn1_makeseq(); 626 627 asn1_cleanup(); 628 } 629 630 asn1_error_code asn1_encode_ticket(asn1buf *buf, const krb5_ticket *val, unsigned int *retlen) 631 { 632 asn1_setup(); 633 634 if(val == NULL) return ASN1_MISSING_FIELD; 635 636 asn1_addfield(&(val->enc_part),3,asn1_encode_encrypted_data); 637 asn1_addfield(val->server,2,asn1_encode_principal_name); 638 asn1_addfield(val->server,1,asn1_encode_realm); 639 asn1_addfield(KVNO,0,asn1_encode_integer); 640 asn1_makeseq(); 641 asn1_apptag(1); 642 643 asn1_cleanup(); 644 } 645 646 asn1_error_code asn1_encode_sequence_of_enctype(asn1buf *buf, const int len, const krb5_enctype *val, unsigned int *retlen) 647 { 648 asn1_setup(); 649 int i; 650 651 if(val == NULL) return ASN1_MISSING_FIELD; 652 653 for(i=len-1; i>=0; i--){ 654 retval = asn1_encode_integer(buf,val[i],&length); 655 if(retval) return retval; 656 sum += length; 657 } 658 asn1_makeseq(); 659 660 asn1_cleanup(); 661 } 662 663 asn1_error_code asn1_encode_kdc_req(int msg_type, asn1buf *buf, const krb5_kdc_req *val, unsigned int *retlen) 664 { 665 asn1_setup(); 666 667 if(val == NULL) return ASN1_MISSING_FIELD; 668 669 asn1_addfield(val,4,asn1_encode_kdc_req_body); 670 if(val->padata != NULL && val->padata[0] != NULL) 671 asn1_addfield((const krb5_pa_data**)val->padata,3,asn1_encode_sequence_of_pa_data); 672 if (msg_type != KRB5_AS_REQ && msg_type != KRB5_TGS_REQ) 673 return KRB5_BADMSGTYPE; 674 asn1_addfield(msg_type,2,asn1_encode_integer); 675 asn1_addfield(KVNO,1,asn1_encode_integer); 676 asn1_makeseq(); 677 678 asn1_cleanup(); 679 } 680 681 asn1_error_code asn1_encode_krb_safe_body(asn1buf *buf, const krb5_safe *val, unsigned int *retlen) 682 { 683 asn1_setup(); 684 685 if(val == NULL) return ASN1_MISSING_FIELD; 686 687 if(val->r_address != NULL) 688 asn1_addfield(val->r_address,5,asn1_encode_host_address); 689 asn1_addfield(val->s_address,4,asn1_encode_host_address); 690 if(val->seq_number) 691 asn1_addfield(val->seq_number,3,asn1_encode_unsigned_integer); 692 if(val->timestamp){ 693 asn1_addfield(val->usec,2,asn1_encode_integer); 694 asn1_addfield(val->timestamp,1,asn1_encode_kerberos_time); 695 } 696 if (val->user_data.length && val->user_data.data == NULL) 697 return ASN1_MISSING_FIELD; 698 asn1_addlenfield(val->user_data.length,val->user_data.data,0,asn1_encode_charstring) 699 ; 700 701 asn1_makeseq(); 702 asn1_cleanup(); 703 } 704 705 asn1_error_code asn1_encode_sequence_of_krb_cred_info(asn1buf *buf, const krb5_cred_info **val, unsigned int *retlen) 706 { 707 asn1_setup(); 708 int i; 709 710 if(val == NULL) return ASN1_MISSING_FIELD; 711 712 for(i=0; val[i] != NULL; i++); 713 for(i--; i>=0; i--){ 714 retval = asn1_encode_krb_cred_info(buf,val[i],&length); 715 if(retval) return retval; 716 sum += length; 717 } 718 asn1_makeseq(); 719 720 asn1_cleanup(); 721 } 722 723 asn1_error_code asn1_encode_krb_cred_info(asn1buf *buf, const krb5_cred_info *val, unsigned int *retlen) 724 { 725 asn1_setup(); 726 727 if(val == NULL) return ASN1_MISSING_FIELD; 728 729 if(val->caddrs != NULL && val->caddrs[0] != NULL) 730 asn1_addfield((const krb5_address**)val->caddrs,10,asn1_encode_host_addresses); 731 if(val->server != NULL){ 732 asn1_addfield(val->server,9,asn1_encode_principal_name); 733 asn1_addfield(val->server,8,asn1_encode_realm); 734 } 735 if(val->times.renew_till) 736 asn1_addfield(val->times.renew_till,7,asn1_encode_kerberos_time); 737 if(val->times.endtime) 738 asn1_addfield(val->times.endtime,6,asn1_encode_kerberos_time); 739 if(val->times.starttime) 740 asn1_addfield(val->times.starttime,5,asn1_encode_kerberos_time); 741 if(val->times.authtime) 742 asn1_addfield(val->times.authtime,4,asn1_encode_kerberos_time); 743 if(val->flags) 744 asn1_addfield(val->flags,3,asn1_encode_ticket_flags); 745 if(val->client != NULL){ 746 asn1_addfield(val->client,2,asn1_encode_principal_name); 747 asn1_addfield(val->client,1,asn1_encode_realm); 748 } 749 asn1_addfield(val->session,0,asn1_encode_encryption_key); 750 751 asn1_makeseq(); 752 753 asn1_cleanup(); 754 } 755 756 asn1_error_code asn1_encode_etype_info_entry(asn1buf *buf, const krb5_etype_info_entry *val, 757 unsigned int *retlen, int etype_info2) 758 { 759 asn1_setup(); 760 761 assert(val->s2kparams.data == NULL || etype_info2); 762 if(val == NULL || (val->length > 0 && val->length != KRB5_ETYPE_NO_SALT && 763 val->salt == NULL)) 764 return ASN1_MISSING_FIELD; 765 if(val->s2kparams.data != NULL) { 766 /* Solaris Kerberos */ 767 asn1_addlenfield(val->s2kparams.length, (const uchar_t *)val->s2kparams.data, 2, 768 asn1_encode_octetstring); 769 } 770 if (val->length >= 0 && val->length != KRB5_ETYPE_NO_SALT){ 771 if (etype_info2) { 772 /* Solaris Kerberos */ 773 asn1_addlenfield(val->length, (const char *)val->salt,1, 774 asn1_encode_generalstring) 775 } 776 else asn1_addlenfield(val->length,val->salt,1, 777 asn1_encode_octetstring); 778 } 779 asn1_addfield(val->etype,0,asn1_encode_integer); 780 asn1_makeseq(); 781 782 asn1_cleanup(); 783 } 784 785 asn1_error_code asn1_encode_etype_info(asn1buf *buf, const krb5_etype_info_entry **val, 786 unsigned int *retlen, int etype_info2) 787 { 788 asn1_setup(); 789 int i; 790 791 if (val == NULL) return ASN1_MISSING_FIELD; 792 793 for(i=0; val[i] != NULL; i++); /* get to the end of the array */ 794 for(i--; i>=0; i--){ 795 retval = asn1_encode_etype_info_entry(buf,val[i],&length, etype_info2); 796 if(retval) return retval; 797 sum += length; 798 } 799 asn1_makeseq(); 800 asn1_cleanup(); 801 } 802 803 asn1_error_code asn1_encode_sequence_of_passwdsequence(asn1buf *buf, const passwd_phrase_element **val, unsigned int *retlen) 804 { 805 asn1_setup(); 806 int i; 807 808 if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 809 810 for(i=0; val[i] != NULL; i++); /* get to the end of the array */ 811 for(i--; i>=0; i--){ 812 retval = asn1_encode_passwdsequence(buf,val[i],&length); 813 if(retval) return retval; 814 sum += length; 815 } 816 asn1_makeseq(); 817 asn1_cleanup(); 818 } 819 820 asn1_error_code asn1_encode_passwdsequence(asn1buf *buf, const passwd_phrase_element *val, unsigned int *retlen) 821 { 822 asn1_setup(); 823 asn1_addlenfield(val->phrase->length,val->phrase->data,1,asn1_encode_charstring); 824 asn1_addlenfield(val->passwd->length,val->passwd->data,0,asn1_encode_charstring); 825 asn1_makeseq(); 826 asn1_cleanup(); 827 } 828 829 asn1_error_code asn1_encode_sam_flags(asn1buf *buf, const krb5_flags val, unsigned int *retlen) 830 { 831 return asn1_encode_krb5_flags(buf,val,retlen); 832 } 833 834 #define add_optstring(val,n,fn) \ 835 if ((val).length > 0) {asn1_addlenfield((val).length,(val).data,n,fn);} 836 837 asn1_error_code asn1_encode_sam_challenge(asn1buf *buf, const krb5_sam_challenge *val, unsigned int *retlen) 838 { 839 asn1_setup(); 840 /* possibly wrong */ 841 if (val->sam_cksum.length) 842 asn1_addfield(&(val->sam_cksum),9,asn1_encode_checksum); 843 844 if (val->sam_nonce) 845 asn1_addfield(val->sam_nonce,8,asn1_encode_integer); 846 847 add_optstring(val->sam_pk_for_sad,7,asn1_encode_charstring); 848 add_optstring(val->sam_response_prompt,6,asn1_encode_charstring); 849 add_optstring(val->sam_challenge,5,asn1_encode_charstring); 850 add_optstring(val->sam_challenge_label,4,asn1_encode_charstring); 851 add_optstring(val->sam_track_id,3,asn1_encode_charstring); 852 add_optstring(val->sam_type_name,2,asn1_encode_charstring); 853 854 asn1_addfield(val->sam_flags,1,asn1_encode_sam_flags); 855 asn1_addfield(val->sam_type,0,asn1_encode_integer); 856 857 asn1_makeseq(); 858 asn1_cleanup(); 859 } 860 861 asn1_error_code asn1_encode_sam_challenge_2(asn1buf *buf, const krb5_sam_challenge_2 *val, unsigned int *retlen) 862 { 863 asn1_setup(); 864 if ( (!val) || (!val->sam_cksum) || (!val->sam_cksum[0])) 865 return ASN1_MISSING_FIELD; 866 867 asn1_addfield((const krb5_checksum **) val->sam_cksum, 1, asn1_encode_sequence_of_checksum); 868 retval = asn1buf_insert_octetstring(buf, val->sam_challenge_2_body.length, 869 (unsigned char *)val->sam_challenge_2_body.data); 870 if(retval){ 871 asn1buf_destroy(&buf); 872 return retval; 873 } 874 sum += val->sam_challenge_2_body.length; 875 retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, 0, 876 val->sam_challenge_2_body.length, &length); 877 if(retval) { 878 asn1buf_destroy(&buf); 879 return retval; 880 } 881 sum += length; 882 883 asn1_makeseq(); 884 asn1_cleanup(); 885 } 886 887 asn1_error_code asn1_encode_sam_challenge_2_body(asn1buf *buf, const krb5_sam_challenge_2_body *val, unsigned int *retlen) 888 { 889 asn1_setup(); 890 891 asn1_addfield(val->sam_etype, 9, asn1_encode_integer); 892 asn1_addfield(val->sam_nonce,8,asn1_encode_integer); 893 add_optstring(val->sam_pk_for_sad,7,asn1_encode_charstring); 894 add_optstring(val->sam_response_prompt,6,asn1_encode_charstring); 895 add_optstring(val->sam_challenge,5,asn1_encode_charstring); 896 add_optstring(val->sam_challenge_label,4,asn1_encode_charstring); 897 add_optstring(val->sam_track_id,3,asn1_encode_charstring); 898 add_optstring(val->sam_type_name,2,asn1_encode_charstring); 899 900 asn1_addfield(val->sam_flags,1,asn1_encode_sam_flags); 901 asn1_addfield(val->sam_type,0,asn1_encode_integer); 902 903 asn1_makeseq(); 904 asn1_cleanup(); 905 } 906 907 asn1_error_code asn1_encode_sam_key(asn1buf *buf, const krb5_sam_key *val, unsigned int *retlen) 908 { 909 asn1_setup(); 910 asn1_addfield(&(val->sam_key),0,asn1_encode_encryption_key); 911 912 asn1_makeseq(); 913 914 asn1_cleanup(); 915 } 916 917 918 asn1_error_code asn1_encode_enc_sam_response_enc(asn1buf *buf, const krb5_enc_sam_response_enc *val, unsigned int *retlen) 919 { 920 asn1_setup(); 921 add_optstring(val->sam_sad,3,asn1_encode_charstring); 922 asn1_addfield(val->sam_usec,2,asn1_encode_integer); 923 asn1_addfield(val->sam_timestamp,1,asn1_encode_kerberos_time); 924 asn1_addfield(val->sam_nonce,0,asn1_encode_integer); 925 926 asn1_makeseq(); 927 928 asn1_cleanup(); 929 } 930 931 asn1_error_code asn1_encode_enc_sam_response_enc_2(asn1buf *buf, const krb5_enc_sam_response_enc_2 *val, unsigned int *retlen) 932 { 933 asn1_setup(); 934 add_optstring(val->sam_sad,1,asn1_encode_charstring); 935 asn1_addfield(val->sam_nonce,0,asn1_encode_integer); 936 937 asn1_makeseq(); 938 939 asn1_cleanup(); 940 } 941 942 asn1_error_code asn1_encode_sam_response(asn1buf *buf, const krb5_sam_response *val, unsigned int *retlen) 943 { 944 asn1_setup(); 945 946 if (val->sam_patimestamp) 947 asn1_addfield(val->sam_patimestamp,6,asn1_encode_kerberos_time); 948 if (val->sam_nonce) 949 asn1_addfield(val->sam_nonce,5,asn1_encode_integer); 950 asn1_addfield(&(val->sam_enc_nonce_or_ts),4,asn1_encode_encrypted_data); 951 if (val->sam_enc_key.ciphertext.length) 952 asn1_addfield(&(val->sam_enc_key),3,asn1_encode_encrypted_data); 953 add_optstring(val->sam_track_id,2,asn1_encode_charstring); 954 asn1_addfield(val->sam_flags,1,asn1_encode_sam_flags); 955 asn1_addfield(val->sam_type,0,asn1_encode_integer); 956 957 asn1_makeseq(); 958 959 asn1_cleanup(); 960 } 961 962 asn1_error_code asn1_encode_sam_response_2(asn1buf *buf, const krb5_sam_response_2 *val, unsigned int *retlen) 963 { 964 asn1_setup(); 965 966 asn1_addfield(val->sam_nonce,4,asn1_encode_integer); 967 asn1_addfield(&(val->sam_enc_nonce_or_sad),3,asn1_encode_encrypted_data); 968 add_optstring(val->sam_track_id,2,asn1_encode_charstring); 969 asn1_addfield(val->sam_flags,1,asn1_encode_sam_flags); 970 asn1_addfield(val->sam_type,0,asn1_encode_integer); 971 972 asn1_makeseq(); 973 974 asn1_cleanup(); 975 } 976 977 asn1_error_code asn1_encode_predicted_sam_response(asn1buf *buf, const krb5_predicted_sam_response *val, unsigned int *retlen) 978 { 979 asn1_setup(); 980 981 add_optstring(val->msd,6,asn1_encode_charstring); 982 asn1_addfield(val->client,5,asn1_encode_principal_name); 983 asn1_addfield(val->client,4,asn1_encode_realm); 984 asn1_addfield(val->susec,3,asn1_encode_integer); 985 asn1_addfield(val->stime,2,asn1_encode_kerberos_time); 986 asn1_addfield(val->sam_flags,1,asn1_encode_sam_flags); 987 asn1_addfield(&(val->sam_key),0,asn1_encode_encryption_key); 988 989 asn1_makeseq(); 990 991 asn1_cleanup(); 992 } 993 994 /* 995 * Do some ugliness to insert a raw pre-encoded KRB-SAFE-BODY. 996 */ 997 asn1_error_code asn1_encode_krb_saved_safe_body(asn1buf *buf, const krb5_data *body, unsigned int *retlen) 998 { 999 asn1_error_code retval; 1000 1001 retval = asn1buf_insert_octetstring(buf, body->length, 1002 (krb5_octet *)body->data); 1003 if (retval){ 1004 asn1buf_destroy(&buf); 1005 return retval; 1006 } 1007 *retlen = body->length; 1008 return 0; 1009 } 1010 1011 /* 1012 * PKINIT 1013 */ 1014 1015 asn1_error_code asn1_encode_pk_authenticator(asn1buf *buf, const krb5_pk_authenticator *val, unsigned int *retlen) 1016 { 1017 asn1_setup(); 1018 asn1_addlenfield(val->paChecksum.length, val->paChecksum.contents, 3, asn1_encode_octetstring); 1019 asn1_addfield(val->nonce, 2, asn1_encode_integer); 1020 asn1_addfield(val->ctime, 1, asn1_encode_kerberos_time); 1021 asn1_addfield(val->cusec, 0, asn1_encode_integer); 1022 1023 asn1_makeseq(); 1024 asn1_cleanup(); 1025 } 1026 1027 asn1_error_code asn1_encode_pk_authenticator_draft9(asn1buf *buf, const krb5_pk_authenticator_draft9 *val, unsigned int *retlen) 1028 { 1029 asn1_setup(); 1030 1031 asn1_addfield(val->nonce, 4, asn1_encode_integer); 1032 asn1_addfield(val->ctime, 3, asn1_encode_kerberos_time); 1033 asn1_addfield(val->cusec, 2, asn1_encode_integer); 1034 asn1_addfield(val->kdcName, 1, asn1_encode_realm); 1035 asn1_addfield(val->kdcName, 0, asn1_encode_principal_name); 1036 1037 asn1_makeseq(); 1038 asn1_cleanup(); 1039 } 1040 1041 1042 asn1_error_code asn1_encode_algorithm_identifier(asn1buf *buf, const krb5_algorithm_identifier *val, unsigned int *retlen) 1043 { 1044 asn1_setup(); 1045 1046 if (val->parameters.length != 0) { 1047 retval = asn1buf_insert_octetstring(buf, val->parameters.length, 1048 val->parameters.data); 1049 if(retval) { 1050 asn1buf_destroy(&buf); 1051 return retval; 1052 } 1053 sum += val->parameters.length; 1054 } 1055 1056 retval = asn1_encode_oid(buf, val->algorithm.length, 1057 val->algorithm.data, 1058 &length); 1059 1060 if(retval) { 1061 asn1buf_destroy(&buf); 1062 return retval; 1063 } 1064 sum += length; 1065 1066 asn1_makeseq(); 1067 asn1_cleanup(); 1068 } 1069 1070 asn1_error_code asn1_encode_subject_pk_info(asn1buf *buf, const krb5_subject_pk_info *val, unsigned int *retlen) 1071 { 1072 asn1_setup(); 1073 1074 asn1_insert_implicit_bitstring(val->subjectPublicKey.length,val->subjectPublicKey.data,ASN1_BITSTRING); 1075 1076 if (val->algorithm.parameters.length != 0) { 1077 retval = asn1buf_insert_octetstring(buf, val->algorithm.parameters.length, 1078 val->algorithm.parameters.data); 1079 if(retval) { 1080 asn1buf_destroy(&buf); 1081 return retval; 1082 } 1083 sum += val->algorithm.parameters.length; 1084 } 1085 1086 retval = asn1_encode_oid(buf, val->algorithm.algorithm.length, 1087 val->algorithm.algorithm.data, 1088 &length); 1089 1090 if(retval) { 1091 asn1buf_destroy(&buf); 1092 return retval; 1093 } 1094 sum += length; 1095 1096 retval = asn1_make_etag(buf, UNIVERSAL, ASN1_SEQUENCE, 1097 val->algorithm.parameters.length + length, 1098 &length); 1099 1100 if(retval) { 1101 asn1buf_destroy(&buf); 1102 return retval; 1103 } 1104 sum += length; 1105 1106 asn1_makeseq(); 1107 asn1_cleanup(); 1108 } 1109 1110 asn1_error_code asn1_encode_sequence_of_algorithm_identifier(asn1buf *buf, const krb5_algorithm_identifier **val, unsigned int *retlen) 1111 { 1112 asn1_setup(); 1113 int i; 1114 1115 if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 1116 1117 for(i=0; val[i] != NULL; i++); 1118 for(i--; i>=0; i--){ 1119 retval = asn1_encode_algorithm_identifier(buf,val[i],&length); 1120 if(retval) return retval; 1121 sum += length; 1122 } 1123 asn1_makeseq(); 1124 1125 asn1_cleanup(); 1126 } 1127 1128 asn1_error_code asn1_encode_auth_pack(asn1buf *buf, const krb5_auth_pack *val, unsigned int *retlen) 1129 { 1130 asn1_setup(); 1131 1132 if (val->clientDHNonce.length != 0) 1133 asn1_addlenfield(val->clientDHNonce.length, val->clientDHNonce.data, 3, asn1_encode_octetstring); 1134 if (val->supportedCMSTypes != NULL) 1135 asn1_addfield((const krb5_algorithm_identifier **)val->supportedCMSTypes,2,asn1_encode_sequence_of_algorithm_identifier); 1136 if (val->clientPublicValue != NULL) 1137 asn1_addfield(val->clientPublicValue,1,asn1_encode_subject_pk_info); 1138 asn1_addfield(&(val->pkAuthenticator),0,asn1_encode_pk_authenticator); 1139 1140 asn1_makeseq(); 1141 asn1_cleanup(); 1142 } 1143 1144 asn1_error_code asn1_encode_auth_pack_draft9(asn1buf *buf, const krb5_auth_pack_draft9 *val, unsigned int *retlen) 1145 { 1146 asn1_setup(); 1147 1148 if (val->clientPublicValue != NULL) 1149 asn1_addfield(val->clientPublicValue, 1, asn1_encode_subject_pk_info); 1150 asn1_addfield(&(val->pkAuthenticator), 0, asn1_encode_pk_authenticator_draft9); 1151 1152 asn1_makeseq(); 1153 asn1_cleanup(); 1154 } 1155 1156 asn1_error_code asn1_encode_external_principal_identifier(asn1buf *buf, const krb5_external_principal_identifier *val, unsigned int *retlen) 1157 { 1158 asn1_setup(); 1159 1160 /* Verify there is something to encode */ 1161 if (val->subjectKeyIdentifier.length == 0 && val->issuerAndSerialNumber.length == 0 && val->subjectName.length == 0) 1162 return ASN1_MISSING_FIELD; 1163 1164 if (val->subjectKeyIdentifier.length != 0) 1165 asn1_insert_implicit_octetstring(val->subjectKeyIdentifier.length,val->subjectKeyIdentifier.data,2); 1166 1167 if (val->issuerAndSerialNumber.length != 0) 1168 asn1_insert_implicit_octetstring(val->issuerAndSerialNumber.length,val->issuerAndSerialNumber.data,1); 1169 1170 if (val->subjectName.length != 0) 1171 asn1_insert_implicit_octetstring(val->subjectName.length,val->subjectName.data,0); 1172 1173 asn1_makeseq(); 1174 asn1_cleanup(); 1175 } 1176 1177 asn1_error_code asn1_encode_sequence_of_external_principal_identifier(asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen) 1178 { 1179 asn1_setup(); 1180 int i; 1181 1182 if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 1183 1184 for(i=0; val[i] != NULL; i++); 1185 for(i--; i>=0; i--){ 1186 retval = asn1_encode_external_principal_identifier(buf,val[i],&length); 1187 if(retval) return retval; 1188 sum += length; 1189 } 1190 asn1_makeseq(); 1191 1192 asn1_cleanup(); 1193 } 1194 1195 asn1_error_code asn1_encode_pa_pk_as_req(asn1buf *buf, const krb5_pa_pk_as_req *val, unsigned int *retlen) 1196 { 1197 asn1_setup(); 1198 1199 if (val->kdcPkId.length != 0) 1200 asn1_insert_implicit_octetstring(val->kdcPkId.length,val->kdcPkId.data,2); 1201 1202 if (val->trustedCertifiers != NULL) 1203 asn1_addfield((const krb5_external_principal_identifier **)val->trustedCertifiers,1,asn1_encode_sequence_of_external_principal_identifier); 1204 1205 asn1_insert_implicit_octetstring(val->signedAuthPack.length,val->signedAuthPack.data,0); 1206 1207 asn1_makeseq(); 1208 asn1_cleanup(); 1209 } 1210 1211 asn1_error_code asn1_encode_trusted_ca(asn1buf *buf, const krb5_trusted_ca *val, unsigned int *retlen) 1212 { 1213 asn1_setup(); 1214 1215 switch (val->choice) { 1216 case choice_trusted_cas_issuerAndSerial: 1217 asn1_insert_implicit_octetstring(val->u.issuerAndSerial.length,val->u.issuerAndSerial.data,2); 1218 break; 1219 case choice_trusted_cas_caName: 1220 asn1_insert_implicit_octetstring(val->u.caName.length,val->u.caName.data,1); 1221 break; 1222 case choice_trusted_cas_principalName: 1223 asn1_addfield_implicit(val->u.principalName,0,asn1_encode_principal_name); 1224 break; 1225 default: 1226 return ASN1_MISSING_FIELD; 1227 } 1228 1229 asn1_cleanup(); 1230 } 1231 1232 asn1_error_code asn1_encode_sequence_of_trusted_ca(asn1buf *buf, const krb5_trusted_ca **val, unsigned int *retlen) 1233 { 1234 asn1_setup(); 1235 int i; 1236 1237 if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 1238 1239 for(i=0; val[i] != NULL; i++); 1240 for(i--; i>=0; i--){ 1241 retval = asn1_encode_trusted_ca(buf,val[i],&length); 1242 if(retval) return retval; 1243 sum += length; 1244 } 1245 asn1_makeseq(); 1246 asn1_cleanup(); 1247 } 1248 1249 asn1_error_code asn1_encode_pa_pk_as_req_draft9(asn1buf *buf, const krb5_pa_pk_as_req_draft9 *val, unsigned int *retlen) 1250 { 1251 asn1_setup(); 1252 1253 if (val->encryptionCert.length != 0) 1254 asn1_insert_implicit_octetstring(val->encryptionCert.length,val->encryptionCert.data,3); 1255 1256 if (val->kdcCert.length != 0) 1257 asn1_insert_implicit_octetstring(val->kdcCert.length,val->kdcCert.data,2); 1258 1259 if (val->trustedCertifiers != NULL) 1260 asn1_addfield((const krb5_trusted_ca **)val->trustedCertifiers,1,asn1_encode_sequence_of_trusted_ca); 1261 1262 asn1_insert_implicit_octetstring(val->signedAuthPack.length,val->signedAuthPack.data,0); 1263 1264 asn1_makeseq(); 1265 asn1_cleanup(); 1266 } 1267 1268 asn1_error_code asn1_encode_dh_rep_info(asn1buf *buf, const krb5_dh_rep_info *val, unsigned int *retlen) 1269 { 1270 asn1_setup(); 1271 1272 if (val->serverDHNonce.length != 0) 1273 asn1_insert_implicit_octetstring(val->serverDHNonce.length,val->serverDHNonce.data,1); 1274 1275 asn1_insert_implicit_octetstring(val->dhSignedData.length,val->dhSignedData.data,0); 1276 1277 asn1_makeseq(); 1278 asn1_cleanup(); 1279 } 1280 1281 asn1_error_code asn1_encode_kdc_dh_key_info(asn1buf *buf, const krb5_kdc_dh_key_info *val, unsigned int *retlen) 1282 { 1283 asn1_setup(); 1284 1285 if (val->dhKeyExpiration != 0) 1286 asn1_addfield(val->dhKeyExpiration, 2, asn1_encode_kerberos_time); 1287 asn1_addfield(val->nonce, 1, asn1_encode_integer); 1288 1289 asn1_insert_implicit_bitstring(val->subjectPublicKey.length,val->subjectPublicKey.data,3); 1290 retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, 0, 1291 val->subjectPublicKey.length + 1 + length, 1292 &length); 1293 if(retval) { 1294 asn1buf_destroy(&buf); 1295 return retval; 1296 } 1297 sum += length; 1298 1299 asn1_makeseq(); 1300 asn1_cleanup(); 1301 } 1302 1303 asn1_error_code asn1_encode_reply_key_pack(asn1buf *buf, const krb5_reply_key_pack *val, unsigned int *retlen) 1304 { 1305 asn1_setup(); 1306 1307 asn1_addfield(&(val->asChecksum), 1, asn1_encode_checksum); 1308 asn1_addfield(&(val->replyKey), 0, asn1_encode_encryption_key); 1309 1310 asn1_makeseq(); 1311 asn1_cleanup(); 1312 } 1313 1314 asn1_error_code asn1_encode_reply_key_pack_draft9(asn1buf *buf, const krb5_reply_key_pack_draft9 *val, unsigned int *retlen) 1315 { 1316 asn1_setup(); 1317 1318 asn1_addfield(val->nonce, 1, asn1_encode_integer); 1319 asn1_addfield(&(val->replyKey), 0, asn1_encode_encryption_key); 1320 1321 asn1_makeseq(); 1322 asn1_cleanup(); 1323 } 1324 1325 asn1_error_code asn1_encode_pa_pk_as_rep(asn1buf *buf, const krb5_pa_pk_as_rep *val, unsigned int *retlen) 1326 { 1327 asn1_setup(); 1328 1329 switch (val->choice) 1330 { 1331 case choice_pa_pk_as_rep_dhInfo: 1332 asn1_addfield(&(val->u.dh_Info), choice_pa_pk_as_rep_dhInfo, asn1_encode_dh_rep_info); 1333 break; 1334 case choice_pa_pk_as_rep_encKeyPack: 1335 asn1_insert_implicit_octetstring(val->u.encKeyPack.length,val->u.encKeyPack.data,1); 1336 break; 1337 default: 1338 return ASN1_MISSING_FIELD; 1339 } 1340 1341 asn1_cleanup(); 1342 } 1343 1344 asn1_error_code asn1_encode_pa_pk_as_rep_draft9(asn1buf *buf, const krb5_pa_pk_as_rep_draft9 *val, unsigned int *retlen) 1345 { 1346 asn1_setup(); 1347 1348 switch (val->choice) 1349 { 1350 case choice_pa_pk_as_rep_draft9_dhSignedData: 1351 asn1_insert_implicit_octetstring(val->u.dhSignedData.length,val->u.dhSignedData.data,0); 1352 break; 1353 case choice_pa_pk_as_rep_encKeyPack: 1354 asn1_insert_implicit_octetstring(val->u.encKeyPack.length,val->u.encKeyPack.data,1); 1355 break; 1356 default: 1357 return ASN1_MISSING_FIELD; 1358 } 1359 1360 asn1_cleanup(); 1361 } 1362 1363 asn1_error_code asn1_encode_td_trusted_certifiers(asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen) 1364 { 1365 asn1_setup(); 1366 retval = asn1_encode_sequence_of_external_principal_identifier(buf, val, &length); 1367 if (retval) { 1368 asn1buf_destroy(&buf); 1369 return retval; 1370 } 1371 asn1_cleanup(); 1372 } 1373 1374 asn1_error_code asn1_encode_sequence_of_typed_data(asn1buf *buf, const krb5_typed_data **val, unsigned int *retlen) 1375 { 1376 asn1_setup(); 1377 int i; 1378 1379 if(val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 1380 1381 for(i=0; val[i] != NULL; i++); 1382 for(i--; i>=0; i--){ 1383 retval = asn1_encode_typed_data(buf,val[i],&length); 1384 if(retval) return retval; 1385 sum += length; 1386 } 1387 asn1_makeseq(); 1388 1389 asn1_cleanup(); 1390 } 1391 1392 asn1_error_code asn1_encode_typed_data(asn1buf *buf, const krb5_typed_data *val, unsigned int *retlen) 1393 { 1394 asn1_setup(); 1395 asn1_addlenfield(val->length, val->data, 1, asn1_encode_octetstring); 1396 asn1_addfield(val->type, 0, asn1_encode_integer); 1397 asn1_makeseq(); 1398 asn1_cleanup(); 1399 } 1400