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
asn1_encode_kerberos_time_at(asn1buf * buf,const krb5_timestamp * val,unsigned int * retlen)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
optional_encrypted_data(const void * vptr)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
asn1_encode_krb5_flags_at(asn1buf * buf,const krb5_flags * val,unsigned int * retlen)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 };
optional_enc_kdc_rep_part(const void * p)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 };
optional_kdc_req_hack(const void * p)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
asn1_encode_kdc_req_body(asn1buf * buf,const krb5_kdc_req * val,unsigned int * retlen)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 };
optional_krb_safe_body(const void * p)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 };
optional_krb_cred_info(const void * p)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
optional_etype_info_entry(const void * vptr)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
optional_etype_info2_entry(const void * vptr)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 };
optional_sam_challenge(const void * p)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 };
optional_enc_sam_response_enc(const void * p)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 };
optional_enc_sam_response_enc_2(const void * p)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 };
optional_sam_response(const void * p)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 };
optional_sam_response_2(const void * p)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 };
optional_predicted_sam_response(const void * p)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 };
optional_krb5_authenticator(const void * p)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 };
optional_enc_tkt_part(const void * p)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 };
optional_as_rep(const void * p)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 };
optional_tgs_rep(const void * p)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 };
optional_ap_rep_enc_part(const void * p)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 };
optional_as_req(const void * p)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 };
optional_tgs_req(const void * p)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 };
optional_priv_enc_part(const void * p)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 };
optional_enc_cred_part(const void * p)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 };
optional_error(const void * p)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
optional_alt_method(const void * p)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
optional_pa_enc_ts(const void * p)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
fast_armored_req_optional(const void * p)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
fast_response_optional(const void * p)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
asn1_encode_kerberos_time(asn1buf * buf,const krb5_timestamp val,unsigned int * retlen)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. */
asn1_encode_pk_authenticator(asn1buf * buf,const krb5_pk_authenticator * val,unsigned int * retlen)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
asn1_encode_pk_authenticator_draft9(asn1buf * buf,const krb5_pk_authenticator_draft9 * val,unsigned int * retlen)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
asn1_encode_algorithm_identifier(asn1buf * buf,const krb5_algorithm_identifier * val,unsigned int * retlen)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
asn1_encode_subject_pk_info(asn1buf * buf,const krb5_subject_pk_info * val,unsigned int * retlen)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
asn1_encode_sequence_of_algorithm_identifier(asn1buf * buf,const krb5_algorithm_identifier ** val,unsigned int * retlen)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
asn1_encode_auth_pack(asn1buf * buf,const krb5_auth_pack * val,unsigned int * retlen)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
asn1_encode_auth_pack_draft9(asn1buf * buf,const krb5_auth_pack_draft9 * val,unsigned int * retlen)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
asn1_encode_external_principal_identifier(asn1buf * buf,const krb5_external_principal_identifier * val,unsigned int * retlen)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
asn1_encode_sequence_of_external_principal_identifier(asn1buf * buf,const krb5_external_principal_identifier ** val,unsigned int * retlen)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
asn1_encode_pa_pk_as_req(asn1buf * buf,const krb5_pa_pk_as_req * val,unsigned int * retlen)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
asn1_encode_trusted_ca(asn1buf * buf,const krb5_trusted_ca * val,unsigned int * retlen)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
asn1_encode_sequence_of_trusted_ca(asn1buf * buf,const krb5_trusted_ca ** val,unsigned int * retlen)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
asn1_encode_pa_pk_as_req_draft9(asn1buf * buf,const krb5_pa_pk_as_req_draft9 * val,unsigned int * retlen)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
asn1_encode_dh_rep_info(asn1buf * buf,const krb5_dh_rep_info * val,unsigned int * retlen)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
asn1_encode_kdc_dh_key_info(asn1buf * buf,const krb5_kdc_dh_key_info * val,unsigned int * retlen)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
asn1_encode_reply_key_pack(asn1buf * buf,const krb5_reply_key_pack * val,unsigned int * retlen)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
asn1_encode_reply_key_pack_draft9(asn1buf * buf,const krb5_reply_key_pack_draft9 * val,unsigned int * retlen)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
asn1_encode_pa_pk_as_rep(asn1buf * buf,const krb5_pa_pk_as_rep * val,unsigned int * retlen)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
asn1_encode_pa_pk_as_rep_draft9(asn1buf * buf,const krb5_pa_pk_as_rep_draft9 * val,unsigned int * retlen)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
asn1_encode_td_trusted_certifiers(asn1buf * buf,const krb5_external_principal_identifier ** val,unsigned int * retlen)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
asn1_encode_sequence_of_typed_data(asn1buf * buf,const krb5_typed_data ** val,unsigned int * retlen)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
asn1_encode_typed_data(asn1buf * buf,const krb5_typed_data * val,unsigned int * retlen)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