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