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