1 /* 2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 /* -*- mode: c; indent-tabs-mode: nil -*- */ 6 /* 7 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 8 * Use is subject to license terms. 9 */ 10 /* 11 * src/lib/krb5/asn.1/asn1_k_encode.c 12 * 13 * Copyright 1994, 2008 by the Massachusetts Institute of Technology. 14 * All Rights Reserved. 15 * 16 * Export of this software from the United States of America may 17 * require a specific license from the United States Government. 18 * It is the responsibility of any person or organization contemplating 19 * export to obtain such a license before exporting. 20 * 21 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 22 * distribute this software and its documentation for any purpose and 23 * without fee is hereby granted, provided that the above copyright 24 * notice appear in all copies and that both that copyright notice and 25 * this permission notice appear in supporting documentation, and that 26 * the name of M.I.T. not be used in advertising or publicity pertaining 27 * to distribution of the software without specific, written prior 28 * permission. Furthermore if you modify this software you must label 29 * your software as modified software and not distribute it in such a 30 * fashion that it might be confused with the original M.I.T. software. 31 * M.I.T. makes no representations about the suitability of 32 * this software for any purpose. It is provided "as is" without express 33 * or implied warranty. 34 */ 35 36 #include "asn1_k_encode.h" 37 #include "asn1_make.h" 38 #include "asn1_encode.h" 39 #include <assert.h> 40 #include "k5-platform-store_32.h" /* Solaris Kerberos */ 41 42 /* helper macros 43 44 These are mostly only needed for PKINIT, but there are three 45 basic-krb5 encoders not converted yet. */ 46 47 /* setup() -- create and initialize bookkeeping variables 48 retval: stores error codes returned from subroutines 49 length: length of the most-recently produced encoding 50 sum: cumulative length of the entire encoding */ 51 #define asn1_setup()\ 52 asn1_error_code retval;\ 53 unsigned int sum=0 54 55 /* form a sequence (by adding a sequence header to the current encoding) */ 56 #define asn1_makeseq()\ 57 { unsigned int length;\ 58 retval = asn1_make_sequence(buf,sum,&length);\ 59 if (retval) {\ 60 return retval; }\ 61 sum += length; } 62 63 /* produce the final output and clean up the workspace */ 64 #define asn1_cleanup()\ 65 *retlen = sum;\ 66 return 0 67 68 /* asn1_addfield -- add a field, or component, to the encoding */ 69 #define asn1_addfield(value,tag,encoder)\ 70 { unsigned int length; \ 71 retval = encoder(buf,value,&length); \ 72 if (retval) {\ 73 return retval; }\ 74 sum += length;\ 75 retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\ 76 if (retval) {\ 77 return retval; }\ 78 sum += length; } 79 80 DEFINTTYPE(int32, krb5_int32); 81 DEFPTRTYPE(int32_ptr, int32); 82 83 DEFUINTTYPE(uint, unsigned int); 84 DEFUINTTYPE(octet, krb5_octet); 85 DEFUINTTYPE(ui_4, krb5_ui_4); 86 87 DEFFNLENTYPE(octetstring, unsigned char *, asn1_encode_octetstring); 88 DEFFNLENTYPE(s_octetstring, char *, asn1_encode_octetstring); 89 DEFFNLENTYPE(charstring, char *, asn1_encode_charstring); 90 DEFFNLENTYPE(generalstring, char *, asn1_encode_generalstring); 91 DEFFNLENTYPE(u_generalstring, unsigned char *, asn1_encode_generalstring); 92 DEFFNLENTYPE(opaque, char *, asn1_encode_opaque); 93 94 DEFFIELDTYPE(gstring_data, krb5_data, 95 FIELDOF_STRING(krb5_data, generalstring, data, length, -1)); 96 DEFPTRTYPE(gstring_data_ptr,gstring_data); 97 98 DEFFIELDTYPE(ostring_data, krb5_data, 99 FIELDOF_STRING(krb5_data, s_octetstring, data, length, -1)); 100 DEFPTRTYPE(ostring_data_ptr,ostring_data); 101 102 DEFFIELDTYPE(opaque_data, krb5_data, 103 FIELDOF_STRING(krb5_data, opaque, data, length, -1)); 104 105 DEFFIELDTYPE(realm_of_principal_data, krb5_principal_data, 106 FIELDOF_NORM(krb5_principal_data, gstring_data, realm, -1)); 107 DEFPTRTYPE(realm_of_principal, realm_of_principal_data); 108 109 110 static const struct field_info princname_fields[] = { 111 FIELDOF_NORM(krb5_principal_data, int32, type, 0), 112 FIELDOF_SEQOF_INT32(krb5_principal_data, gstring_data_ptr, data, length, 1), 113 }; 114 /* krb5_principal is a typedef for krb5_principal_data*, so this is 115 effectively "encode_principal_data_at" with an address arg. */ 116 DEFSEQTYPE(principal_data, krb5_principal_data, princname_fields, 0); 117 DEFPTRTYPE(principal, principal_data); 118 119 static asn1_error_code 120 asn1_encode_kerberos_time_at(asn1buf *buf, const krb5_timestamp *val, 121 unsigned int *retlen) 122 { 123 /* Range checking for time_t vs krb5_timestamp? */ 124 time_t tval = *val; 125 return asn1_encode_generaltime(buf, tval, retlen); 126 } 127 DEFFNXTYPE(kerberos_time, krb5_timestamp, asn1_encode_kerberos_time_at); 128 129 static const struct field_info address_fields[] = { 130 FIELDOF_NORM(krb5_address, int32, addrtype, 0), 131 FIELDOF_STRING(krb5_address, octetstring, contents, length, 1), 132 }; 133 DEFSEQTYPE(address, krb5_address, address_fields, 0); 134 DEFPTRTYPE(address_ptr, address); 135 136 DEFNULLTERMSEQOFTYPE(seq_of_host_addresses, address_ptr); 137 DEFPTRTYPE(ptr_seqof_host_addresses, seq_of_host_addresses); 138 139 static unsigned int 140 optional_encrypted_data (const void *vptr) 141 { 142 const krb5_enc_data *val = vptr; 143 unsigned int optional = 0; 144 145 if (val->kvno != 0) 146 optional |= (1u << 1); 147 148 return optional; 149 } 150 151 static const struct field_info encrypted_data_fields[] = { 152 FIELDOF_NORM(krb5_enc_data, int32, enctype, 0), 153 FIELDOF_OPT(krb5_enc_data, uint, kvno, 1, 1), 154 FIELDOF_NORM(krb5_enc_data, ostring_data, ciphertext, 2), 155 }; 156 DEFSEQTYPE(encrypted_data, krb5_enc_data, encrypted_data_fields, 157 optional_encrypted_data); 158 159 /* The encode_bitstring function wants an array of bytes (since PKINIT 160 may provide something that isn't 32 bits), but krb5_flags is stored 161 as a 32-bit integer in host order. */ 162 static asn1_error_code 163 asn1_encode_krb5_flags_at(asn1buf *buf, const krb5_flags *val, 164 unsigned int *retlen) 165 { 166 unsigned char cbuf[4]; 167 store_32_be((krb5_ui_4) *val, cbuf); 168 return asn1_encode_bitstring(buf, 4, cbuf, retlen); 169 } 170 DEFFNXTYPE(krb5_flags, krb5_flags, asn1_encode_krb5_flags_at); 171 172 static const struct field_info authdata_elt_fields[] = { 173 /* ad-type[0] INTEGER */ 174 FIELDOF_NORM(krb5_authdata, int32, ad_type, 0), 175 /* ad-data[1] OCTET STRING */ 176 FIELDOF_STRING(krb5_authdata, octetstring, contents, length, 1), 177 }; 178 DEFSEQTYPE(authdata_elt, krb5_authdata, authdata_elt_fields, 0); 179 DEFPTRTYPE(authdata_elt_ptr, authdata_elt); 180 DEFNONEMPTYNULLTERMSEQOFTYPE(auth_data, authdata_elt_ptr); 181 DEFPTRTYPE(auth_data_ptr, auth_data); 182 183 static const struct field_info encryption_key_fields[] = { 184 FIELDOF_NORM(krb5_keyblock, int32, enctype, 0), 185 FIELDOF_STRING(krb5_keyblock, octetstring, contents, length, 1), 186 }; 187 DEFSEQTYPE(encryption_key, krb5_keyblock, encryption_key_fields, 0); 188 DEFPTRTYPE(ptr_encryption_key, encryption_key); 189 190 static const struct field_info checksum_fields[] = { 191 FIELDOF_NORM(krb5_checksum, int32, checksum_type, 0), 192 FIELDOF_STRING(krb5_checksum, octetstring, contents, length, 1), 193 }; 194 DEFSEQTYPE(checksum, krb5_checksum, checksum_fields, 0); 195 DEFPTRTYPE(checksum_ptr, checksum); 196 DEFNULLTERMSEQOFTYPE(seq_of_checksum, checksum_ptr); 197 DEFPTRTYPE(ptr_seqof_checksum, seq_of_checksum); 198 199 static const struct field_info lr_fields[] = { 200 FIELDOF_NORM(krb5_last_req_entry, int32, lr_type, 0), 201 FIELDOF_NORM(krb5_last_req_entry, kerberos_time, value, 1), 202 }; 203 DEFSEQTYPE(last_req_ent, krb5_last_req_entry, lr_fields, 0); 204 205 DEFPTRTYPE(last_req_ent_ptr, last_req_ent); 206 DEFNONEMPTYNULLTERMSEQOFTYPE(last_req, last_req_ent_ptr); 207 DEFPTRTYPE(last_req_ptr, last_req); 208 209 static const struct field_info ticket_fields[] = { 210 FIELD_INT_IMM(KVNO, 0), 211 FIELDOF_NORM(krb5_ticket, realm_of_principal, server, 1), 212 FIELDOF_NORM(krb5_ticket, principal, server, 2), 213 FIELDOF_NORM(krb5_ticket, encrypted_data, enc_part, 3), 214 }; 215 DEFSEQTYPE(untagged_ticket, krb5_ticket, ticket_fields, 0); 216 DEFAPPTAGGEDTYPE(ticket, 1, untagged_ticket); 217 218 static const struct field_info pa_data_fields[] = { 219 FIELDOF_NORM(krb5_pa_data, int32, pa_type, 1), 220 FIELDOF_STRING(krb5_pa_data, octetstring, contents, length, 2), 221 }; 222 DEFSEQTYPE(pa_data, krb5_pa_data, pa_data_fields, 0); 223 DEFPTRTYPE(pa_data_ptr, pa_data); 224 225 DEFNULLTERMSEQOFTYPE(seq_of_pa_data, pa_data_ptr); 226 DEFPTRTYPE(ptr_seqof_pa_data, seq_of_pa_data); 227 228 DEFPTRTYPE(ticket_ptr, ticket); 229 DEFNONEMPTYNULLTERMSEQOFTYPE(seq_of_ticket,ticket_ptr); 230 DEFPTRTYPE(ptr_seqof_ticket, seq_of_ticket); 231 232 /* EncKDCRepPart ::= SEQUENCE */ 233 static const struct field_info enc_kdc_rep_part_fields[] = { 234 /* key[0] EncryptionKey */ 235 FIELDOF_NORM(krb5_enc_kdc_rep_part, ptr_encryption_key, session, 0), 236 /* last-req[1] LastReq */ 237 FIELDOF_NORM(krb5_enc_kdc_rep_part, last_req_ptr, last_req, 1), 238 /* nonce[2] INTEGER */ 239 FIELDOF_NORM(krb5_enc_kdc_rep_part, int32, nonce, 2), 240 /* key-expiration[3] KerberosTime OPTIONAL */ 241 FIELDOF_OPT(krb5_enc_kdc_rep_part, kerberos_time, key_exp, 3, 3), 242 /* flags[4] TicketFlags */ 243 FIELDOF_NORM(krb5_enc_kdc_rep_part, krb5_flags, flags, 4), 244 /* authtime[5] KerberosTime */ 245 FIELDOF_NORM(krb5_enc_kdc_rep_part, kerberos_time, times.authtime, 5), 246 /* starttime[6] KerberosTime OPTIONAL */ 247 FIELDOF_OPT(krb5_enc_kdc_rep_part, kerberos_time, times.starttime, 6, 6), 248 /* endtime[7] KerberosTime */ 249 FIELDOF_NORM(krb5_enc_kdc_rep_part, kerberos_time, times.endtime, 7), 250 /* renew-till[8] KerberosTime OPTIONAL */ 251 FIELDOF_OPT(krb5_enc_kdc_rep_part, kerberos_time, times.renew_till, 8, 8), 252 /* srealm[9] Realm */ 253 FIELDOF_NORM(krb5_enc_kdc_rep_part, realm_of_principal, server, 9), 254 /* sname[10] PrincipalName */ 255 FIELDOF_NORM(krb5_enc_kdc_rep_part, principal, server, 10), 256 /* caddr[11] HostAddresses OPTIONAL */ 257 FIELDOF_OPT(krb5_enc_kdc_rep_part, ptr_seqof_host_addresses, caddrs, 258 11, 11), 259 /* encrypted-pa-data[12] SEQUENCE OF PA-DATA OPTIONAL */ 260 FIELDOF_OPT(krb5_enc_kdc_rep_part, ptr_seqof_pa_data, enc_padata, 12, 12), 261 }; 262 static unsigned int optional_enc_kdc_rep_part(const void *p) 263 { 264 const krb5_enc_kdc_rep_part *val = p; 265 unsigned int optional = 0; 266 267 if (val->key_exp) 268 optional |= (1u << 3); 269 if (val->times.starttime) 270 optional |= (1u << 6); 271 if (val->flags & TKT_FLG_RENEWABLE) 272 optional |= (1u << 8); 273 if (val->caddrs != NULL && val->caddrs[0] != NULL) 274 optional |= (1u << 11); 275 276 return optional; 277 } 278 DEFSEQTYPE(enc_kdc_rep_part, krb5_enc_kdc_rep_part, enc_kdc_rep_part_fields, 279 optional_enc_kdc_rep_part); 280 281 /* Yuck! Eventually push this *up* above the encoder API and make the 282 rest of the library put the realm name in one consistent place. At 283 the same time, might as well add the msg-type field and encode both 284 AS-REQ and TGS-REQ through the same descriptor. */ 285 struct kdc_req_hack { 286 krb5_kdc_req v; 287 krb5_data *server_realm; 288 }; 289 static const struct field_info kdc_req_hack_fields[] = { 290 FIELDOF_NORM(struct kdc_req_hack, krb5_flags, v.kdc_options, 0), 291 FIELDOF_OPT(struct kdc_req_hack, principal, v.client, 1, 1), 292 FIELDOF_NORM(struct kdc_req_hack, gstring_data_ptr, server_realm, 2), 293 FIELDOF_OPT(struct kdc_req_hack, principal, v.server, 3, 3), 294 FIELDOF_OPT(struct kdc_req_hack, kerberos_time, v.from, 4, 4), 295 FIELDOF_NORM(struct kdc_req_hack, kerberos_time, v.till, 5), 296 FIELDOF_OPT(struct kdc_req_hack, kerberos_time, v.rtime, 6, 6), 297 FIELDOF_NORM(struct kdc_req_hack, int32, v.nonce, 7), 298 FIELDOF_SEQOF_INT32(struct kdc_req_hack, int32_ptr, v.ktype, v.nktypes, 8), 299 FIELDOF_OPT(struct kdc_req_hack, ptr_seqof_host_addresses, v.addresses, 9, 9), 300 FIELDOF_OPT(struct kdc_req_hack, encrypted_data, v.authorization_data, 10, 10), 301 FIELDOF_OPT(struct kdc_req_hack, ptr_seqof_ticket, v.second_ticket, 11, 11), 302 }; 303 static unsigned int optional_kdc_req_hack(const void *p) 304 { 305 const struct kdc_req_hack *val2 = p; 306 const krb5_kdc_req *val = &val2->v; 307 unsigned int optional = 0; 308 309 if (val->second_ticket != NULL && val->second_ticket[0] != NULL) 310 optional |= (1u << 11); 311 if (val->authorization_data.ciphertext.data != NULL) 312 optional |= (1u << 10); 313 if (val->addresses != NULL && val->addresses[0] != NULL) 314 optional |= (1u << 9); 315 if (val->rtime) 316 optional |= (1u << 6); 317 if (val->from) 318 optional |= (1u << 4); 319 if (val->server != NULL) 320 optional |= (1u << 3); 321 if (val->client != NULL) 322 optional |= (1u << 1); 323 324 return optional; 325 } 326 DEFSEQTYPE(kdc_req_body_hack, struct kdc_req_hack, kdc_req_hack_fields, 327 optional_kdc_req_hack); 328 static asn1_error_code 329 asn1_encode_kdc_req_hack(asn1buf *, const struct kdc_req_hack *, 330 unsigned int *); 331 MAKE_ENCFN(asn1_encode_kdc_req_hack, kdc_req_body_hack); 332 static asn1_error_code 333 asn1_encode_kdc_req_body(asn1buf *buf, const krb5_kdc_req *val, 334 unsigned int *retlen) 335 { 336 struct kdc_req_hack val2; 337 val2.v = *val; 338 if (val->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY) { 339 if (val->second_ticket != NULL && val->second_ticket[0] != NULL) { 340 val2.server_realm = &val->second_ticket[0]->server->realm; 341 } else return ASN1_MISSING_FIELD; 342 } else if (val->server != NULL) { 343 val2.server_realm = &val->server->realm; 344 } else return ASN1_MISSING_FIELD; 345 return asn1_encode_kdc_req_hack(buf, &val2, retlen); 346 } 347 DEFFNXTYPE(kdc_req_body, krb5_kdc_req, asn1_encode_kdc_req_body); 348 /* end ugly hack */ 349 350 DEFPTRTYPE(ptr_kdc_req_body,kdc_req_body); 351 352 static const struct field_info transited_fields[] = { 353 FIELDOF_NORM(krb5_transited, octet, tr_type, 0), 354 FIELDOF_NORM(krb5_transited, ostring_data, tr_contents, 1), 355 }; 356 DEFSEQTYPE(transited, krb5_transited, transited_fields, 0); 357 358 static const struct field_info krb_safe_body_fields[] = { 359 FIELDOF_NORM(krb5_safe, ostring_data, user_data, 0), 360 FIELDOF_OPT(krb5_safe, kerberos_time, timestamp, 1, 1), 361 FIELDOF_OPT(krb5_safe, int32, usec, 2, 2), 362 FIELDOF_OPT(krb5_safe, uint, seq_number, 3, 3), 363 FIELDOF_NORM(krb5_safe, address_ptr, s_address, 4), 364 FIELDOF_OPT(krb5_safe, address_ptr, r_address, 5, 5), 365 }; 366 static unsigned int optional_krb_safe_body(const void *p) 367 { 368 const krb5_safe *val = p; 369 unsigned int optional = 0; 370 371 if (val->timestamp) { 372 optional |= (1u << 1); 373 optional |= (1u << 2); 374 } 375 if (val->seq_number) 376 optional |= (1u << 3); 377 if (val->r_address != NULL) 378 optional |= (1u << 5); 379 380 return optional; 381 } 382 DEFSEQTYPE(krb_safe_body, krb5_safe, krb_safe_body_fields, 383 optional_krb_safe_body); 384 385 static const struct field_info krb_cred_info_fields[] = { 386 FIELDOF_NORM(krb5_cred_info, ptr_encryption_key, session, 0), 387 FIELDOF_OPT(krb5_cred_info, realm_of_principal, client, 1, 1), 388 FIELDOF_OPT(krb5_cred_info, principal, client, 2, 2), 389 FIELDOF_OPT(krb5_cred_info, krb5_flags, flags, 3, 3), 390 FIELDOF_OPT(krb5_cred_info, kerberos_time, times.authtime, 4, 4), 391 FIELDOF_OPT(krb5_cred_info, kerberos_time, times.starttime, 5, 5), 392 FIELDOF_OPT(krb5_cred_info, kerberos_time, times.endtime, 6, 6), 393 FIELDOF_OPT(krb5_cred_info, kerberos_time, times.renew_till, 7, 7), 394 FIELDOF_OPT(krb5_cred_info, realm_of_principal, server, 8, 8), 395 FIELDOF_OPT(krb5_cred_info, principal, server, 9, 9), 396 FIELDOF_OPT(krb5_cred_info, ptr_seqof_host_addresses, caddrs, 10, 10), 397 }; 398 static unsigned int optional_krb_cred_info(const void *p) 399 { 400 const krb5_cred_info *val = p; 401 unsigned int optional = 0; 402 403 if (val->caddrs != NULL && val->caddrs[0] != NULL) 404 optional |= (1u << 10); 405 if (val->server != NULL) { 406 optional |= (1u << 9); 407 optional |= (1u << 8); 408 } 409 if (val->times.renew_till) 410 optional |= (1u << 7); 411 if (val->times.endtime) 412 optional |= (1u << 6); 413 if (val->times.starttime) 414 optional |= (1u << 5); 415 if (val->times.authtime) 416 optional |= (1u << 4); 417 if (val->flags) 418 optional |= (1u << 3); 419 if (val->client != NULL) { 420 optional |= (1u << 2); 421 optional |= (1u << 1); 422 } 423 424 return optional; 425 } 426 DEFSEQTYPE(cred_info, krb5_cred_info, krb_cred_info_fields, 427 optional_krb_cred_info); 428 DEFPTRTYPE(cred_info_ptr, cred_info); 429 DEFNULLTERMSEQOFTYPE(seq_of_cred_info, cred_info_ptr); 430 431 DEFPTRTYPE(ptrseqof_cred_info, seq_of_cred_info); 432 433 434 435 static unsigned int 436 optional_etype_info_entry(const void *vptr) 437 { 438 const krb5_etype_info_entry *val = vptr; 439 unsigned int optional = 0; 440 441 if (val->length >= 0 && val->length != KRB5_ETYPE_NO_SALT) 442 optional |= (1u << 1); 443 444 return optional; 445 } 446 static const struct field_info etype_info_entry_fields[] = { 447 FIELDOF_NORM(krb5_etype_info_entry, int32, etype, 0), 448 FIELDOF_OPTSTRING(krb5_etype_info_entry, octetstring, salt, length, 1, 1), 449 }; 450 DEFSEQTYPE(etype_info_entry, krb5_etype_info_entry, etype_info_entry_fields, 451 optional_etype_info_entry); 452 453 static unsigned int 454 optional_etype_info2_entry(const void *vptr) 455 { 456 const krb5_etype_info_entry *val = vptr; 457 unsigned int optional = 0; 458 459 if (val->length >= 0 && val->length != KRB5_ETYPE_NO_SALT) 460 optional |= (1u << 1); 461 if (val->s2kparams.data) 462 optional |= (1u << 2); 463 464 return optional; 465 } 466 467 static const struct field_info etype_info2_entry_fields[] = { 468 FIELDOF_NORM(krb5_etype_info_entry, int32, etype, 0), 469 FIELDOF_OPTSTRING(krb5_etype_info_entry, u_generalstring, salt, length, 470 1, 1), 471 FIELDOF_OPT(krb5_etype_info_entry, ostring_data, s2kparams, 2, 2), 472 }; 473 DEFSEQTYPE(etype_info2_entry, krb5_etype_info_entry, etype_info2_entry_fields, 474 optional_etype_info2_entry); 475 476 DEFPTRTYPE(etype_info_entry_ptr, etype_info_entry); 477 DEFNULLTERMSEQOFTYPE(etype_info, etype_info_entry_ptr); 478 479 DEFPTRTYPE(etype_info2_entry_ptr, etype_info2_entry); 480 DEFNULLTERMSEQOFTYPE(etype_info2, etype_info2_entry_ptr); 481 482 static const struct field_info passwdsequence_fields[] = { 483 FIELDOF_NORM(passwd_phrase_element, ostring_data_ptr, passwd, 0), 484 FIELDOF_NORM(passwd_phrase_element, ostring_data_ptr, phrase, 1), 485 }; 486 DEFSEQTYPE(passwdsequence, passwd_phrase_element, passwdsequence_fields, 0); 487 488 DEFPTRTYPE(passwdsequence_ptr, passwdsequence); 489 DEFNONEMPTYNULLTERMSEQOFTYPE(seqof_passwdsequence, passwdsequence_ptr); 490 DEFPTRTYPE(ptr_seqof_passwdsequence, seqof_passwdsequence); 491 492 493 static const struct field_info sam_challenge_fields[] = { 494 FIELDOF_NORM(krb5_sam_challenge, int32, sam_type, 0), 495 FIELDOF_NORM(krb5_sam_challenge, krb5_flags, sam_flags, 1), 496 FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_type_name, 2, 2), 497 FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_track_id,3, 3), 498 FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_challenge_label,4, 4), 499 FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_challenge,5, 5), 500 FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_response_prompt,6, 6), 501 FIELDOF_OPT(krb5_sam_challenge, ostring_data, sam_pk_for_sad,7, 7), 502 FIELDOF_OPT(krb5_sam_challenge, int32, sam_nonce, 8, 8), 503 FIELDOF_OPT(krb5_sam_challenge, checksum, sam_cksum, 9, 9), 504 }; 505 static unsigned int optional_sam_challenge(const void *p) 506 { 507 const krb5_sam_challenge *val = p; 508 unsigned int optional = 0; 509 510 if (val->sam_cksum.length) 511 optional |= (1u << 9); 512 513 if (val->sam_nonce) 514 optional |= (1u << 8); 515 516 if (val->sam_pk_for_sad.length > 0) optional |= (1u << 7); 517 if (val->sam_response_prompt.length > 0) optional |= (1u << 6); 518 if (val->sam_challenge.length > 0) optional |= (1u << 5); 519 if (val->sam_challenge_label.length > 0) optional |= (1u << 4); 520 if (val->sam_track_id.length > 0) optional |= (1u << 3); 521 if (val->sam_type_name.length > 0) optional |= (1u << 2); 522 523 return optional; 524 } 525 DEFSEQTYPE(sam_challenge,krb5_sam_challenge,sam_challenge_fields, 526 optional_sam_challenge); 527 528 #if 0 /* encoders not used! */ 529 MAKE_ENCFN(asn1_encode_sequence_of_checksum, seq_of_checksum); 530 static asn1_error_code 531 asn1_encode_sam_challenge_2(asn1buf *buf, const krb5_sam_challenge_2 *val, 532 unsigned int *retlen) 533 { 534 asn1_setup(); 535 if ( (!val) || (!val->sam_cksum) || (!val->sam_cksum[0])) 536 return ASN1_MISSING_FIELD; 537 538 asn1_addfield(val->sam_cksum, 1, asn1_encode_sequence_of_checksum); 539 540 { 541 unsigned int length; 542 543 retval = asn1buf_insert_octetstring(buf, val->sam_challenge_2_body.length, 544 (unsigned char *)val->sam_challenge_2_body.data); 545 if (retval) { 546 return retval; 547 } 548 sum += val->sam_challenge_2_body.length; 549 retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, 0, 550 val->sam_challenge_2_body.length, &length); 551 if (retval) { 552 return retval; 553 } 554 sum += length; 555 } 556 557 asn1_makeseq(); 558 asn1_cleanup(); 559 } 560 DEFFNXTYPE(sam_challenge_2, krb5_sam_challenge_2, asn1_encode_sam_challenge_2); 561 562 static const struct field_info sam_challenge_2_body_fields[] = { 563 FIELDOF_NORM(krb5_sam_challenge_2_body, int32, sam_type, 0), 564 FIELDOF_NORM(krb5_sam_challenge_2_body, krb5_flags, sam_flags, 1), 565 FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_type_name, 2, 2), 566 FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_track_id,3, 3), 567 FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_challenge_label,4, 4), 568 FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_challenge,5, 5), 569 FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_response_prompt,6, 6), 570 FIELDOF_OPT(krb5_sam_challenge_2_body, ostring_data, sam_pk_for_sad,7, 7), 571 FIELDOF_NORM(krb5_sam_challenge_2_body, int32, sam_nonce, 8), 572 FIELDOF_NORM(krb5_sam_challenge_2_body, int32, sam_etype, 9), 573 }; 574 static unsigned int optional_sam_challenge_2_body(const void *p) 575 { 576 const krb5_sam_challenge_2_body *val = p; 577 unsigned int optional = 0; 578 579 if (val->sam_pk_for_sad.length > 0) optional |= (1u << 7); 580 if (val->sam_response_prompt.length > 0) optional |= (1u << 6); 581 if (val->sam_challenge.length > 0) optional |= (1u << 5); 582 if (val->sam_challenge_label.length > 0) optional |= (1u << 4); 583 if (val->sam_track_id.length > 0) optional |= (1u << 3); 584 if (val->sam_type_name.length > 0) optional |= (1u << 2); 585 586 return optional; 587 } 588 DEFSEQTYPE(sam_challenge_2_body,krb5_sam_challenge_2_body,sam_challenge_2_body_fields, 589 optional_sam_challenge_2_body); 590 #endif 591 592 static const struct field_info sam_key_fields[] = { 593 FIELDOF_NORM(krb5_sam_key, encryption_key, sam_key, 0), 594 }; 595 DEFSEQTYPE(sam_key, krb5_sam_key, sam_key_fields, 0); 596 597 static const struct field_info enc_sam_response_enc_fields[] = { 598 FIELDOF_NORM(krb5_enc_sam_response_enc, int32, sam_nonce, 0), 599 FIELDOF_NORM(krb5_enc_sam_response_enc, kerberos_time, sam_timestamp, 1), 600 FIELDOF_NORM(krb5_enc_sam_response_enc, int32, sam_usec, 2), 601 FIELDOF_OPT(krb5_enc_sam_response_enc, ostring_data, sam_sad, 3, 3), 602 }; 603 static unsigned int optional_enc_sam_response_enc(const void *p) 604 { 605 const krb5_enc_sam_response_enc *val = p; 606 unsigned int optional = 0; 607 608 if (val->sam_sad.length > 0) optional |= (1u << 3); 609 610 return optional; 611 } 612 DEFSEQTYPE(enc_sam_response_enc, krb5_enc_sam_response_enc, 613 enc_sam_response_enc_fields, optional_enc_sam_response_enc); 614 615 static const struct field_info enc_sam_response_enc_2_fields[] = { 616 FIELDOF_NORM(krb5_enc_sam_response_enc_2, int32, sam_nonce, 0), 617 FIELDOF_OPT(krb5_enc_sam_response_enc_2, ostring_data, sam_sad, 1, 1), 618 }; 619 static unsigned int optional_enc_sam_response_enc_2(const void *p) 620 { 621 const krb5_enc_sam_response_enc_2 *val = p; 622 unsigned int optional = 0; 623 624 if (val->sam_sad.length > 0) optional |= (1u << 1); 625 626 return optional; 627 } 628 DEFSEQTYPE(enc_sam_response_enc_2, krb5_enc_sam_response_enc_2, 629 enc_sam_response_enc_2_fields, optional_enc_sam_response_enc_2); 630 631 static const struct field_info sam_response_fields[] = { 632 FIELDOF_NORM(krb5_sam_response, int32, sam_type, 0), 633 FIELDOF_NORM(krb5_sam_response, krb5_flags, sam_flags, 1), 634 FIELDOF_OPT(krb5_sam_response, ostring_data, sam_track_id, 2, 2), 635 FIELDOF_OPT(krb5_sam_response, encrypted_data, sam_enc_key, 3, 3), 636 FIELDOF_NORM(krb5_sam_response, encrypted_data, sam_enc_nonce_or_ts, 4), 637 FIELDOF_OPT(krb5_sam_response, int32, sam_nonce, 5, 5), 638 FIELDOF_OPT(krb5_sam_response, kerberos_time, sam_patimestamp, 6, 6), 639 }; 640 static unsigned int optional_sam_response(const void *p) 641 { 642 const krb5_sam_response *val = p; 643 unsigned int optional = 0; 644 645 if (val->sam_patimestamp) 646 optional |= (1u << 6); 647 if (val->sam_nonce) 648 optional |= (1u << 5); 649 if (val->sam_enc_key.ciphertext.length) 650 optional |= (1u << 3); 651 if (val->sam_track_id.length > 0) optional |= (1u << 2); 652 653 return optional; 654 } 655 DEFSEQTYPE(sam_response, krb5_sam_response, sam_response_fields, 656 optional_sam_response); 657 658 static const struct field_info sam_response_2_fields[] = { 659 FIELDOF_NORM(krb5_sam_response_2, int32, sam_type, 0), 660 FIELDOF_NORM(krb5_sam_response_2, krb5_flags, sam_flags, 1), 661 FIELDOF_OPT(krb5_sam_response_2, ostring_data, sam_track_id, 2, 2), 662 FIELDOF_NORM(krb5_sam_response_2, encrypted_data, sam_enc_nonce_or_sad, 3), 663 FIELDOF_NORM(krb5_sam_response_2, int32, sam_nonce, 4), 664 }; 665 static unsigned int optional_sam_response_2(const void *p) 666 { 667 const krb5_sam_response_2 *val = p; 668 unsigned int optional = 0; 669 670 if (val->sam_track_id.length > 0) optional |= (1u << 2); 671 672 return optional; 673 } 674 DEFSEQTYPE(sam_response_2, krb5_sam_response_2, sam_response_2_fields, 675 optional_sam_response_2); 676 677 static const struct field_info predicted_sam_response_fields[] = { 678 FIELDOF_NORM(krb5_predicted_sam_response, encryption_key, sam_key, 0), 679 FIELDOF_NORM(krb5_predicted_sam_response, krb5_flags, sam_flags, 1), 680 FIELDOF_NORM(krb5_predicted_sam_response, kerberos_time, stime, 2), 681 FIELDOF_NORM(krb5_predicted_sam_response, int32, susec, 3), 682 FIELDOF_NORM(krb5_predicted_sam_response, realm_of_principal, client, 4), 683 FIELDOF_NORM(krb5_predicted_sam_response, principal, client, 5), 684 FIELDOF_OPT(krb5_predicted_sam_response, ostring_data, msd, 6, 6), 685 }; 686 static unsigned int optional_predicted_sam_response(const void *p) 687 { 688 const krb5_predicted_sam_response *val = p; 689 unsigned int optional = 0; 690 691 if (val->msd.length > 0) optional |= (1u << 6); 692 693 return optional; 694 } 695 DEFSEQTYPE(predicted_sam_response, krb5_predicted_sam_response, 696 predicted_sam_response_fields, 697 optional_predicted_sam_response); 698 699 static const struct field_info krb5_authenticator_fields[] = { 700 /* Authenticator ::= [APPLICATION 2] SEQUENCE */ 701 /* authenticator-vno[0] INTEGER */ 702 FIELD_INT_IMM(KVNO, 0), 703 /* crealm[1] Realm */ 704 FIELDOF_NORM(krb5_authenticator, realm_of_principal, client, 1), 705 /* cname[2] PrincipalName */ 706 FIELDOF_NORM(krb5_authenticator, principal, client, 2), 707 /* cksum[3] Checksum OPTIONAL */ 708 FIELDOF_OPT(krb5_authenticator, checksum_ptr, checksum, 3, 3), 709 /* cusec[4] INTEGER */ 710 FIELDOF_NORM(krb5_authenticator, int32, cusec, 4), 711 /* ctime[5] KerberosTime */ 712 FIELDOF_NORM(krb5_authenticator, kerberos_time, ctime, 5), 713 /* subkey[6] EncryptionKey OPTIONAL */ 714 FIELDOF_OPT(krb5_authenticator, ptr_encryption_key, subkey, 6, 6), 715 /* seq-number[7] INTEGER OPTIONAL */ 716 FIELDOF_OPT(krb5_authenticator, uint, seq_number, 7, 7), 717 /* authorization-data[8] AuthorizationData OPTIONAL */ 718 FIELDOF_OPT(krb5_authenticator, auth_data_ptr, authorization_data, 8, 8), 719 }; 720 static unsigned int optional_krb5_authenticator(const void *p) 721 { 722 const krb5_authenticator *val = p; 723 unsigned int optional = 0; 724 725 if (val->authorization_data != NULL && val->authorization_data[0] != NULL) 726 optional |= (1u << 8); 727 728 if (val->seq_number != 0) 729 optional |= (1u << 7); 730 731 if (val->subkey != NULL) 732 optional |= (1u << 6); 733 734 if (val->checksum != NULL) 735 optional |= (1u << 3); 736 737 return optional; 738 } 739 DEFSEQTYPE(untagged_krb5_authenticator, krb5_authenticator, krb5_authenticator_fields, 740 optional_krb5_authenticator); 741 DEFAPPTAGGEDTYPE(krb5_authenticator, 2, untagged_krb5_authenticator); 742 743 static const struct field_info enc_tkt_part_fields[] = { 744 /* EncTicketPart ::= [APPLICATION 3] SEQUENCE */ 745 /* flags[0] TicketFlags */ 746 FIELDOF_NORM(krb5_enc_tkt_part, krb5_flags, flags, 0), 747 /* key[1] EncryptionKey */ 748 FIELDOF_NORM(krb5_enc_tkt_part, ptr_encryption_key, session, 1), 749 /* crealm[2] Realm */ 750 FIELDOF_NORM(krb5_enc_tkt_part, realm_of_principal, client, 2), 751 /* cname[3] PrincipalName */ 752 FIELDOF_NORM(krb5_enc_tkt_part, principal, client, 3), 753 /* transited[4] TransitedEncoding */ 754 FIELDOF_NORM(krb5_enc_tkt_part, transited, transited, 4), 755 /* authtime[5] KerberosTime */ 756 FIELDOF_NORM(krb5_enc_tkt_part, kerberos_time, times.authtime, 5), 757 /* starttime[6] KerberosTime OPTIONAL */ 758 FIELDOF_OPT(krb5_enc_tkt_part, kerberos_time, times.starttime, 6, 6), 759 /* endtime[7] KerberosTime */ 760 FIELDOF_NORM(krb5_enc_tkt_part, kerberos_time, times.endtime, 7), 761 /* renew-till[8] KerberosTime OPTIONAL */ 762 FIELDOF_OPT(krb5_enc_tkt_part, kerberos_time, times.renew_till, 8, 8), 763 /* caddr[9] HostAddresses OPTIONAL */ 764 FIELDOF_OPT(krb5_enc_tkt_part, ptr_seqof_host_addresses, caddrs, 9, 9), 765 /* authorization-data[10] AuthorizationData OPTIONAL */ 766 FIELDOF_OPT(krb5_enc_tkt_part, auth_data_ptr, authorization_data, 10, 10), 767 }; 768 static unsigned int optional_enc_tkt_part(const void *p) 769 { 770 const krb5_enc_tkt_part *val = p; 771 unsigned int optional = 0; 772 773 if (val->authorization_data != NULL && val->authorization_data[0] != NULL) 774 optional |= (1u << 10); 775 if (val->caddrs != NULL && val->caddrs[0] != NULL) 776 optional |= (1u << 9); 777 if (val->times.renew_till) 778 optional |= (1u << 8); 779 if (val->times.starttime) 780 optional |= (1u << 6); 781 782 return optional; 783 } 784 DEFSEQTYPE(untagged_enc_tkt_part, krb5_enc_tkt_part, enc_tkt_part_fields, 785 optional_enc_tkt_part); 786 DEFAPPTAGGEDTYPE(enc_tkt_part, 3, untagged_enc_tkt_part); 787 788 DEFAPPTAGGEDTYPE(enc_tgs_rep_part, 26, enc_kdc_rep_part); 789 790 static const struct field_info as_rep_fields[] = { 791 /* AS-REP ::= [APPLICATION 11] KDC-REP */ 792 /* But KDC-REP needs to know what type it's being encapsulated 793 in, so expand each version. */ 794 FIELD_INT_IMM(KVNO, 0), 795 FIELD_INT_IMM(KRB5_AS_REP, 1), 796 FIELDOF_OPT(krb5_kdc_rep, ptr_seqof_pa_data, padata, 2, 2), 797 FIELDOF_NORM(krb5_kdc_rep, realm_of_principal, client, 3), 798 FIELDOF_NORM(krb5_kdc_rep, principal, client, 4), 799 FIELDOF_NORM(krb5_kdc_rep, ticket_ptr, ticket, 5), 800 FIELDOF_NORM(krb5_kdc_rep, encrypted_data, enc_part, 6), 801 }; 802 static unsigned int optional_as_rep(const void *p) 803 { 804 const krb5_kdc_rep *val = p; 805 unsigned int optional = 0; 806 807 if (val->padata != NULL && val->padata[0] != NULL) 808 optional |= (1u << 2); 809 810 return optional; 811 } 812 DEFSEQTYPE(untagged_as_rep, krb5_kdc_rep, as_rep_fields, optional_as_rep); 813 DEFAPPTAGGEDTYPE(as_rep, 11, untagged_as_rep); 814 815 static const struct field_info tgs_rep_fields[] = { 816 /* TGS-REP ::= [APPLICATION 13] KDC-REP */ 817 /* But KDC-REP needs to know what type it's being encapsulated 818 in, so expand each version. */ 819 FIELD_INT_IMM(KVNO, 0), 820 FIELD_INT_IMM(KRB5_TGS_REP, 1), 821 FIELDOF_OPT(krb5_kdc_rep, ptr_seqof_pa_data, padata, 2, 2), 822 FIELDOF_NORM(krb5_kdc_rep, realm_of_principal, client, 3), 823 FIELDOF_NORM(krb5_kdc_rep, principal, client, 4), 824 FIELDOF_NORM(krb5_kdc_rep, ticket_ptr, ticket, 5), 825 FIELDOF_NORM(krb5_kdc_rep, encrypted_data, enc_part, 6), 826 }; 827 static unsigned int optional_tgs_rep(const void *p) 828 { 829 const krb5_kdc_rep *val = p; 830 unsigned int optional = 0; 831 832 if (val->padata != NULL && val->padata[0] != NULL) 833 optional |= (1u << 2); 834 835 return optional; 836 } 837 DEFSEQTYPE(untagged_tgs_rep, krb5_kdc_rep, tgs_rep_fields, optional_tgs_rep); 838 DEFAPPTAGGEDTYPE(tgs_rep, 13, untagged_tgs_rep); 839 840 static const struct field_info ap_req_fields[] = { 841 /* AP-REQ ::= [APPLICATION 14] SEQUENCE */ 842 /* pvno[0] INTEGER */ 843 FIELD_INT_IMM(KVNO, 0), 844 /* msg-type[1] INTEGER */ 845 FIELD_INT_IMM(ASN1_KRB_AP_REQ, 1), 846 /* ap-options[2] APOptions */ 847 FIELDOF_NORM(krb5_ap_req, krb5_flags, ap_options, 2), 848 /* ticket[3] Ticket */ 849 FIELDOF_NORM(krb5_ap_req, ticket_ptr, ticket, 3), 850 /* authenticator[4] EncryptedData */ 851 FIELDOF_NORM(krb5_ap_req, encrypted_data, authenticator, 4), 852 }; 853 DEFSEQTYPE(untagged_ap_req, krb5_ap_req, ap_req_fields, 0); 854 DEFAPPTAGGEDTYPE(ap_req, 14, untagged_ap_req); 855 856 static const struct field_info ap_rep_fields[] = { 857 /* AP-REP ::= [APPLICATION 15] SEQUENCE */ 858 /* pvno[0] INTEGER */ 859 FIELD_INT_IMM(KVNO, 0), 860 /* msg-type[1] INTEGER */ 861 FIELD_INT_IMM(ASN1_KRB_AP_REP, 1), 862 /* enc-part[2] EncryptedData */ 863 FIELDOF_NORM(krb5_ap_rep, encrypted_data, enc_part, 2), 864 }; 865 DEFSEQTYPE(untagged_ap_rep, krb5_ap_rep, ap_rep_fields, 0); 866 DEFAPPTAGGEDTYPE(ap_rep, 15, untagged_ap_rep); 867 868 static const struct field_info ap_rep_enc_part_fields[] = { 869 /* EncAPRepPart ::= [APPLICATION 27] SEQUENCE */ 870 /* ctime[0] KerberosTime */ 871 FIELDOF_NORM(krb5_ap_rep_enc_part, kerberos_time, ctime, 0), 872 /* cusec[1] INTEGER */ 873 FIELDOF_NORM(krb5_ap_rep_enc_part, int32, cusec, 1), 874 /* subkey[2] EncryptionKey OPTIONAL */ 875 FIELDOF_OPT(krb5_ap_rep_enc_part, ptr_encryption_key, subkey, 2, 2), 876 /* seq-number[3] INTEGER OPTIONAL */ 877 FIELDOF_OPT(krb5_ap_rep_enc_part, uint, seq_number, 3, 3), 878 }; 879 static unsigned int optional_ap_rep_enc_part(const void *p) 880 { 881 const krb5_ap_rep_enc_part *val = p; 882 unsigned int optional = 0; 883 884 if (val->seq_number) 885 optional |= (1u << 3); 886 if (val->subkey != NULL) 887 optional |= (1u << 2); 888 889 return optional; 890 } 891 DEFSEQTYPE(untagged_ap_rep_enc_part, krb5_ap_rep_enc_part, 892 ap_rep_enc_part_fields, optional_ap_rep_enc_part); 893 DEFAPPTAGGEDTYPE(ap_rep_enc_part, 27, untagged_ap_rep_enc_part); 894 895 static const struct field_info as_req_fields[] = { 896 /* AS-REQ ::= [APPLICATION 10] KDC-REQ */ 897 FIELD_INT_IMM(KVNO, 1), 898 FIELD_INT_IMM(KRB5_AS_REQ, 2), 899 FIELDOF_OPT(krb5_kdc_req, ptr_seqof_pa_data, padata, 3, 3), 900 FIELDOF_ENCODEAS(krb5_kdc_req, kdc_req_body, 4), 901 }; 902 static unsigned int optional_as_req(const void *p) 903 { 904 const krb5_kdc_req *val = p; 905 unsigned int optional = 0; 906 907 if (val->padata != NULL && val->padata[0] != NULL) 908 optional |= (1u << 3); 909 910 return optional; 911 } 912 DEFSEQTYPE(untagged_as_req, krb5_kdc_req, as_req_fields, optional_as_req); 913 DEFAPPTAGGEDTYPE(as_req, 10, untagged_as_req); 914 915 static const struct field_info tgs_req_fields[] = { 916 /* TGS-REQ ::= [APPLICATION 12] KDC-REQ */ 917 FIELD_INT_IMM(KVNO, 1), 918 FIELD_INT_IMM(KRB5_TGS_REQ, 2), 919 FIELDOF_OPT(krb5_kdc_req, ptr_seqof_pa_data, padata, 3, 3), 920 FIELDOF_ENCODEAS(krb5_kdc_req, kdc_req_body, 4), 921 }; 922 static unsigned int optional_tgs_req(const void *p) 923 { 924 const krb5_kdc_req *val = p; 925 unsigned int optional = 0; 926 927 if (val->padata != NULL && val->padata[0] != NULL) 928 optional |= (1u << 3); 929 930 return optional; 931 } 932 DEFSEQTYPE(untagged_tgs_req, krb5_kdc_req, tgs_req_fields, 933 optional_tgs_req); 934 DEFAPPTAGGEDTYPE(tgs_req, 12, untagged_tgs_req); 935 936 static const struct field_info krb5_safe_fields[] = { 937 FIELD_INT_IMM(KVNO, 0), 938 FIELD_INT_IMM(ASN1_KRB_SAFE,1), 939 FIELD_SELF(krb_safe_body, 2), 940 FIELDOF_NORM(krb5_safe, checksum_ptr, checksum, 3), 941 }; 942 DEFSEQTYPE(untagged_krb5_safe, krb5_safe, krb5_safe_fields, 0); 943 DEFAPPTAGGEDTYPE(krb5_safe, 20, untagged_krb5_safe); 944 945 DEFPTRTYPE(krb_saved_safe_body_ptr, opaque_data); 946 DEFFIELDTYPE(krb5_safe_checksum_only, krb5_safe, 947 FIELDOF_NORM(krb5_safe, checksum_ptr, checksum, -1)); 948 DEFPTRTYPE(krb5_safe_checksum_only_ptr, krb5_safe_checksum_only); 949 static const struct field_info krb5_safe_with_body_fields[] = { 950 FIELD_INT_IMM(KVNO, 0), 951 FIELD_INT_IMM(ASN1_KRB_SAFE,1), 952 FIELDOF_NORM(struct krb5_safe_with_body, krb_saved_safe_body_ptr, body, 2), 953 FIELDOF_NORM(struct krb5_safe_with_body, krb5_safe_checksum_only_ptr, safe, 3), 954 }; 955 DEFSEQTYPE(untagged_krb5_safe_with_body, struct krb5_safe_with_body, 956 krb5_safe_with_body_fields, 0); 957 DEFAPPTAGGEDTYPE(krb5_safe_with_body, 20, untagged_krb5_safe_with_body); 958 959 static const struct field_info priv_fields[] = { 960 FIELD_INT_IMM(KVNO, 0), 961 FIELD_INT_IMM(ASN1_KRB_PRIV, 1), 962 FIELDOF_NORM(krb5_priv, encrypted_data, enc_part, 3), 963 }; 964 DEFSEQTYPE(untagged_priv, krb5_priv, priv_fields, 0); 965 DEFAPPTAGGEDTYPE(krb5_priv, 21, untagged_priv); 966 967 static const struct field_info priv_enc_part_fields[] = { 968 FIELDOF_NORM(krb5_priv_enc_part, ostring_data, user_data, 0), 969 FIELDOF_OPT(krb5_priv_enc_part, kerberos_time, timestamp, 1, 1), 970 FIELDOF_OPT(krb5_priv_enc_part, int32, usec, 2, 2), 971 FIELDOF_OPT(krb5_priv_enc_part, uint, seq_number, 3, 3), 972 FIELDOF_NORM(krb5_priv_enc_part, address_ptr, s_address, 4), 973 FIELDOF_OPT(krb5_priv_enc_part, address_ptr, r_address, 5, 5), 974 }; 975 static unsigned int optional_priv_enc_part(const void *p) 976 { 977 const krb5_priv_enc_part *val = p; 978 unsigned int optional = 0; 979 980 if (val->timestamp) { 981 optional |= (1u << 2); 982 optional |= (1u << 1); 983 } 984 if (val->seq_number) 985 optional |= (1u << 3); 986 if (val->r_address) 987 optional |= (1u << 5); 988 989 return optional; 990 } 991 DEFSEQTYPE(untagged_priv_enc_part, krb5_priv_enc_part, priv_enc_part_fields, 992 optional_priv_enc_part); 993 DEFAPPTAGGEDTYPE(priv_enc_part, 28, untagged_priv_enc_part); 994 995 static const struct field_info cred_fields[] = { 996 /* KRB-CRED ::= [APPLICATION 22] SEQUENCE */ 997 /* pvno[0] INTEGER */ 998 FIELD_INT_IMM(KVNO, 0), 999 /* msg-type[1] INTEGER, -- KRB_CRED */ 1000 FIELD_INT_IMM(ASN1_KRB_CRED, 1), 1001 /* tickets[2] SEQUENCE OF Ticket */ 1002 FIELDOF_NORM(krb5_cred, ptr_seqof_ticket, tickets, 2), 1003 /* enc-part[3] EncryptedData */ 1004 FIELDOF_NORM(krb5_cred, encrypted_data, enc_part, 3), 1005 }; 1006 DEFSEQTYPE(untagged_cred, krb5_cred, cred_fields, 0); 1007 DEFAPPTAGGEDTYPE(krb5_cred, 22, untagged_cred); 1008 1009 static const struct field_info enc_cred_part_fields[] = { 1010 /* EncKrbCredPart ::= [APPLICATION 29] SEQUENCE */ 1011 /* ticket-info[0] SEQUENCE OF KrbCredInfo */ 1012 FIELDOF_NORM(krb5_cred_enc_part, ptrseqof_cred_info, ticket_info, 0), 1013 /* nonce[1] INTEGER OPTIONAL */ 1014 FIELDOF_OPT(krb5_cred_enc_part, int32, nonce, 1, 1), 1015 /* timestamp[2] KerberosTime OPTIONAL */ 1016 FIELDOF_OPT(krb5_cred_enc_part, kerberos_time, timestamp, 2, 2), 1017 /* usec[3] INTEGER OPTIONAL */ 1018 FIELDOF_OPT(krb5_cred_enc_part, int32, usec, 3, 3), 1019 /* s-address[4] HostAddress OPTIONAL */ 1020 FIELDOF_OPT(krb5_cred_enc_part, address_ptr, s_address, 4, 4), 1021 /* r-address[5] HostAddress OPTIONAL */ 1022 FIELDOF_OPT(krb5_cred_enc_part, address_ptr, r_address, 5, 5), 1023 }; 1024 static unsigned int optional_enc_cred_part(const void *p) 1025 { 1026 const krb5_cred_enc_part *val = p; 1027 unsigned int optional = 0; 1028 1029 if (val->r_address != NULL) 1030 optional |= (1u << 5); 1031 1032 if (val->s_address != NULL) 1033 optional |= (1u << 4); 1034 1035 if (val->timestamp) { 1036 optional |= (1u << 2); 1037 optional |= (1u << 3); 1038 } 1039 1040 if (val->nonce) 1041 optional |= (1u << 1); 1042 1043 return optional; 1044 } 1045 DEFSEQTYPE(untagged_enc_cred_part, krb5_cred_enc_part, enc_cred_part_fields, 1046 optional_enc_cred_part); 1047 DEFAPPTAGGEDTYPE(enc_cred_part, 29, untagged_enc_cred_part); 1048 1049 static const struct field_info error_fields[] = { 1050 /* KRB-ERROR ::= [APPLICATION 30] SEQUENCE */ 1051 /* pvno[0] INTEGER */ 1052 FIELD_INT_IMM(KVNO, 0), 1053 /* msg-type[1] INTEGER */ 1054 FIELD_INT_IMM(ASN1_KRB_ERROR, 1), 1055 /* ctime[2] KerberosTime OPTIONAL */ 1056 FIELDOF_OPT(krb5_error, kerberos_time, ctime, 2, 2), 1057 /* cusec[3] INTEGER OPTIONAL */ 1058 FIELDOF_OPT(krb5_error, int32, cusec, 3, 3), 1059 /* stime[4] KerberosTime */ 1060 FIELDOF_NORM(krb5_error, kerberos_time, stime, 4), 1061 /* susec[5] INTEGER */ 1062 FIELDOF_NORM(krb5_error, int32, susec, 5), 1063 /* error-code[6] INTEGER */ 1064 FIELDOF_NORM(krb5_error, ui_4, error, 6), 1065 /* crealm[7] Realm OPTIONAL */ 1066 FIELDOF_OPT(krb5_error, realm_of_principal, client, 7, 7), 1067 /* cname[8] PrincipalName OPTIONAL */ 1068 FIELDOF_OPT(krb5_error, principal, client, 8, 8), 1069 /* realm[9] Realm -- Correct realm */ 1070 FIELDOF_NORM(krb5_error, realm_of_principal, server, 9), 1071 /* sname[10] PrincipalName -- Correct name */ 1072 FIELDOF_NORM(krb5_error, principal, server, 10), 1073 /* e-text[11] GeneralString OPTIONAL */ 1074 FIELDOF_OPT(krb5_error, gstring_data, text, 11, 11), 1075 /* e-data[12] OCTET STRING OPTIONAL */ 1076 FIELDOF_OPT(krb5_error, ostring_data, e_data, 12, 12), 1077 }; 1078 static unsigned int optional_error(const void *p) 1079 { 1080 const krb5_error *val = p; 1081 unsigned int optional = 0; 1082 1083 if (val->ctime) 1084 optional |= (1u << 2); 1085 if (val->cusec) 1086 optional |= (1u << 3); 1087 if (val->client) { 1088 optional |= (1u << 7); 1089 optional |= (1u << 8); 1090 } 1091 if (val->text.data != NULL && val->text.length > 0) 1092 optional |= (1u << 11); 1093 if (val->e_data.data != NULL && val->e_data.length > 0) 1094 optional |= (1u << 12); 1095 1096 return optional; 1097 } 1098 DEFSEQTYPE(untagged_krb5_error, krb5_error, error_fields, optional_error); 1099 DEFAPPTAGGEDTYPE(krb5_error, 30, untagged_krb5_error); 1100 1101 static const struct field_info alt_method_fields[] = { 1102 FIELDOF_NORM(krb5_alt_method, int32, method, 0), 1103 FIELDOF_OPTSTRING(krb5_alt_method, octetstring, data, length, 1, 1), 1104 }; 1105 static unsigned int 1106 optional_alt_method(const void *p) 1107 { 1108 const krb5_alt_method *a = p; 1109 unsigned int optional = 0; 1110 1111 if (a->data != NULL && a->length > 0) 1112 optional |= (1u << 1); 1113 1114 return optional; 1115 } 1116 DEFSEQTYPE(alt_method, krb5_alt_method, alt_method_fields, optional_alt_method); 1117 1118 static const struct field_info pa_enc_ts_fields[] = { 1119 FIELDOF_NORM(krb5_pa_enc_ts, kerberos_time, patimestamp, 0), 1120 FIELDOF_OPT(krb5_pa_enc_ts, int32, pausec, 1, 1), 1121 }; 1122 static unsigned int 1123 optional_pa_enc_ts(const void *p) 1124 { 1125 const krb5_pa_enc_ts *val = p; 1126 unsigned int optional = 0; 1127 1128 if (val->pausec) 1129 optional |= (1u << 1); 1130 1131 return optional; 1132 } 1133 DEFSEQTYPE(pa_enc_ts, krb5_pa_enc_ts, pa_enc_ts_fields, optional_pa_enc_ts); 1134 1135 static const struct field_info pwd_data_fields[] = { 1136 FIELDOF_NORM(krb5_pwd_data, int32, sequence_count, 0), 1137 FIELDOF_NORM(krb5_pwd_data, ptr_seqof_passwdsequence, element, 1), 1138 }; 1139 DEFSEQTYPE(pwd_data, krb5_pwd_data, pwd_data_fields, 0); 1140 1141 static const struct field_info setpw_req_fields[] = { 1142 FIELDOF_NORM(struct krb5_setpw_req, ostring_data, password, 0), 1143 FIELDOF_NORM(struct krb5_setpw_req, principal, target, 1), 1144 FIELDOF_NORM(struct krb5_setpw_req, realm_of_principal, target, 2), 1145 }; 1146 1147 DEFSEQTYPE(setpw_req, struct krb5_setpw_req, setpw_req_fields, 0); 1148 1149 /* [MS-SFU] Section 2.2.1. */ 1150 static const struct field_info pa_for_user_fields[] = { 1151 FIELDOF_NORM(krb5_pa_for_user, principal, user, 0), 1152 FIELDOF_NORM(krb5_pa_for_user, realm_of_principal, user, 1), 1153 FIELDOF_NORM(krb5_pa_for_user, checksum, cksum, 2), 1154 FIELDOF_NORM(krb5_pa_for_user, gstring_data, auth_package, 3), 1155 }; 1156 1157 DEFSEQTYPE(pa_for_user, krb5_pa_for_user, pa_for_user_fields, 0); 1158 1159 /* draft-ietf-krb-wg-kerberos-referrals Appendix A. */ 1160 static const struct field_info pa_svr_referral_data_fields[] = { 1161 FIELDOF_NORM(krb5_pa_svr_referral_data, realm_of_principal, principal, 0), 1162 FIELDOF_OPT(krb5_pa_svr_referral_data, principal, principal, 1, 1), 1163 }; 1164 1165 DEFSEQTYPE(pa_svr_referral_data, krb5_pa_svr_referral_data, pa_svr_referral_data_fields, 0); 1166 1167 /* draft-ietf-krb-wg-kerberos-referrals Section 8. */ 1168 static const struct field_info pa_server_referral_data_fields[] = { 1169 FIELDOF_OPT(krb5_pa_server_referral_data, gstring_data_ptr, referred_realm, 0, 0), 1170 FIELDOF_OPT(krb5_pa_server_referral_data, principal, true_principal_name, 1, 1), 1171 FIELDOF_OPT(krb5_pa_server_referral_data, principal, requested_principal_name, 2, 2), 1172 FIELDOF_OPT(krb5_pa_server_referral_data, kerberos_time, referral_valid_until, 3, 3), 1173 FIELDOF_NORM(krb5_pa_server_referral_data, checksum, rep_cksum, 4), 1174 }; 1175 1176 DEFSEQTYPE(pa_server_referral_data, krb5_pa_server_referral_data, pa_server_referral_data_fields, 0); 1177 1178 #if 0 1179 /* draft-brezak-win2k-krb-authz Section 6. */ 1180 static const struct field_info pa_pac_request_fields[] = { 1181 FIELDOF_NORM(krb5_pa_pac_req, boolean, include_pac, 0), 1182 }; 1183 1184 DEFSEQTYPE(pa_pac_request, krb5_pa_pac_req, pa_pac_request_fields, 0); 1185 #endif 1186 1187 /* RFC 4537 */ 1188 DEFFIELDTYPE(etype_list, krb5_etype_list, 1189 FIELDOF_SEQOF_INT32(krb5_etype_list, int32_ptr, etypes, length, -1)); 1190 1191 /* draft-ietf-krb-wg-preauth-framework-09 */ 1192 static const struct field_info fast_armor_fields[] = { 1193 FIELDOF_NORM(krb5_fast_armor, int32, armor_type, 0), 1194 FIELDOF_NORM( krb5_fast_armor, ostring_data, armor_value, 1), 1195 }; 1196 1197 DEFSEQTYPE( fast_armor, krb5_fast_armor, fast_armor_fields, 0); 1198 DEFPTRTYPE( ptr_fast_armor, fast_armor); 1199 1200 static const struct field_info fast_armored_req_fields[] = { 1201 FIELDOF_OPT( krb5_fast_armored_req, ptr_fast_armor, armor, 0, 0), 1202 FIELDOF_NORM( krb5_fast_armored_req, checksum, req_checksum, 1), 1203 FIELDOF_NORM( krb5_fast_armored_req, encrypted_data, enc_part, 2), 1204 }; 1205 1206 static unsigned int fast_armored_req_optional (const void *p) { 1207 const krb5_fast_armored_req *val = p; 1208 unsigned int optional = 0; 1209 if (val->armor) 1210 optional |= (1u)<<0; 1211 return optional; 1212 } 1213 1214 DEFSEQTYPE( fast_armored_req, krb5_fast_armored_req, fast_armored_req_fields, fast_armored_req_optional); 1215 DEFFIELDTYPE( pa_fx_fast_request, krb5_fast_armored_req, 1216 FIELDOF_ENCODEAS( krb5_fast_armored_req, fast_armored_req, 0)); 1217 1218 DEFFIELDTYPE(fast_req_padata, krb5_kdc_req, 1219 FIELDOF_NORM(krb5_kdc_req, ptr_seqof_pa_data, padata, -1)); 1220 DEFPTRTYPE(ptr_fast_req_padata, fast_req_padata); 1221 1222 static const struct field_info fast_req_fields[] = { 1223 FIELDOF_NORM(krb5_fast_req, krb5_flags, fast_options, 0), 1224 FIELDOF_NORM( krb5_fast_req, ptr_fast_req_padata, req_body, 1), 1225 FIELDOF_NORM( krb5_fast_req, ptr_kdc_req_body, req_body, 2), 1226 }; 1227 1228 DEFSEQTYPE(fast_req, krb5_fast_req, fast_req_fields, 0); 1229 1230 1231 static const struct field_info fast_finished_fields[] = { 1232 FIELDOF_NORM( krb5_fast_finished, kerberos_time, timestamp, 0), 1233 FIELDOF_NORM( krb5_fast_finished, int32, usec, 1), 1234 FIELDOF_NORM( krb5_fast_finished, realm_of_principal, client, 2), 1235 FIELDOF_NORM(krb5_fast_finished, principal, client, 3), 1236 FIELDOF_NORM( krb5_fast_finished, checksum, ticket_checksum, 4), 1237 }; 1238 1239 DEFSEQTYPE( fast_finished, krb5_fast_finished, fast_finished_fields, 0); 1240 1241 DEFPTRTYPE( ptr_fast_finished, fast_finished); 1242 1243 static const struct field_info fast_response_fields[] = { 1244 FIELDOF_NORM(krb5_fast_response, ptr_seqof_pa_data, padata, 0), 1245 FIELDOF_OPT( krb5_fast_response, ptr_encryption_key, strengthen_key, 1, 1), 1246 FIELDOF_OPT( krb5_fast_response, ptr_fast_finished, finished, 2, 2), 1247 FIELDOF_NORM(krb5_fast_response, int32, nonce, 3), 1248 }; 1249 1250 static unsigned int fast_response_optional (const void *p) 1251 { 1252 unsigned int optional = 0; 1253 const krb5_fast_response *val = p; 1254 if (val->strengthen_key) 1255 optional |= (1u <<1); 1256 if (val->finished) 1257 optional |= (1u<<2); 1258 return optional; 1259 } 1260 DEFSEQTYPE( fast_response, krb5_fast_response, fast_response_fields, fast_response_optional); 1261 1262 static const struct field_info fast_rep_fields[] = { 1263 FIELDOF_ENCODEAS(krb5_enc_data, encrypted_data, 0), 1264 }; 1265 DEFSEQTYPE(fast_rep, krb5_enc_data, fast_rep_fields, 0); 1266 1267 DEFFIELDTYPE(pa_fx_fast_reply, krb5_enc_data, 1268 FIELDOF_ENCODEAS(krb5_enc_data, fast_rep, 0)); 1269 1270 1271 1272 1273 /* Exported complete encoders -- these produce a krb5_data with 1274 the encoding in the correct byte order. */ 1275 1276 MAKE_FULL_ENCODER(encode_krb5_authenticator, krb5_authenticator); 1277 MAKE_FULL_ENCODER(encode_krb5_ticket, ticket); 1278 MAKE_FULL_ENCODER(encode_krb5_encryption_key, encryption_key); 1279 MAKE_FULL_ENCODER(encode_krb5_enc_tkt_part, enc_tkt_part); 1280 /* XXX We currently (for backwards compatibility) encode both 1281 EncASRepPart and EncTGSRepPart with application tag 26. */ 1282 MAKE_FULL_ENCODER(encode_krb5_enc_kdc_rep_part, enc_tgs_rep_part); 1283 MAKE_FULL_ENCODER(encode_krb5_as_rep, as_rep); 1284 MAKE_FULL_ENCODER(encode_krb5_tgs_rep, tgs_rep); 1285 MAKE_FULL_ENCODER(encode_krb5_ap_req, ap_req); 1286 MAKE_FULL_ENCODER(encode_krb5_ap_rep, ap_rep); 1287 MAKE_FULL_ENCODER(encode_krb5_ap_rep_enc_part, ap_rep_enc_part); 1288 MAKE_FULL_ENCODER(encode_krb5_as_req, as_req); 1289 MAKE_FULL_ENCODER(encode_krb5_tgs_req, tgs_req); 1290 MAKE_FULL_ENCODER(encode_krb5_kdc_req_body, kdc_req_body); 1291 MAKE_FULL_ENCODER(encode_krb5_safe, krb5_safe); 1292 1293 /* 1294 * encode_krb5_safe_with_body 1295 * 1296 * Like encode_krb5_safe(), except takes a saved KRB-SAFE-BODY 1297 * encoding to avoid problems with re-encoding. 1298 */ 1299 MAKE_FULL_ENCODER(encode_krb5_safe_with_body, krb5_safe_with_body); 1300 1301 MAKE_FULL_ENCODER(encode_krb5_priv, krb5_priv); 1302 MAKE_FULL_ENCODER(encode_krb5_enc_priv_part, priv_enc_part); 1303 MAKE_FULL_ENCODER(encode_krb5_cred, krb5_cred); 1304 MAKE_FULL_ENCODER(encode_krb5_enc_cred_part, enc_cred_part); 1305 MAKE_FULL_ENCODER(encode_krb5_error, krb5_error); 1306 MAKE_FULL_ENCODER(encode_krb5_authdata, auth_data); 1307 MAKE_FULL_ENCODER(encode_krb5_authdata_elt, authdata_elt); 1308 MAKE_FULL_ENCODER(encode_krb5_alt_method, alt_method); 1309 MAKE_FULL_ENCODER(encode_krb5_etype_info, etype_info); 1310 MAKE_FULL_ENCODER(encode_krb5_etype_info2, etype_info2); 1311 MAKE_FULL_ENCODER(encode_krb5_enc_data, encrypted_data); 1312 MAKE_FULL_ENCODER(encode_krb5_pa_enc_ts, pa_enc_ts); 1313 /* Sandia Additions */ 1314 MAKE_FULL_ENCODER(encode_krb5_pwd_sequence, passwdsequence); 1315 MAKE_FULL_ENCODER(encode_krb5_pwd_data, pwd_data); 1316 MAKE_FULL_ENCODER(encode_krb5_padata_sequence, seq_of_pa_data); 1317 /* sam preauth additions */ 1318 MAKE_FULL_ENCODER(encode_krb5_sam_challenge, sam_challenge); 1319 #if 0 /* encoders not used! */ 1320 MAKE_FULL_ENCODER(encode_krb5_sam_challenge_2, sam_challenge_2); 1321 MAKE_FULL_ENCODER(encode_krb5_sam_challenge_2_body, 1322 sam_challenge_2_body); 1323 #endif 1324 MAKE_FULL_ENCODER(encode_krb5_sam_key, sam_key); 1325 MAKE_FULL_ENCODER(encode_krb5_enc_sam_response_enc, 1326 enc_sam_response_enc); 1327 MAKE_FULL_ENCODER(encode_krb5_enc_sam_response_enc_2, 1328 enc_sam_response_enc_2); 1329 MAKE_FULL_ENCODER(encode_krb5_sam_response, sam_response); 1330 MAKE_FULL_ENCODER(encode_krb5_sam_response_2, sam_response_2); 1331 MAKE_FULL_ENCODER(encode_krb5_predicted_sam_response, 1332 predicted_sam_response); 1333 MAKE_FULL_ENCODER(encode_krb5_setpw_req, setpw_req); 1334 MAKE_FULL_ENCODER(encode_krb5_pa_for_user, pa_for_user); 1335 MAKE_FULL_ENCODER(encode_krb5_pa_svr_referral_data, pa_svr_referral_data); 1336 MAKE_FULL_ENCODER(encode_krb5_pa_server_referral_data, pa_server_referral_data); 1337 MAKE_FULL_ENCODER(encode_krb5_etype_list, etype_list); 1338 1339 MAKE_FULL_ENCODER(encode_krb5_pa_fx_fast_request, pa_fx_fast_request); 1340 MAKE_FULL_ENCODER( encode_krb5_fast_req, fast_req); 1341 MAKE_FULL_ENCODER( encode_krb5_pa_fx_fast_reply, pa_fx_fast_reply); 1342 MAKE_FULL_ENCODER(encode_krb5_fast_response, fast_response); 1343 1344 1345 1346 1347 1348 1349 /* 1350 * PKINIT 1351 */ 1352 1353 /* This code hasn't been converted to use the above framework yet, 1354 because we currently have no test cases to validate the new 1355 version. It *also* appears that some of the encodings may disagree 1356 with the specifications, but that's a separate problem. */ 1357 1358 /**** asn1 macros ****/ 1359 #if 0 1360 How to write an asn1 encoder function using these macros: 1361 1362 asn1_error_code asn1_encode_krb5_substructure(asn1buf *buf, 1363 const krb5_type *val, 1364 int *retlen) 1365 { 1366 asn1_setup(); 1367 1368 asn1_addfield(val->last_field, n, asn1_type); 1369 asn1_addfield(rep->next_to_last_field, n-1, asn1_type); 1370 ... 1371 1372 /* for OPTIONAL fields */ 1373 if (rep->field_i == should_not_be_omitted) 1374 asn1_addfield(rep->field_i, i, asn1_type); 1375 1376 /* for string fields (these encoders take an additional argument, 1377 the length of the string) */ 1378 addlenfield(rep->field_length, rep->field, i-1, asn1_type); 1379 1380 /* if you really have to do things yourself... */ 1381 retval = asn1_encode_asn1_type(buf,rep->field,&length); 1382 if (retval) return retval; 1383 sum += length; 1384 retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, tag_number, length, 1385 &length); 1386 if (retval) return retval; 1387 sum += length; 1388 1389 ... 1390 asn1_addfield(rep->second_field, 1, asn1_type); 1391 asn1_addfield(rep->first_field, 0, asn1_type); 1392 asn1_makeseq(); 1393 1394 asn1_cleanup(); 1395 } 1396 #endif 1397 1398 /* asn1_addlenfield -- add a field whose length must be separately specified */ 1399 #define asn1_addlenfield(len,value,tag,encoder)\ 1400 { unsigned int length; \ 1401 retval = encoder(buf,len,value,&length); \ 1402 if (retval) {\ 1403 return retval; }\ 1404 sum += length;\ 1405 retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\ 1406 if (retval) {\ 1407 return retval; }\ 1408 sum += length; } 1409 1410 /* asn1_addfield_implicit -- add an implicitly tagged field, or component, to the encoding */ 1411 #define asn1_addfield_implicit(value,tag,encoder)\ 1412 { unsigned int length;\ 1413 retval = encoder(buf,value,&length);\ 1414 if (retval) {\ 1415 return retval; }\ 1416 sum += length;\ 1417 retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,length,&length); \ 1418 if (retval) {\ 1419 return retval; }\ 1420 sum += length; } 1421 1422 /* asn1_insert_implicit_octetstring -- add an octet string with implicit tagging */ 1423 #define asn1_insert_implicit_octetstring(len,value,tag)\ 1424 { unsigned int length;\ 1425 retval = asn1buf_insert_octetstring(buf,len,value);\ 1426 if (retval) {\ 1427 return retval; }\ 1428 sum += len;\ 1429 retval = asn1_make_tag(buf,CONTEXT_SPECIFIC,PRIMITIVE,tag,len,&length); \ 1430 if (retval) {\ 1431 return retval; }\ 1432 sum += length; } 1433 1434 /* asn1_insert_implicit_bitstring -- add a bitstring with implicit tagging */ 1435 /* needs "length" declared in enclosing context */ 1436 #define asn1_insert_implicit_bitstring(len,value,tag)\ 1437 { retval = asn1buf_insert_octetstring(buf,len,value); \ 1438 if (retval) {\ 1439 return retval; }\ 1440 sum += len;\ 1441 retval = asn1buf_insert_octet(buf, 0);\ 1442 if (retval) {\ 1443 return retval; }\ 1444 sum++;\ 1445 retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,tag,len+1,&length); \ 1446 if (retval) {\ 1447 return retval; }\ 1448 sum += length; } 1449 1450 #ifndef DISABLE_PKINIT 1451 1452 /* Callable encoders for the types defined above, until the PKINIT 1453 encoders get converted. */ 1454 MAKE_ENCFN(asn1_encode_realm, realm_of_principal_data); 1455 MAKE_ENCFN(asn1_encode_principal_name, principal_data); 1456 MAKE_ENCFN(asn1_encode_encryption_key, encryption_key); 1457 MAKE_ENCFN(asn1_encode_checksum, checksum); 1458 1459 static asn1_error_code 1460 asn1_encode_kerberos_time(asn1buf *buf, const krb5_timestamp val, 1461 unsigned int *retlen) 1462 { 1463 return asn1_encode_kerberos_time_at(buf,&val,retlen); 1464 } 1465 1466 /* Now the real PKINIT encoder functions. */ 1467 asn1_error_code asn1_encode_pk_authenticator(asn1buf *buf, const krb5_pk_authenticator *val, unsigned int *retlen) 1468 { 1469 asn1_setup(); 1470 asn1_addlenfield(val->paChecksum.length, val->paChecksum.contents, 3, asn1_encode_octetstring); 1471 asn1_addfield(val->nonce, 2, asn1_encode_integer); 1472 asn1_addfield(val->ctime, 1, asn1_encode_kerberos_time); 1473 asn1_addfield(val->cusec, 0, asn1_encode_integer); 1474 1475 asn1_makeseq(); 1476 asn1_cleanup(); 1477 } 1478 1479 asn1_error_code asn1_encode_pk_authenticator_draft9(asn1buf *buf, const krb5_pk_authenticator_draft9 *val, unsigned int *retlen) 1480 { 1481 asn1_setup(); 1482 1483 asn1_addfield(val->nonce, 4, asn1_encode_integer); 1484 asn1_addfield(val->ctime, 3, asn1_encode_kerberos_time); 1485 asn1_addfield(val->cusec, 2, asn1_encode_integer); 1486 asn1_addfield(val->kdcName, 1, asn1_encode_realm); 1487 asn1_addfield(val->kdcName, 0, asn1_encode_principal_name); 1488 1489 asn1_makeseq(); 1490 asn1_cleanup(); 1491 } 1492 1493 1494 asn1_error_code asn1_encode_algorithm_identifier(asn1buf *buf, const krb5_algorithm_identifier *val, unsigned int *retlen) 1495 { 1496 asn1_setup(); 1497 1498 if (val->parameters.length != 0) { 1499 retval = asn1buf_insert_octetstring(buf, val->parameters.length, 1500 val->parameters.data); 1501 if (retval) 1502 return retval; 1503 sum += val->parameters.length; 1504 } 1505 1506 { 1507 unsigned int length; 1508 retval = asn1_encode_oid(buf, val->algorithm.length, 1509 val->algorithm.data, 1510 &length); 1511 1512 if (retval) 1513 return retval; 1514 sum += length; 1515 } 1516 1517 asn1_makeseq(); 1518 asn1_cleanup(); 1519 } 1520 1521 asn1_error_code asn1_encode_subject_pk_info(asn1buf *buf, const krb5_subject_pk_info *val, unsigned int *retlen) 1522 { 1523 asn1_setup(); 1524 1525 { 1526 unsigned int length; 1527 asn1_insert_implicit_bitstring(val->subjectPublicKey.length,val->subjectPublicKey.data,ASN1_BITSTRING); 1528 } 1529 1530 if (val->algorithm.parameters.length != 0) { 1531 unsigned int length; 1532 1533 retval = asn1buf_insert_octetstring(buf, val->algorithm.parameters.length, 1534 val->algorithm.parameters.data); 1535 if (retval) 1536 return retval; 1537 sum += val->algorithm.parameters.length; 1538 1539 retval = asn1_encode_oid(buf, val->algorithm.algorithm.length, 1540 val->algorithm.algorithm.data, 1541 &length); 1542 1543 if (retval) 1544 return retval; 1545 sum += length; 1546 1547 1548 retval = asn1_make_etag(buf, UNIVERSAL, ASN1_SEQUENCE, 1549 val->algorithm.parameters.length + length, 1550 &length); 1551 1552 if (retval) 1553 return retval; 1554 sum += length; 1555 } 1556 1557 asn1_makeseq(); 1558 asn1_cleanup(); 1559 } 1560 1561 asn1_error_code asn1_encode_sequence_of_algorithm_identifier(asn1buf *buf, const krb5_algorithm_identifier **val, unsigned int *retlen) 1562 { 1563 asn1_setup(); 1564 int i; 1565 1566 if (val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 1567 1568 for (i=0; val[i] != NULL; i++); 1569 for (i--; i>=0; i--) { 1570 unsigned int length; 1571 retval = asn1_encode_algorithm_identifier(buf,val[i],&length); 1572 if (retval) return retval; 1573 sum += length; 1574 } 1575 asn1_makeseq(); 1576 1577 asn1_cleanup(); 1578 } 1579 1580 asn1_error_code asn1_encode_auth_pack(asn1buf *buf, const krb5_auth_pack *val, unsigned int *retlen) 1581 { 1582 asn1_setup(); 1583 1584 if (val->clientDHNonce.length != 0) 1585 asn1_addlenfield(val->clientDHNonce.length, val->clientDHNonce.data, 3, asn1_encode_octetstring); 1586 if (val->supportedCMSTypes != NULL) 1587 asn1_addfield((const krb5_algorithm_identifier **)val->supportedCMSTypes,2,asn1_encode_sequence_of_algorithm_identifier); 1588 if (val->clientPublicValue != NULL) 1589 asn1_addfield(val->clientPublicValue,1,asn1_encode_subject_pk_info); 1590 asn1_addfield(&(val->pkAuthenticator),0,asn1_encode_pk_authenticator); 1591 1592 asn1_makeseq(); 1593 asn1_cleanup(); 1594 } 1595 1596 asn1_error_code asn1_encode_auth_pack_draft9(asn1buf *buf, const krb5_auth_pack_draft9 *val, unsigned int *retlen) 1597 { 1598 asn1_setup(); 1599 1600 if (val->clientPublicValue != NULL) 1601 asn1_addfield(val->clientPublicValue, 1, asn1_encode_subject_pk_info); 1602 asn1_addfield(&(val->pkAuthenticator), 0, asn1_encode_pk_authenticator_draft9); 1603 1604 asn1_makeseq(); 1605 asn1_cleanup(); 1606 } 1607 1608 asn1_error_code asn1_encode_external_principal_identifier(asn1buf *buf, const krb5_external_principal_identifier *val, unsigned int *retlen) 1609 { 1610 asn1_setup(); 1611 1612 /* Verify there is something to encode */ 1613 if (val->subjectKeyIdentifier.length == 0 && val->issuerAndSerialNumber.length == 0 && val->subjectName.length == 0) 1614 return ASN1_MISSING_FIELD; 1615 1616 if (val->subjectKeyIdentifier.length != 0) 1617 asn1_insert_implicit_octetstring(val->subjectKeyIdentifier.length,val->subjectKeyIdentifier.data,2); 1618 1619 if (val->issuerAndSerialNumber.length != 0) 1620 asn1_insert_implicit_octetstring(val->issuerAndSerialNumber.length,val->issuerAndSerialNumber.data,1); 1621 1622 if (val->subjectName.length != 0) 1623 asn1_insert_implicit_octetstring(val->subjectName.length,val->subjectName.data,0); 1624 1625 asn1_makeseq(); 1626 asn1_cleanup(); 1627 } 1628 1629 asn1_error_code asn1_encode_sequence_of_external_principal_identifier(asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen) 1630 { 1631 asn1_setup(); 1632 int i; 1633 1634 if (val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 1635 1636 for (i=0; val[i] != NULL; i++); 1637 for (i--; i>=0; i--) { 1638 unsigned int length; 1639 retval = asn1_encode_external_principal_identifier(buf,val[i],&length); 1640 if (retval) return retval; 1641 sum += length; 1642 } 1643 asn1_makeseq(); 1644 1645 asn1_cleanup(); 1646 } 1647 1648 asn1_error_code asn1_encode_pa_pk_as_req(asn1buf *buf, const krb5_pa_pk_as_req *val, unsigned int *retlen) 1649 { 1650 asn1_setup(); 1651 1652 if (val->kdcPkId.length != 0) 1653 asn1_insert_implicit_octetstring(val->kdcPkId.length,val->kdcPkId.data,2); 1654 1655 if (val->trustedCertifiers != NULL) 1656 asn1_addfield((const krb5_external_principal_identifier **)val->trustedCertifiers,1,asn1_encode_sequence_of_external_principal_identifier); 1657 1658 asn1_insert_implicit_octetstring(val->signedAuthPack.length,val->signedAuthPack.data,0); 1659 1660 asn1_makeseq(); 1661 asn1_cleanup(); 1662 } 1663 1664 asn1_error_code asn1_encode_trusted_ca(asn1buf *buf, const krb5_trusted_ca *val, unsigned int *retlen) 1665 { 1666 asn1_setup(); 1667 1668 switch (val->choice) { 1669 case choice_trusted_cas_issuerAndSerial: 1670 asn1_insert_implicit_octetstring(val->u.issuerAndSerial.length,val->u.issuerAndSerial.data,2); 1671 break; 1672 case choice_trusted_cas_caName: 1673 asn1_insert_implicit_octetstring(val->u.caName.length,val->u.caName.data,1); 1674 break; 1675 case choice_trusted_cas_principalName: 1676 asn1_addfield_implicit(val->u.principalName,0,asn1_encode_principal_name); 1677 break; 1678 default: 1679 return ASN1_MISSING_FIELD; 1680 } 1681 1682 asn1_cleanup(); 1683 } 1684 1685 asn1_error_code asn1_encode_sequence_of_trusted_ca(asn1buf *buf, const krb5_trusted_ca **val, unsigned int *retlen) 1686 { 1687 asn1_setup(); 1688 int i; 1689 1690 if (val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 1691 1692 for (i=0; val[i] != NULL; i++); 1693 for (i--; i>=0; i--) { 1694 unsigned int length; 1695 retval = asn1_encode_trusted_ca(buf,val[i],&length); 1696 if (retval) return retval; 1697 sum += length; 1698 } 1699 asn1_makeseq(); 1700 asn1_cleanup(); 1701 } 1702 1703 asn1_error_code asn1_encode_pa_pk_as_req_draft9(asn1buf *buf, const krb5_pa_pk_as_req_draft9 *val, unsigned int *retlen) 1704 { 1705 asn1_setup(); 1706 1707 if (val->encryptionCert.length != 0) 1708 asn1_insert_implicit_octetstring(val->encryptionCert.length,val->encryptionCert.data,3); 1709 1710 if (val->kdcCert.length != 0) 1711 asn1_insert_implicit_octetstring(val->kdcCert.length,val->kdcCert.data,2); 1712 1713 if (val->trustedCertifiers != NULL) 1714 asn1_addfield((const krb5_trusted_ca **)val->trustedCertifiers,1,asn1_encode_sequence_of_trusted_ca); 1715 1716 asn1_insert_implicit_octetstring(val->signedAuthPack.length,val->signedAuthPack.data,0); 1717 1718 asn1_makeseq(); 1719 asn1_cleanup(); 1720 } 1721 1722 asn1_error_code asn1_encode_dh_rep_info(asn1buf *buf, const krb5_dh_rep_info *val, unsigned int *retlen) 1723 { 1724 asn1_setup(); 1725 1726 if (val->serverDHNonce.length != 0) 1727 asn1_insert_implicit_octetstring(val->serverDHNonce.length,val->serverDHNonce.data,1); 1728 1729 asn1_insert_implicit_octetstring(val->dhSignedData.length,val->dhSignedData.data,0); 1730 1731 asn1_makeseq(); 1732 asn1_cleanup(); 1733 } 1734 1735 asn1_error_code asn1_encode_kdc_dh_key_info(asn1buf *buf, const krb5_kdc_dh_key_info *val, unsigned int *retlen) 1736 { 1737 asn1_setup(); 1738 1739 if (val->dhKeyExpiration != 0) 1740 asn1_addfield(val->dhKeyExpiration, 2, asn1_encode_kerberos_time); 1741 asn1_addfield(val->nonce, 1, asn1_encode_integer); 1742 1743 { 1744 unsigned int length; 1745 1746 asn1_insert_implicit_bitstring(val->subjectPublicKey.length,val->subjectPublicKey.data,3); 1747 retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, 0, 1748 val->subjectPublicKey.length + 1 + length, 1749 &length); 1750 if (retval) 1751 return retval; 1752 sum += length; 1753 } 1754 1755 asn1_makeseq(); 1756 asn1_cleanup(); 1757 } 1758 1759 asn1_error_code asn1_encode_reply_key_pack(asn1buf *buf, const krb5_reply_key_pack *val, unsigned int *retlen) 1760 { 1761 asn1_setup(); 1762 1763 asn1_addfield(&(val->asChecksum), 1, asn1_encode_checksum); 1764 asn1_addfield(&(val->replyKey), 0, asn1_encode_encryption_key); 1765 1766 asn1_makeseq(); 1767 asn1_cleanup(); 1768 } 1769 1770 asn1_error_code asn1_encode_reply_key_pack_draft9(asn1buf *buf, const krb5_reply_key_pack_draft9 *val, unsigned int *retlen) 1771 { 1772 asn1_setup(); 1773 1774 asn1_addfield(val->nonce, 1, asn1_encode_integer); 1775 asn1_addfield(&(val->replyKey), 0, asn1_encode_encryption_key); 1776 1777 asn1_makeseq(); 1778 asn1_cleanup(); 1779 } 1780 1781 asn1_error_code asn1_encode_pa_pk_as_rep(asn1buf *buf, const krb5_pa_pk_as_rep *val, unsigned int *retlen) 1782 { 1783 asn1_setup(); 1784 1785 switch (val->choice) 1786 { 1787 case choice_pa_pk_as_rep_dhInfo: 1788 asn1_addfield(&(val->u.dh_Info), choice_pa_pk_as_rep_dhInfo, asn1_encode_dh_rep_info); 1789 break; 1790 case choice_pa_pk_as_rep_encKeyPack: 1791 asn1_insert_implicit_octetstring(val->u.encKeyPack.length,val->u.encKeyPack.data,1); 1792 break; 1793 default: 1794 return ASN1_MISSING_FIELD; 1795 } 1796 1797 asn1_cleanup(); 1798 } 1799 1800 asn1_error_code asn1_encode_pa_pk_as_rep_draft9(asn1buf *buf, const krb5_pa_pk_as_rep_draft9 *val, unsigned int *retlen) 1801 { 1802 asn1_setup(); 1803 1804 switch (val->choice) 1805 { 1806 case choice_pa_pk_as_rep_draft9_dhSignedData: 1807 asn1_insert_implicit_octetstring(val->u.dhSignedData.length,val->u.dhSignedData.data,0); 1808 break; 1809 case choice_pa_pk_as_rep_encKeyPack: 1810 asn1_insert_implicit_octetstring(val->u.encKeyPack.length,val->u.encKeyPack.data,1); 1811 break; 1812 default: 1813 return ASN1_MISSING_FIELD; 1814 } 1815 1816 asn1_cleanup(); 1817 } 1818 1819 asn1_error_code asn1_encode_td_trusted_certifiers(asn1buf *buf, const krb5_external_principal_identifier **val, unsigned int *retlen) 1820 { 1821 asn1_setup(); 1822 { 1823 unsigned int length; 1824 retval = asn1_encode_sequence_of_external_principal_identifier(buf, val, &length); 1825 if (retval) 1826 return retval; 1827 /* length set but ignored? sum not updated? */ 1828 } 1829 asn1_cleanup(); 1830 } 1831 1832 #endif /* DISABLE_PKINIT */ 1833 1834 asn1_error_code asn1_encode_sequence_of_typed_data(asn1buf *buf, const krb5_typed_data **val, unsigned int *retlen) 1835 { 1836 asn1_setup(); 1837 int i; 1838 1839 if (val == NULL || val[0] == NULL) return ASN1_MISSING_FIELD; 1840 1841 for (i=0; val[i] != NULL; i++); 1842 for (i--; i>=0; i--) { 1843 unsigned int length; 1844 1845 retval = asn1_encode_typed_data(buf,val[i],&length); 1846 if (retval) return retval; 1847 sum += length; 1848 } 1849 asn1_makeseq(); 1850 1851 asn1_cleanup(); 1852 } 1853 1854 asn1_error_code asn1_encode_typed_data(asn1buf *buf, const krb5_typed_data *val, unsigned int *retlen) 1855 { 1856 asn1_setup(); 1857 asn1_addlenfield(val->length, val->data, 1, asn1_encode_octetstring); 1858 asn1_addfield(val->type, 0, asn1_encode_integer); 1859 asn1_makeseq(); 1860 asn1_cleanup(); 1861 } 1862