~ubuntu-branches/ubuntu/maverick/krb5/maverick

« back to all changes in this revision

Viewing changes to src/lib/krb5/asn.1/asn1_k_decode.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman
  • Date: 2009-05-07 16:16:34 UTC
  • mfrom: (13.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20090507161634-xqyk0s9na0le4flj
Tags: 1.7dfsg~beta1-4
When  decrypting the TGS response fails with the subkey, try with the
session key to work around Heimdal bug, Closes: #527353 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c; indent-tabs-mode: nil -*- */
1
2
/*
2
3
 * src/lib/krb5/asn.1/asn1_k_decode.c
3
 
 * 
4
 
 * Copyright 1994 by the Massachusetts Institute of Technology.
 
4
 *
 
5
 * Copyright 1994, 2007, 2008 by the Massachusetts Institute of Technology.
5
6
 * All Rights Reserved.
6
7
 *
7
8
 * Export of this software from the United States of America may
8
9
 *   require a specific license from the United States Government.
9
10
 *   It is the responsibility of any person or organization contemplating
10
11
 *   export to obtain such a license before exporting.
11
 
 * 
 
12
 *
12
13
 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13
14
 * distribute this software and its documentation for any purpose and
14
15
 * without fee is hereby granted, provided that the above copyright
29
30
#include "asn1_get.h"
30
31
#include "asn1_misc.h"
31
32
 
 
33
#define clean_return(val) { retval = val; goto error_out; }
 
34
 
32
35
/* Declare useful decoder variables. */
33
 
#define setup()                                 \
34
 
  asn1_error_code retval;                       \
35
 
  asn1_class asn1class;                         \
36
 
  asn1_construction construction;               \
37
 
  asn1_tagnum tagnum;                           \
 
36
#define setup()                                 \
 
37
  asn1_error_code retval;                       \
 
38
  asn1_class asn1class;                         \
 
39
  asn1_construction construction;               \
 
40
  asn1_tagnum tagnum;                           \
38
41
  unsigned int length, taglen
39
42
 
40
43
#define unused_var(x) if (0) { x = 0; x = x - x; }
41
44
 
42
45
/* This is used for prefetch of next tag in sequence. */
43
 
#define next_tag()                                                              \
44
 
{ taginfo t2;                                                                   \
45
 
  retval = asn1_get_tag_2(&subbuf, &t2);                                        \
46
 
  if (retval) return retval;                                                    \
47
 
  /* Copy out to match previous functionality, until better integrated.  */     \
48
 
  asn1class = t2.asn1class;                                                     \
49
 
  construction = t2.construction;                                               \
50
 
  tagnum = t2.tagnum;                                                           \
51
 
  taglen = t2.length;                                                           \
52
 
  indef = t2.indef;                                                             \
 
46
#define next_tag()                                                              \
 
47
{ taginfo t2;                                                                   \
 
48
  retval = asn1_get_tag_2(&subbuf, &t2);                                        \
 
49
  if (retval) clean_return(retval);                                             \
 
50
  /* Copy out to match previous functionality, until better integrated.  */     \
 
51
  asn1class = t2.asn1class;                                                     \
 
52
  construction = t2.construction;                                               \
 
53
  tagnum = t2.tagnum;                                                           \
 
54
  taglen = t2.length;                                                           \
 
55
  indef = t2.indef;                                                             \
 
56
}
 
57
 
 
58
static asn1_error_code
 
59
asn1_get_eoc_tag (asn1buf *buf)
 
60
{
 
61
    asn1_error_code retval;
 
62
    taginfo t;
 
63
 
 
64
    retval = asn1_get_tag_2(buf, &t);
 
65
    if (retval)
 
66
        return retval;
 
67
    if (t.asn1class != UNIVERSAL || t.tagnum || t.indef)
 
68
        return ASN1_MISSING_EOC;
 
69
    return 0;
53
70
}
54
71
 
55
72
/* Force check for EOC tag. */
56
 
#define get_eoc()                                                                       \
57
 
    {                                                                                   \
58
 
        taginfo t3;                                                                     \
59
 
        retval = asn1_get_tag_2(&subbuf, &t3);                                          \
60
 
        if(retval) return retval;                                                       \
61
 
        if (t3.asn1class != UNIVERSAL || t3.tagnum || t3.indef)                         \
62
 
            return ASN1_MISSING_EOC;                                                    \
63
 
        /* Copy out to match previous functionality, until better integrated.  */       \
64
 
        asn1class = t3.asn1class;                                                       \
65
 
        construction = t3.construction;                                                 \
66
 
        tagnum = t3.tagnum;                                                             \
67
 
        taglen = t3.length;                                                             \
68
 
        indef = t3.indef;                                                               \
 
73
#define get_eoc()                               \
 
74
    {                                           \
 
75
        retval = asn1_get_eoc_tag(&subbuf);     \
 
76
        if (retval) clean_return(retval);       \
69
77
    }
70
78
 
71
 
#define alloc_field(var, type)                  \
72
 
  var = (type*)calloc(1, sizeof(type));         \
73
 
  if ((var) == NULL) return ENOMEM
 
79
#define alloc_field(var)                        \
 
80
  var = calloc(1, sizeof(*var));                \
 
81
  if ((var) == NULL) clean_return(ENOMEM)
 
82
 
 
83
/*
 
84
 * Allocate a principal and initialize enough fields for
 
85
 * krb5_free_principal to have defined behavior.
 
86
 */
 
87
#define alloc_principal(var)                    \
 
88
  alloc_field(var);                             \
 
89
  var->realm.data = NULL;                       \
 
90
  var->data = NULL
 
91
 
 
92
/*
 
93
 * Allocate a data structure and initialize enough fields for
 
94
 * krb5_free_data to have defined behavior.
 
95
 */
 
96
#define alloc_data(var)                         \
 
97
  alloc_field(var);                             \
 
98
  var->data = NULL
74
99
 
75
100
/* Fetch an expected APPLICATION class tag and verify. */
76
 
#define apptag(tagexpect)                                                               \
77
 
  {                                                                                     \
78
 
      taginfo t1;                                                                       \
79
 
      retval = asn1_get_tag_2(buf, &t1);                                                \
80
 
      if (retval) return retval;                                                        \
81
 
      if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED ||              \
82
 
          t1.tagnum != (tagexpect)) return ASN1_BAD_ID;                                 \
83
 
      /* Copy out to match previous functionality, until better integrated.  */         \
84
 
      asn1class = t1.asn1class;                                                         \
85
 
      construction = t1.construction;                                                   \
86
 
      tagnum = t1.tagnum;                                                               \
87
 
      applen = t1.length;                                                               \
 
101
#define apptag(tagexpect)                                                               \
 
102
  {                                                                                     \
 
103
      taginfo t1;                                                                       \
 
104
      retval = asn1_get_tag_2(buf, &t1);                                                \
 
105
      if (retval) clean_return(retval);                                                 \
 
106
      if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED ||              \
 
107
          t1.tagnum != (tagexpect)) clean_return(ASN1_BAD_ID);                          \
 
108
      /* Copy out to match previous functionality, until better integrated.  */         \
 
109
      asn1class = t1.asn1class;                                                         \
 
110
      construction = t1.construction;                                                   \
 
111
      tagnum = t1.tagnum;                                                               \
 
112
      applen = t1.length;                                                               \
88
113
  }
89
114
 
90
115
/**** normal fields ****/
96
121
 * get_eoc() assumes that any values fetched by this macro are
97
122
 * enclosed in a context-specific tag.
98
123
 */
99
 
#define get_field_body(var, decoder)            \
100
 
  retval = decoder(&subbuf, &(var));            \
101
 
  if (retval) return retval;                    \
102
 
  if (!taglen && indef) { get_eoc(); }          \
 
124
#define get_field_body(var, decoder)            \
 
125
  retval = decoder(&subbuf, &(var));            \
 
126
  if (retval) clean_return(retval);            \
 
127
  if (!taglen && indef) { get_eoc(); }          \
103
128
  next_tag()
104
129
 
105
130
/*
 
131
 * error_if_bad_tag
 
132
 *
 
133
 * Checks that the next tag is the expected one; returns with an error
 
134
 * if not.
 
135
 */
 
136
#define error_if_bad_tag(tagexpect) \
 
137
  if (tagnum != (tagexpect)) { clean_return((tagnum < (tagexpect)) ? ASN1_MISPLACED_FIELD : ASN1_MISSING_FIELD); }
 
138
 
 
139
/*
106
140
 * get_field
107
141
 *
108
142
 * Get field having an expected context specific tag.  This assumes
109
143
 * that context-specific tags are monotonically increasing in its
110
144
 * verification of tag numbers.
111
145
 */
112
 
#define get_field(var, tagexpect, decoder)                              \
113
 
  if (tagnum > (tagexpect)) return ASN1_MISSING_FIELD;                  \
114
 
  if (tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;                \
115
 
  if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)    \
116
 
      && (tagnum || taglen || asn1class != UNIVERSAL))                  \
117
 
    return ASN1_BAD_ID;                                                 \
 
146
#define get_field(var, tagexpect, decoder)                              \
 
147
  error_if_bad_tag(tagexpect);                                          \
 
148
  if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)    \
 
149
      && (tagnum || taglen || asn1class != UNIVERSAL))                  \
 
150
    clean_return(ASN1_BAD_ID);                                          \
118
151
  get_field_body(var,decoder)
119
152
 
120
153
/*
125
158
 * distinguish between absent optional values and present optional
126
159
 * values that happen to have the value of OPTVAL.
127
160
 */
128
 
#define opt_field(var, tagexpect, decoder, optvalue)                    \
129
 
  if (asn1buf_remains(&subbuf, seqindef)) {                             \
130
 
    if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)  \
131
 
        && (tagnum || taglen || asn1class != UNIVERSAL))                \
132
 
      return ASN1_BAD_ID;                                               \
133
 
    if (tagnum == (tagexpect)) {                                        \
134
 
      get_field_body(var, decoder);                                     \
135
 
    } else var = optvalue;                                              \
 
161
#define opt_field(var, tagexpect, decoder, optvalue)                    \
 
162
  if (asn1buf_remains(&subbuf, seqindef)) {                             \
 
163
    if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)  \
 
164
        && (tagnum || taglen || asn1class != UNIVERSAL))                \
 
165
      clean_return(ASN1_BAD_ID);                                        \
 
166
    if (tagnum == (tagexpect)) {                                        \
 
167
      get_field_body(var, decoder);                                     \
 
168
    } else var = optvalue;                                              \
136
169
  }
137
 
  
 
170
 
138
171
/**** fields w/ length ****/
139
172
 
140
173
/* similar to get_field_body */
141
 
#define get_lenfield_body(len, var, decoder)    \
142
 
  retval = decoder(&subbuf, &(len), &(var));    \
143
 
  if (retval) return retval;                    \
144
 
  if (!taglen && indef) { get_eoc(); }          \
 
174
#define get_lenfield_body(len, var, decoder)    \
 
175
  retval = decoder(&subbuf, &(len), &(var));    \
 
176
  if (retval) clean_return(retval);             \
 
177
  if (!taglen && indef) { get_eoc(); }          \
145
178
  next_tag()
146
179
 
147
180
/* similar to get_field_body */
148
 
#define get_lenfield(len, var, tagexpect, decoder)                      \
149
 
  if (tagnum > (tagexpect)) return ASN1_MISSING_FIELD;                  \
150
 
  if (tagnum < (tagexpect)) return ASN1_MISPLACED_FIELD;                \
151
 
  if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)    \
152
 
      && (tagnum || taglen || asn1class != UNIVERSAL))                  \
153
 
    return ASN1_BAD_ID;                                                 \
 
181
#define get_lenfield(len, var, tagexpect, decoder)                      \
 
182
  error_if_bad_tag(tagexpect);                                          \
 
183
  if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)    \
 
184
      && (tagnum || taglen || asn1class != UNIVERSAL))                  \
 
185
    clean_return(ASN1_BAD_ID);                                          \
154
186
  get_lenfield_body(len, var, decoder)
155
187
 
156
188
/* similar to opt_field */
157
 
#define opt_lenfield(len, var, tagexpect, decoder)      \
158
 
  if (tagnum == (tagexpect)) {                          \
159
 
    get_lenfield_body(len, var, decoder);               \
 
189
#define opt_lenfield(len, var, tagexpect, decoder)      \
 
190
  if (tagnum == (tagexpect)) {                          \
 
191
    get_lenfield_body(len, var, decoder);               \
160
192
  } else { len = 0; var = 0; }
161
193
 
162
194
/*
163
195
 * Deal with implicitly tagged fields
164
196
 */
165
 
#define get_implicit_octet_string(len, var, tagexpect)              \
166
 
  if (tagnum != (tagexpect)) return ASN1_MISSING_FIELD;             \
 
197
#define get_implicit_octet_string(len, var, tagexpect)              \
 
198
  if (tagnum != (tagexpect)) clean_return(ASN1_MISSING_FIELD);      \
167
199
  if (asn1class != CONTEXT_SPECIFIC || construction != PRIMITIVE)   \
168
 
     return ASN1_BAD_ID;                                            \
169
 
  retval = asn1buf_remove_octetstring(&subbuf, taglen, &(var));     \
170
 
  if (retval) return retval;                                        \
171
 
  (len) = taglen;                                                   \
 
200
    clean_return(ASN1_BAD_ID);                                      \
 
201
  retval = asn1buf_remove_octetstring(&subbuf, taglen, &(var));     \
 
202
  if (retval) clean_return(retval);                                 \
 
203
  (len) = taglen;                                                   \
172
204
  next_tag()
173
205
 
174
 
#define opt_implicit_octet_string(len, var, tagexpect)              \
175
 
  if (tagnum == (tagexpect)) {                                      \
 
206
#define opt_implicit_octet_string(len, var, tagexpect)              \
 
207
  if (tagnum == (tagexpect)) {                                      \
176
208
    if (asn1class != CONTEXT_SPECIFIC || construction != PRIMITIVE) \
177
 
        return ASN1_BAD_ID;                                         \
 
209
        clean_return(ASN1_BAD_ID);                                  \
178
210
    retval = asn1buf_remove_octetstring(&subbuf, taglen, &(var));   \
179
 
    if (retval) return retval;                                      \
180
 
    (len) = taglen;                                                 \
181
 
    next_tag();                                                     \
 
211
    if (retval) clean_return(retval);                               \
 
212
    (len) = taglen;                                                 \
 
213
    next_tag();                                                     \
182
214
  } else { (len) = 0; (var) = NULL; }
183
215
 
184
216
/*
188
220
 * to be called in an inner block that ends with a call to
189
221
 * end_structure().
190
222
 */
191
 
#define begin_structure()                                       \
192
 
  asn1buf subbuf;                                               \
193
 
  int seqindef;                                                 \
194
 
  int indef;                                                    \
195
 
  retval = asn1_get_sequence(buf, &length, &seqindef);          \
196
 
  if (retval) return retval;                                    \
197
 
  retval = asn1buf_imbed(&subbuf, buf, length, seqindef);       \
198
 
  if (retval) return retval;                                    \
 
223
#define begin_structure()                                       \
 
224
  asn1buf subbuf;                                               \
 
225
  int seqindef;                                                 \
 
226
  int indef;                                                    \
 
227
  retval = asn1_get_sequence(buf, &length, &seqindef);          \
 
228
  if (retval) clean_return(retval);                             \
 
229
  retval = asn1buf_imbed(&subbuf, buf, length, seqindef);       \
 
230
  if (retval) clean_return(retval);                             \
199
231
  next_tag()
200
232
 
201
233
/*
203
235
 * It is the same as begin_structure() except next_tag()
204
236
 * is not called.
205
237
 */
206
 
#define begin_structure_no_tag()                                \
207
 
  asn1buf subbuf;                                               \
208
 
  int seqindef;                                                 \
209
 
  int indef;                                                    \
210
 
  retval = asn1_get_sequence(buf, &length, &seqindef);          \
211
 
  if (retval) return retval;                                    \
212
 
  retval = asn1buf_imbed(&subbuf, buf, length, seqindef);       \
213
 
  if (retval) return retval
 
238
#define begin_structure_no_tag()                                \
 
239
  asn1buf subbuf;                                               \
 
240
  int seqindef;                                                 \
 
241
  int indef;                                                    \
 
242
  retval = asn1_get_sequence(buf, &length, &seqindef);          \
 
243
  if (retval) clean_return(retval);                             \
 
244
  retval = asn1buf_imbed(&subbuf, buf, length, seqindef);       \
 
245
  if (retval) clean_return(retval)
214
246
 
215
247
/* skip trailing garbage */
216
 
#define end_structure()                                         \
217
 
  retval = asn1buf_sync(buf, &subbuf, asn1class, tagnum,        \
218
 
                        length, indef, seqindef);               \
219
 
  if (retval) return retval
 
248
#define end_structure()                                         \
 
249
  retval = asn1buf_sync(buf, &subbuf, asn1class, tagnum,        \
 
250
                        length, indef, seqindef);               \
 
251
  if (retval) clean_return(retval)
220
252
 
221
253
/*
222
254
 * begin_choice
225
257
 * to be called in an inner block that ends with a call to
226
258
 * end_choice().
227
259
 */
228
 
#define begin_choice()                                          \
229
 
  asn1buf subbuf;                                               \
230
 
  int seqindef;                                                 \
231
 
  int indef;                                                    \
232
 
  taginfo t;                                                    \
233
 
  retval = asn1_get_tag_2(buf, &t);                             \
234
 
  if (retval) return retval;                                    \
 
260
#define begin_choice()                                          \
 
261
  asn1buf subbuf;                                               \
 
262
  int seqindef;                                                 \
 
263
  int indef;                                                    \
 
264
  taginfo t;                                                    \
 
265
  retval = asn1_get_tag_2(buf, &t);                             \
 
266
  if (retval) clean_return(retval);                             \
235
267
  tagnum = t.tagnum;                                            \
236
268
  taglen = t.length;                                            \
237
269
  indef = t.indef;                                              \
238
270
  length = t.length;                                            \
239
271
  seqindef = t.indef;                                           \
240
 
  asn1class = t.asn1class;                                      \
241
 
  construction = t.construction;                                \
242
 
  retval = asn1buf_imbed(&subbuf, buf, length, seqindef);       \
243
 
  if (retval) return retval
 
272
  asn1class = t.asn1class;                                      \
 
273
  construction = t.construction;                                \
 
274
  retval = asn1buf_imbed(&subbuf, buf, length, seqindef);       \
 
275
  if (retval) clean_return(retval)
244
276
 
245
277
/* skip trailing garbage */
246
 
#define end_choice()                                            \
247
 
  length -= t.length;                                           \
248
 
  retval = asn1buf_sync(buf, &subbuf, t.asn1class, t.tagnum,    \
249
 
                        length, t.indef, seqindef);             \
250
 
  if (retval) return retval
 
278
#define end_choice()                                            \
 
279
  length -= t.length;                                           \
 
280
  retval = asn1buf_sync(buf, &subbuf, t.asn1class, t.tagnum,    \
 
281
                        length, t.indef, seqindef);             \
 
282
  if (retval) clean_return(retval)
251
283
 
252
284
/*
253
285
 * sequence_of
256
288
 * meant to be called in an inner block that ends with a call to
257
289
 * end_sequence_of().
258
290
 */
259
 
#define sequence_of(buf)                        \
260
 
  unsigned int length, taglen;                  \
261
 
  asn1_class asn1class;                         \
262
 
  asn1_construction construction;               \
263
 
  asn1_tagnum tagnum;                           \
264
 
  int indef;                                    \
 
291
#define sequence_of(buf)                        \
 
292
  unsigned int length, taglen;                  \
 
293
  asn1_class asn1class;                         \
 
294
  asn1_construction construction;               \
 
295
  asn1_tagnum tagnum;                           \
 
296
  int indef;                                    \
265
297
  sequence_of_common(buf)
266
298
 
267
299
/*
271
303
 * sequence structure and thus declares variables of different names
272
304
 * than does sequence_of() to avoid shadowing.
273
305
 */
274
 
#define sequence_of_no_tagvars(buf)             \
275
 
  asn1_class eseqclass;                         \
276
 
  asn1_construction eseqconstr;                 \
277
 
  asn1_tagnum eseqnum;                          \
278
 
  unsigned int eseqlen;                         \
279
 
  int eseqindef;                                \
 
306
#define sequence_of_no_tagvars(buf)             \
280
307
  sequence_of_common(buf)
281
308
 
282
309
/*
286
313
 * and imbeds an inner buffer seqbuf.  Unlike begin_structure(), it
287
314
 * does not prefetch the next tag.
288
315
 */
289
 
#define sequence_of_common(buf)                                 \
290
 
  int size = 0;                                                 \
291
 
  asn1buf seqbuf;                                               \
292
 
  int seqofindef;                                               \
293
 
  retval = asn1_get_sequence(buf, &length, &seqofindef);        \
294
 
  if (retval) return retval;                                    \
295
 
  retval = asn1buf_imbed(&seqbuf, buf, length, seqofindef);     \
296
 
  if (retval) return retval
 
316
#define sequence_of_common(buf)                                 \
 
317
  asn1buf seqbuf;                                               \
 
318
  int seqofindef;                                               \
 
319
  retval = asn1_get_sequence(buf, &length, &seqofindef);        \
 
320
  if (retval) clean_return(retval);                             \
 
321
  retval = asn1buf_imbed(&seqbuf, buf, length, seqofindef);     \
 
322
  if (retval) clean_return(retval)
297
323
 
298
324
/*
299
325
 * end_sequence_of
301
327
 * Attempts to fetch an EOC tag, if any, and to sync over trailing
302
328
 * garbage, if any.
303
329
 */
304
 
#define end_sequence_of(buf)                                                    \
305
 
  {                                                                             \
306
 
      taginfo t4;                                                               \
307
 
      retval = asn1_get_tag_2(&seqbuf, &t4);                                    \
308
 
      if (retval) return retval;                                                \
309
 
      /* Copy out to match previous functionality, until better integrated.  */ \
310
 
      asn1class = t4.asn1class;                                                 \
311
 
      construction = t4.construction;                                           \
312
 
      tagnum = t4.tagnum;                                                       \
313
 
      taglen = t4.length;                                                       \
314
 
      indef = t4.indef;                                                         \
315
 
  }                                                                             \
316
 
  retval = asn1buf_sync(buf, &seqbuf, asn1class, tagnum,                        \
317
 
                        length, indef, seqofindef);                             \
318
 
  if (retval) return retval;
 
330
#define end_sequence_of(buf)                                                    \
 
331
  {                                                                             \
 
332
      taginfo t4;                                                               \
 
333
      retval = asn1_get_tag_2(&seqbuf, &t4);                                    \
 
334
      if (retval) clean_return(retval);                                         \
 
335
      /* Copy out to match previous functionality, until better integrated.  */ \
 
336
      asn1class = t4.asn1class;                                                 \
 
337
      construction = t4.construction;                                           \
 
338
      tagnum = t4.tagnum;                                                       \
 
339
      taglen = t4.length;                                                       \
 
340
      indef = t4.indef;                                                         \
 
341
  }                                                                             \
 
342
  retval = asn1buf_sync(buf, &seqbuf, asn1class, tagnum,                        \
 
343
                        length, indef, seqofindef);                             \
 
344
  if (retval) clean_return(retval);
319
345
 
320
346
/*
321
347
 * end_sequence_of_no_tagvars
323
349
 * Like end_sequence_of(), but uses the different (non-shadowing)
324
350
 * variable names.
325
351
 */
326
 
#define end_sequence_of_no_tagvars(buf)                                         \
327
 
  {                                                                             \
328
 
      taginfo t5;                                                               \
329
 
      retval = asn1_get_tag_2(&seqbuf, &t5);                                    \
330
 
      if (retval) return retval;                                                \
331
 
      /* Copy out to match previous functionality, until better integrated.  */ \
332
 
      eseqclass = t5.asn1class;                                                 \
333
 
      eseqconstr = t5.construction;                                             \
334
 
      eseqnum = t5.tagnum;                                                      \
335
 
      eseqlen = t5.length;                                                      \
336
 
      eseqindef = t5.indef;                                                     \
337
 
  }                                                                             \
338
 
  retval = asn1buf_sync(buf, &seqbuf, eseqclass, eseqnum,                       \
339
 
                        eseqlen, eseqindef, seqofindef);                        \
340
 
  if (retval) return retval;
341
 
 
342
 
#define cleanup()                               \
343
 
  return 0
 
352
static asn1_error_code
 
353
end_sequence_of_no_tagvars_helper(asn1buf *buf, asn1buf *seqbufp,
 
354
                                  int seqofindef)
 
355
{
 
356
    taginfo t;
 
357
    asn1_error_code retval;
 
358
 
 
359
    retval = asn1_get_tag_2(seqbufp, &t);
 
360
    if (retval)
 
361
        return retval;
 
362
    retval = asn1buf_sync(buf, seqbufp, t.asn1class, t.tagnum,
 
363
                          t.length, t.indef, seqofindef);
 
364
    return retval;
 
365
}
 
366
#define end_sequence_of_no_tagvars(buf) \
 
367
    retval = end_sequence_of_no_tagvars_helper(buf, &seqbuf, seqofindef); \
 
368
    if (retval) clean_return(retval)
 
369
 
 
370
/*
 
371
 * Function body for a pointer decoder, which allocates a pointer
 
372
 * field and invokes a structure decoder to fill it in.  Pointer
 
373
 * decoders always fill in their output parameters with NULL (on
 
374
 * error) or a valid constructed structure, making cleanup easier on
 
375
 * callers.
 
376
 */
 
377
#define decode_ptr(type, structure_decoder) \
 
378
    type val; \
 
379
    asn1_error_code retval; \
 
380
\
 
381
    *valptr = NULL; \
 
382
    val = calloc(1, sizeof(*val)); \
 
383
    if (!val) \
 
384
        return ENOMEM; \
 
385
    retval = structure_decoder(buf, val); \
 
386
    if (retval) { \
 
387
        free(val); \
 
388
        return retval; \
 
389
    } \
 
390
    *valptr = val; \
 
391
    return 0;
344
392
 
345
393
/* scalars */
346
394
asn1_error_code asn1_decode_kerberos_time(asn1buf *buf, krb5_timestamp *val)
347
395
{
348
 
    time_t      t;
 
396
    time_t      t;
349
397
    asn1_error_code retval;
350
 
    
 
398
 
351
399
    retval =  asn1_decode_generaltime(buf,&t);
352
400
    if (retval)
353
 
        return retval;
 
401
        return retval;
354
402
 
355
403
    *val = t;
356
404
    return 0;
362
410
  asn1_error_code retval;\
363
411
  long n;\
364
412
  retval = asn1_decode_integer(buf,&n);\
365
 
  if(retval) return retval;\
 
413
  if (retval) return retval;\
366
414
  *val = (ktype)n;\
367
415
  return 0;\
368
416
}
372
420
  asn1_error_code retval;\
373
421
  unsigned long n;\
374
422
  retval = asn1_decode_unsigned_integer(buf,&n);\
375
 
  if(retval) return retval;\
 
423
  if (retval) return retval;\
376
424
  *val = (ktype)n;\
377
425
  return 0;\
378
426
}
389
437
 
390
438
asn1_error_code asn1_decode_seqnum(asn1buf *buf, krb5_ui_4 *val)
391
439
{
392
 
  asn1_error_code retval;
393
 
  unsigned long n;
 
440
    asn1_error_code retval;
 
441
    unsigned long n;
394
442
 
395
 
  retval = asn1_decode_maybe_unsigned(buf, &n);
396
 
  if (retval) return retval;
397
 
  *val = (krb5_ui_4)n & 0xffffffff;
398
 
  return 0;
 
443
    retval = asn1_decode_maybe_unsigned(buf, &n);
 
444
    if (retval) return retval;
 
445
    *val = (krb5_ui_4)n & 0xffffffff;
 
446
    return 0;
399
447
}
400
448
 
401
449
asn1_error_code asn1_decode_msgtype(asn1buf *buf, krb5_msgtype *val)
402
450
{
403
 
  asn1_error_code retval;
404
 
  unsigned long n;
405
 
  
406
 
  retval = asn1_decode_unsigned_integer(buf,&n);
407
 
  if(retval) return retval;
408
 
  
409
 
  *val = (krb5_msgtype) n;
410
 
  return 0;
 
451
    asn1_error_code retval;
 
452
    unsigned long n;
 
453
 
 
454
    retval = asn1_decode_unsigned_integer(buf,&n);
 
455
    if (retval) return retval;
 
456
 
 
457
    *val = (krb5_msgtype) n;
 
458
    return 0;
411
459
}
412
460
 
413
461
 
414
462
/* structures */
415
463
asn1_error_code asn1_decode_realm(asn1buf *buf, krb5_principal *val)
416
464
{
417
 
  return asn1_decode_generalstring(buf,
418
 
                                   &((*val)->realm.length),
419
 
                                   &((*val)->realm.data));
 
465
    return asn1_decode_generalstring(buf,
 
466
                                     &((*val)->realm.length),
 
467
                                     &((*val)->realm.data));
420
468
}
421
469
 
422
470
asn1_error_code asn1_decode_principal_name(asn1buf *buf, krb5_principal *val)
423
471
{
424
 
  setup();
425
 
  { begin_structure();
426
 
    get_field((*val)->type,0,asn1_decode_int32);
427
 
  
428
 
    { sequence_of_no_tagvars(&subbuf);
429
 
      while(asn1buf_remains(&seqbuf,seqofindef) > 0){
430
 
        size++;
431
 
        if ((*val)->data == NULL)
432
 
          (*val)->data = (krb5_data*)malloc(size*sizeof(krb5_data));
433
 
        else
434
 
          (*val)->data = (krb5_data*)realloc((*val)->data,
435
 
                                             size*sizeof(krb5_data));
436
 
        if((*val)->data == NULL) return ENOMEM;
437
 
        retval = asn1_decode_generalstring(&seqbuf,
438
 
                                           &((*val)->data[size-1].length),
439
 
                                           &((*val)->data[size-1].data));
440
 
        if(retval) return retval;
441
 
      }
442
 
      (*val)->length = size;
443
 
      end_sequence_of_no_tagvars(&subbuf);
444
 
    }
445
 
    if (indef) {
446
 
        get_eoc();
447
 
    }
448
 
    next_tag();
449
 
    end_structure();
 
472
    int size = 0, i;
 
473
    krb5_data *array = NULL, *new_array;
 
474
 
 
475
    setup();
 
476
    { begin_structure();
 
477
        get_field((*val)->type,0,asn1_decode_int32);
 
478
 
 
479
        { sequence_of_no_tagvars(&subbuf);
 
480
            while (asn1buf_remains(&seqbuf,seqofindef) > 0) {
 
481
                unsigned int len;
 
482
                char *str;
 
483
 
 
484
                new_array = realloc(array, (size + 1) * sizeof(krb5_data));
 
485
                if (new_array == NULL) clean_return(ENOMEM);
 
486
                array = new_array;
 
487
                retval = asn1_decode_generalstring(&seqbuf, &len, &str);
 
488
                if (retval) clean_return(retval);
 
489
                array[size].data = str;
 
490
                array[size].length = len;
 
491
                size++;
 
492
            }
 
493
            end_sequence_of_no_tagvars(&subbuf);
 
494
        }
 
495
        if (indef) {
 
496
            get_eoc();
 
497
        }
 
498
        next_tag();
 
499
        end_structure();
 
500
    }
 
501
    (*val)->data = array;
 
502
    (*val)->length = size;
450
503
    (*val)->magic = KV5M_PRINCIPAL;
451
 
  }
452
 
  cleanup();
 
504
    return 0;
 
505
error_out:
 
506
    for (i = 0; i < size; i++)
 
507
        free(array[i].data);
 
508
    free(array);
 
509
    return retval;
453
510
}
454
511
 
455
512
asn1_error_code asn1_decode_checksum(asn1buf *buf, krb5_checksum *val)
456
513
{
457
 
  setup();
458
 
  { begin_structure();
459
 
    get_field(val->checksum_type,0,asn1_decode_cksumtype);
460
 
    get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
461
 
    end_structure();
462
 
    val->magic = KV5M_CHECKSUM;
463
 
  }
464
 
  cleanup();
 
514
    setup();
 
515
    val->contents = NULL;
 
516
    { begin_structure();
 
517
        get_field(val->checksum_type,0,asn1_decode_cksumtype);
 
518
        get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
 
519
        end_structure();
 
520
        val->magic = KV5M_CHECKSUM;
 
521
    }
 
522
    return 0;
 
523
error_out:
 
524
    free(val->contents);
 
525
    return retval;
 
526
}
 
527
 
 
528
asn1_error_code asn1_decode_checksum_ptr(asn1buf *buf, krb5_checksum **valptr)
 
529
{
 
530
    decode_ptr(krb5_checksum *, asn1_decode_checksum);
465
531
}
466
532
 
467
533
asn1_error_code asn1_decode_encryption_key(asn1buf *buf, krb5_keyblock *val)
468
534
{
469
 
  setup();
470
 
  { begin_structure();
471
 
    get_field(val->enctype,0,asn1_decode_enctype);
472
 
    get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
473
 
    end_structure();
474
 
    val->magic = KV5M_KEYBLOCK;
475
 
  }
476
 
  cleanup();
 
535
    setup();
 
536
    val->contents = NULL;
 
537
    { begin_structure();
 
538
        get_field(val->enctype,0,asn1_decode_enctype);
 
539
        get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
 
540
        end_structure();
 
541
        val->magic = KV5M_KEYBLOCK;
 
542
    }
 
543
    return 0;
 
544
error_out:
 
545
    free(val->contents);
 
546
    return retval;
 
547
}
 
548
 
 
549
asn1_error_code
 
550
asn1_decode_encryption_key_ptr(asn1buf *buf, krb5_keyblock **valptr)
 
551
{
 
552
    decode_ptr(krb5_keyblock *, asn1_decode_encryption_key);
477
553
}
478
554
 
479
555
asn1_error_code asn1_decode_encrypted_data(asn1buf *buf, krb5_enc_data *val)
480
556
{
481
 
  setup();
482
 
  { begin_structure();
483
 
    get_field(val->enctype,0,asn1_decode_enctype);
484
 
    opt_field(val->kvno,1,asn1_decode_kvno,0);
485
 
    get_lenfield(val->ciphertext.length,val->ciphertext.data,2,asn1_decode_charstring);
486
 
    end_structure();
487
 
    val->magic = KV5M_ENC_DATA;
488
 
  }
489
 
  cleanup();
 
557
    setup();
 
558
    val->ciphertext.data = NULL;
 
559
    { begin_structure();
 
560
        get_field(val->enctype,0,asn1_decode_enctype);
 
561
        opt_field(val->kvno,1,asn1_decode_kvno,0);
 
562
        get_lenfield(val->ciphertext.length,val->ciphertext.data,2,asn1_decode_charstring);
 
563
        end_structure();
 
564
        val->magic = KV5M_ENC_DATA;
 
565
    }
 
566
    return 0;
 
567
error_out:
 
568
    free(val->ciphertext.data);
 
569
    val->ciphertext.data = NULL;
 
570
    return retval;
490
571
}
491
572
 
492
573
asn1_error_code asn1_decode_krb5_flags(asn1buf *buf, krb5_flags *val)
493
574
{
494
 
  asn1_error_code retval;
495
 
  asn1_octet unused, o;
496
 
  taginfo t;
497
 
  int i;
498
 
  krb5_flags f=0;
499
 
  unsigned int length;
500
 
 
501
 
  retval = asn1_get_tag_2(buf, &t);
502
 
  if (retval) return retval;
503
 
  if (t.asn1class != UNIVERSAL || t.construction != PRIMITIVE ||
504
 
      t.tagnum != ASN1_BITSTRING)
505
 
      return ASN1_BAD_ID;
506
 
  length = t.length;
507
 
 
508
 
  retval = asn1buf_remove_octet(buf,&unused); /* # of padding bits */
509
 
  if(retval) return retval;
510
 
 
511
 
  /* Number of unused bits must be between 0 and 7. */
512
 
  if (unused > 7) return ASN1_BAD_FORMAT;
513
 
  length--;
514
 
 
515
 
  for(i = 0; i < length; i++) {
516
 
    retval = asn1buf_remove_octet(buf,&o);
517
 
    if(retval) return retval;
518
 
    /* ignore bits past number 31 */
519
 
    if (i < 4)
520
 
      f = (f<<8) | ((krb5_flags)o&0xFF);
521
 
  }
522
 
  if (length <= 4) {
523
 
    /* Mask out unused bits, but only if necessary. */
524
 
    f &= ~(krb5_flags)0 << unused;
525
 
  }
526
 
  /* left-justify */
527
 
  if (length < 4)
528
 
    f <<= (4 - length) * 8;
529
 
  *val = f;
530
 
  return 0;
 
575
    asn1_error_code retval;
 
576
    asn1_octet unused, o;
 
577
    taginfo t;
 
578
    unsigned int i;
 
579
    krb5_flags f=0;
 
580
    unsigned int length;
 
581
 
 
582
    retval = asn1_get_tag_2(buf, &t);
 
583
    if (retval) return retval;
 
584
    if (t.asn1class != UNIVERSAL || t.construction != PRIMITIVE ||
 
585
        t.tagnum != ASN1_BITSTRING)
 
586
        return ASN1_BAD_ID;
 
587
    length = t.length;
 
588
 
 
589
    retval = asn1buf_remove_octet(buf,&unused); /* # of padding bits */
 
590
    if (retval) return retval;
 
591
 
 
592
    /* Number of unused bits must be between 0 and 7. */
 
593
    if (unused > 7) return ASN1_BAD_FORMAT;
 
594
    length--;
 
595
 
 
596
    for (i = 0; i < length; i++) {
 
597
        retval = asn1buf_remove_octet(buf,&o);
 
598
        if (retval) return retval;
 
599
        /* ignore bits past number 31 */
 
600
        if (i < 4)
 
601
            f = (f<<8) | ((krb5_flags)o&0xFF);
 
602
    }
 
603
    if (length <= 4) {
 
604
        /* Mask out unused bits, but only if necessary. */
 
605
        f &= ~(krb5_flags)0 << unused;
 
606
    }
 
607
    /* left-justify */
 
608
    if (length < 4)
 
609
        f <<= (4 - length) * 8;
 
610
    *val = f;
 
611
    return 0;
531
612
}
532
613
 
533
614
asn1_error_code asn1_decode_ticket_flags(asn1buf *buf, krb5_flags *val)
541
622
 
542
623
asn1_error_code asn1_decode_transited_encoding(asn1buf *buf, krb5_transited *val)
543
624
{
544
 
  setup();
545
 
  { begin_structure();
546
 
    get_field(val->tr_type,0,asn1_decode_octet);
547
 
    get_lenfield(val->tr_contents.length,val->tr_contents.data,1,asn1_decode_charstring);
548
 
    end_structure();
549
 
    val->magic = KV5M_TRANSITED;
550
 
  }
551
 
  cleanup();
 
625
    setup();
 
626
    val->tr_contents.data = NULL;
 
627
    { begin_structure();
 
628
        get_field(val->tr_type,0,asn1_decode_octet);
 
629
        get_lenfield(val->tr_contents.length,val->tr_contents.data,1,asn1_decode_charstring);
 
630
        end_structure();
 
631
        val->magic = KV5M_TRANSITED;
 
632
    }
 
633
    return 0;
 
634
error_out:
 
635
    krb5_free_data_contents(NULL, &val->tr_contents);
 
636
    return retval;
552
637
}
553
638
 
554
639
asn1_error_code asn1_decode_enc_kdc_rep_part(asn1buf *buf, krb5_enc_kdc_rep_part *val)
555
640
{
556
 
  setup();
557
 
  { begin_structure();
558
 
    alloc_field(val->session,krb5_keyblock);
559
 
    get_field(*(val->session),0,asn1_decode_encryption_key);
560
 
    get_field(val->last_req,1,asn1_decode_last_req);
561
 
    get_field(val->nonce,2,asn1_decode_int32);
562
 
    opt_field(val->key_exp,3,asn1_decode_kerberos_time,0);
563
 
    get_field(val->flags,4,asn1_decode_ticket_flags);
564
 
    get_field(val->times.authtime,5,asn1_decode_kerberos_time);
565
 
    /* Set to authtime if missing */
566
 
    opt_field(val->times.starttime,6,asn1_decode_kerberos_time,val->times.authtime);
567
 
    get_field(val->times.endtime,7,asn1_decode_kerberos_time);
568
 
    opt_field(val->times.renew_till,8,asn1_decode_kerberos_time,0);
569
 
    alloc_field(val->server,krb5_principal_data);
570
 
    get_field(val->server,9,asn1_decode_realm);
571
 
    get_field(val->server,10,asn1_decode_principal_name);
572
 
    opt_field(val->caddrs,11,asn1_decode_host_addresses,NULL);
573
 
    end_structure();
574
 
    val->magic = KV5M_ENC_KDC_REP_PART;
575
 
  }
576
 
  cleanup();
 
641
    setup();
 
642
    val->session = NULL;
 
643
    val->last_req = NULL;
 
644
    val->server = NULL;
 
645
    val->caddrs = NULL;
 
646
    { begin_structure();
 
647
        get_field(val->session,0,asn1_decode_encryption_key_ptr);
 
648
        get_field(val->last_req,1,asn1_decode_last_req);
 
649
        get_field(val->nonce,2,asn1_decode_int32);
 
650
        opt_field(val->key_exp,3,asn1_decode_kerberos_time,0);
 
651
        get_field(val->flags,4,asn1_decode_ticket_flags);
 
652
        get_field(val->times.authtime,5,asn1_decode_kerberos_time);
 
653
        /* Set to authtime if missing */
 
654
        opt_field(val->times.starttime,6,asn1_decode_kerberos_time,val->times.authtime);
 
655
        get_field(val->times.endtime,7,asn1_decode_kerberos_time);
 
656
        opt_field(val->times.renew_till,8,asn1_decode_kerberos_time,0);
 
657
        alloc_principal(val->server);
 
658
        get_field(val->server,9,asn1_decode_realm);
 
659
        get_field(val->server,10,asn1_decode_principal_name);
 
660
        opt_field(val->caddrs,11,asn1_decode_host_addresses,NULL);
 
661
        opt_field(val->enc_padata,12,asn1_decode_sequence_of_pa_data,NULL);
 
662
        end_structure();
 
663
        val->magic = KV5M_ENC_KDC_REP_PART;
 
664
    }
 
665
    return 0;
 
666
error_out:
 
667
    krb5_free_keyblock(NULL, val->session);
 
668
    krb5_free_last_req(NULL, val->last_req);
 
669
    krb5_free_principal(NULL, val->server);
 
670
    krb5_free_addresses(NULL, val->caddrs);
 
671
    val->session = NULL;
 
672
    val->last_req = NULL;
 
673
    val->server = NULL;
 
674
    val->caddrs = NULL;
 
675
    return retval;
577
676
}
578
677
 
579
678
asn1_error_code asn1_decode_ticket(asn1buf *buf, krb5_ticket *val)
580
679
{
581
 
  setup();
582
 
  unsigned int applen;
583
 
  apptag(1);
584
 
  { begin_structure();
585
 
    { krb5_kvno vno;
586
 
      get_field(vno,0,asn1_decode_kvno);
587
 
      if(vno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
588
 
    alloc_field(val->server,krb5_principal_data);
589
 
    get_field(val->server,1,asn1_decode_realm);
590
 
    get_field(val->server,2,asn1_decode_principal_name);
591
 
    get_field(val->enc_part,3,asn1_decode_encrypted_data);
592
 
    end_structure();
593
 
    val->magic = KV5M_TICKET;
594
 
  }
595
 
  if (!applen) {
596
 
      taginfo t;
597
 
      retval = asn1_get_tag_2(buf, &t);
598
 
      if (retval) return retval;
599
 
  }
600
 
  cleanup();
 
680
    setup();
 
681
    unsigned int applen;
 
682
    apptag(1);
 
683
    val->server = NULL;
 
684
    val->enc_part.ciphertext.data = NULL;
 
685
    val->enc_part2 = NULL;
 
686
    { begin_structure();
 
687
        { krb5_kvno vno;
 
688
            get_field(vno,0,asn1_decode_kvno);
 
689
            if (vno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); }
 
690
        alloc_principal(val->server);
 
691
        get_field(val->server,1,asn1_decode_realm);
 
692
        get_field(val->server,2,asn1_decode_principal_name);
 
693
        get_field(val->enc_part,3,asn1_decode_encrypted_data);
 
694
        end_structure();
 
695
        val->magic = KV5M_TICKET;
 
696
    }
 
697
    if (!applen) {
 
698
        taginfo t;
 
699
        retval = asn1_get_tag_2(buf, &t);
 
700
        if (retval) clean_return(retval);
 
701
    }
 
702
    return 0;
 
703
error_out:
 
704
    krb5_free_principal(NULL, val->server);
 
705
    krb5_free_data_contents(NULL, &val->enc_part.ciphertext);
 
706
    val->server = NULL;
 
707
    return retval;
 
708
}
 
709
 
 
710
asn1_error_code
 
711
asn1_decode_ticket_ptr(asn1buf *buf, krb5_ticket **valptr)
 
712
{
 
713
    decode_ptr(krb5_ticket *, asn1_decode_ticket);
601
714
}
602
715
 
603
716
asn1_error_code asn1_decode_kdc_req(asn1buf *buf, krb5_kdc_req *val)
604
717
{
605
 
  setup();
606
 
  { begin_structure();
607
 
    { krb5_kvno kvno;
608
 
      get_field(kvno,1,asn1_decode_kvno);
609
 
      if(kvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
610
 
    get_field(val->msg_type,2,asn1_decode_msgtype);
611
 
    opt_field(val->padata,3,asn1_decode_sequence_of_pa_data,NULL);
612
 
    get_field(*val,4,asn1_decode_kdc_req_body);
613
 
    end_structure();
614
 
    val->magic = KV5M_KDC_REQ;
615
 
  }
616
 
  cleanup();
 
718
    setup();
 
719
    val->padata = NULL;
 
720
    { begin_structure();
 
721
        { krb5_kvno kvno;
 
722
            get_field(kvno,1,asn1_decode_kvno);
 
723
            if (kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); }
 
724
        get_field(val->msg_type,2,asn1_decode_msgtype);
 
725
        opt_field(val->padata,3,asn1_decode_sequence_of_pa_data,NULL);
 
726
        get_field(*val,4,asn1_decode_kdc_req_body);
 
727
        end_structure();
 
728
        val->magic = KV5M_KDC_REQ;
 
729
    }
 
730
    return 0;
 
731
error_out:
 
732
    krb5_free_pa_data(NULL, val->padata);
 
733
    val->padata = NULL;
 
734
    return retval;
617
735
}
618
736
 
619
737
asn1_error_code asn1_decode_kdc_req_body(asn1buf *buf, krb5_kdc_req *val)
620
738
{
621
 
  setup();
622
 
  { 
623
 
    krb5_principal psave;
624
 
    begin_structure();
625
 
    get_field(val->kdc_options,0,asn1_decode_kdc_options);
626
 
    if(tagnum == 1){ alloc_field(val->client,krb5_principal_data); }
627
 
    opt_field(val->client,1,asn1_decode_principal_name,NULL);
628
 
    alloc_field(val->server,krb5_principal_data);
629
 
    get_field(val->server,2,asn1_decode_realm);
630
 
    if(val->client != NULL){
631
 
      retval = asn1_krb5_realm_copy(val->client,val->server);
632
 
      if(retval) return retval; }
 
739
    setup();
 
740
    val->client = NULL;
 
741
    val->server = NULL;
 
742
    val->ktype = NULL;
 
743
    val->addresses = NULL;
 
744
    val->authorization_data.ciphertext.data = NULL;
 
745
    val->unenc_authdata = NULL;
 
746
    val->second_ticket = NULL;
 
747
    {
 
748
        krb5_principal psave;
 
749
        begin_structure();
 
750
        get_field(val->kdc_options,0,asn1_decode_kdc_options);
 
751
        if (tagnum == 1) { alloc_principal(val->client); }
 
752
        opt_field(val->client,1,asn1_decode_principal_name,NULL);
 
753
        alloc_principal(val->server);
 
754
        get_field(val->server,2,asn1_decode_realm);
 
755
        if (val->client != NULL) {
 
756
            retval = asn1_krb5_realm_copy(val->client,val->server);
 
757
            if (retval) clean_return(retval); }
633
758
 
634
 
    /* If opt_field server is missing, memory reference to server is
635
 
       lost and results in memory leak */
636
 
    psave = val->server;
637
 
    opt_field(val->server,3,asn1_decode_principal_name,NULL);
638
 
    if(val->server == NULL){
639
 
      if(psave->realm.data) {
640
 
        free(psave->realm.data);
641
 
        psave->realm.data = NULL;
642
 
        psave->realm.length=0;
643
 
      }
644
 
      free(psave);
645
 
    }
646
 
    opt_field(val->from,4,asn1_decode_kerberos_time,0);
647
 
    get_field(val->till,5,asn1_decode_kerberos_time);
648
 
    opt_field(val->rtime,6,asn1_decode_kerberos_time,0);
649
 
    get_field(val->nonce,7,asn1_decode_int32);
650
 
    get_lenfield(val->nktypes,val->ktype,8,asn1_decode_sequence_of_enctype);
651
 
    opt_field(val->addresses,9,asn1_decode_host_addresses,0);
652
 
    if(tagnum == 10){
653
 
      get_field(val->authorization_data,10,asn1_decode_encrypted_data); }
654
 
    else{
655
 
      val->authorization_data.magic = KV5M_ENC_DATA;
656
 
      val->authorization_data.enctype = 0;
657
 
      val->authorization_data.kvno = 0;
658
 
      val->authorization_data.ciphertext.data = NULL;
659
 
      val->authorization_data.ciphertext.length = 0;
660
 
    }
661
 
    opt_field(val->second_ticket,11,asn1_decode_sequence_of_ticket,NULL);
662
 
    end_structure();
663
 
    val->magic = KV5M_KDC_REQ;
664
 
  }
665
 
  cleanup();
 
759
        /* If opt_field server is missing, memory reference to server is
 
760
           lost and results in memory leak */
 
761
        psave = val->server;
 
762
        opt_field(val->server,3,asn1_decode_principal_name,NULL);
 
763
        if (val->server == NULL) {
 
764
            if (psave->realm.data) {
 
765
                free(psave->realm.data);
 
766
                psave->realm.data = NULL;
 
767
                psave->realm.length=0;
 
768
            }
 
769
            free(psave);
 
770
        }
 
771
        opt_field(val->from,4,asn1_decode_kerberos_time,0);
 
772
        get_field(val->till,5,asn1_decode_kerberos_time);
 
773
        opt_field(val->rtime,6,asn1_decode_kerberos_time,0);
 
774
        get_field(val->nonce,7,asn1_decode_int32);
 
775
        get_lenfield(val->nktypes,val->ktype,8,asn1_decode_sequence_of_enctype);
 
776
        opt_field(val->addresses,9,asn1_decode_host_addresses,0);
 
777
        if (tagnum == 10) {
 
778
            get_field(val->authorization_data,10,asn1_decode_encrypted_data); }
 
779
        else {
 
780
            val->authorization_data.magic = KV5M_ENC_DATA;
 
781
            val->authorization_data.enctype = 0;
 
782
            val->authorization_data.kvno = 0;
 
783
            val->authorization_data.ciphertext.data = NULL;
 
784
            val->authorization_data.ciphertext.length = 0;
 
785
        }
 
786
        opt_field(val->second_ticket,11,asn1_decode_sequence_of_ticket,NULL);
 
787
        end_structure();
 
788
        val->magic = KV5M_KDC_REQ;
 
789
    }
 
790
    return 0;
 
791
error_out:
 
792
    krb5_free_principal(NULL, val->client);
 
793
    krb5_free_principal(NULL, val->server);
 
794
    free(val->ktype);
 
795
    krb5_free_addresses(NULL, val->addresses);
 
796
    krb5_free_data_contents(NULL, &val->authorization_data.ciphertext);
 
797
    krb5_free_tickets(NULL, val->second_ticket);
 
798
    val->client = NULL;
 
799
    val->server = NULL;
 
800
    val->ktype = NULL;
 
801
    val->addresses = NULL;
 
802
    val->unenc_authdata = NULL;
 
803
    val->second_ticket = NULL;
 
804
    return retval;
666
805
}
667
806
 
668
807
asn1_error_code asn1_decode_krb_safe_body(asn1buf *buf, krb5_safe *val)
669
808
{
670
 
  setup();
671
 
  { begin_structure();
672
 
    get_lenfield(val->user_data.length,val->user_data.data,0,asn1_decode_charstring);
673
 
    opt_field(val->timestamp,1,asn1_decode_kerberos_time,0);
674
 
    opt_field(val->usec,2,asn1_decode_int32,0);
675
 
    opt_field(val->seq_number,3,asn1_decode_seqnum,0);
676
 
    alloc_field(val->s_address,krb5_address);
677
 
    get_field(*(val->s_address),4,asn1_decode_host_address);
678
 
    if(tagnum == 5){
679
 
      alloc_field(val->r_address,krb5_address);
680
 
      get_field(*(val->r_address),5,asn1_decode_host_address);
681
 
    } else val->r_address = NULL;
682
 
    end_structure();
683
 
    val->magic = KV5M_SAFE;
684
 
  }
685
 
  cleanup();
 
809
    setup();
 
810
    val->user_data.data = NULL;
 
811
    val->r_address = NULL;
 
812
    val->s_address = NULL;
 
813
    val->checksum = NULL;
 
814
    { begin_structure();
 
815
        get_lenfield(val->user_data.length,val->user_data.data,0,asn1_decode_charstring);
 
816
        opt_field(val->timestamp,1,asn1_decode_kerberos_time,0);
 
817
        opt_field(val->usec,2,asn1_decode_int32,0);
 
818
        opt_field(val->seq_number,3,asn1_decode_seqnum,0);
 
819
        get_field(val->s_address,4,asn1_decode_host_address_ptr);
 
820
        if (tagnum == 5) {
 
821
            get_field(val->r_address,5,asn1_decode_host_address_ptr);
 
822
        }
 
823
        end_structure();
 
824
        val->magic = KV5M_SAFE;
 
825
    }
 
826
    return 0;
 
827
error_out:
 
828
    krb5_free_data_contents(NULL, &val->user_data);
 
829
    krb5_free_address(NULL, val->r_address);
 
830
    krb5_free_address(NULL, val->s_address);
 
831
    val->r_address = NULL;
 
832
    val->s_address = NULL;
 
833
    return retval;
686
834
}
687
835
 
688
836
asn1_error_code asn1_decode_host_address(asn1buf *buf, krb5_address *val)
689
837
{
690
 
  setup();
691
 
  { begin_structure();
692
 
    get_field(val->addrtype,0,asn1_decode_addrtype);
693
 
    get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
694
 
    end_structure();
695
 
    val->magic = KV5M_ADDRESS;
696
 
  }
697
 
  cleanup();
 
838
    setup();
 
839
    val->contents = NULL;
 
840
    { begin_structure();
 
841
        get_field(val->addrtype,0,asn1_decode_addrtype);
 
842
        get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
 
843
        end_structure();
 
844
        val->magic = KV5M_ADDRESS;
 
845
    }
 
846
    return 0;
 
847
error_out:
 
848
    free(val->contents);
 
849
    val->contents = NULL;
 
850
    return retval;
 
851
}
 
852
 
 
853
asn1_error_code
 
854
asn1_decode_host_address_ptr(asn1buf *buf, krb5_address **valptr)
 
855
{
 
856
    decode_ptr(krb5_address *, asn1_decode_host_address);
698
857
}
699
858
 
700
859
asn1_error_code asn1_decode_kdc_rep(asn1buf *buf, krb5_kdc_rep *val)
701
860
{
702
 
  setup();
703
 
  { begin_structure();
704
 
    { krb5_kvno pvno;
705
 
      get_field(pvno,0,asn1_decode_kvno);
706
 
      if(pvno != KVNO) return KRB5KDC_ERR_BAD_PVNO; }
707
 
    get_field(val->msg_type,1,asn1_decode_msgtype);
708
 
    opt_field(val->padata,2,asn1_decode_sequence_of_pa_data,NULL);
709
 
    alloc_field(val->client,krb5_principal_data);
710
 
    get_field(val->client,3,asn1_decode_realm);
711
 
    get_field(val->client,4,asn1_decode_principal_name);
712
 
    alloc_field(val->ticket,krb5_ticket);
713
 
    get_field(*(val->ticket),5,asn1_decode_ticket);
714
 
    get_field(val->enc_part,6,asn1_decode_encrypted_data);
715
 
    end_structure();
716
 
    val->magic = KV5M_KDC_REP;
717
 
  }
718
 
  cleanup();
 
861
    setup();
 
862
    val->padata = NULL;
 
863
    val->client = NULL;
 
864
    val->ticket = NULL;
 
865
    val->enc_part.ciphertext.data = NULL;
 
866
    val->enc_part2 = NULL;
 
867
    { begin_structure();
 
868
        { krb5_kvno pvno;
 
869
            get_field(pvno,0,asn1_decode_kvno);
 
870
            if (pvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); }
 
871
        get_field(val->msg_type,1,asn1_decode_msgtype);
 
872
        opt_field(val->padata,2,asn1_decode_sequence_of_pa_data,NULL);
 
873
        alloc_principal(val->client);
 
874
        get_field(val->client,3,asn1_decode_realm);
 
875
        get_field(val->client,4,asn1_decode_principal_name);
 
876
        get_field(val->ticket,5,asn1_decode_ticket_ptr);
 
877
        get_field(val->enc_part,6,asn1_decode_encrypted_data);
 
878
        end_structure();
 
879
        val->magic = KV5M_KDC_REP;
 
880
    }
 
881
    return 0;
 
882
error_out:
 
883
    krb5_free_pa_data(NULL, val->padata);
 
884
    krb5_free_principal(NULL, val->client);
 
885
    krb5_free_ticket(NULL, val->ticket);
 
886
    krb5_free_data_contents(NULL, &val->enc_part.ciphertext);
 
887
    val->padata = NULL;
 
888
    val->client = NULL;
 
889
    val->ticket = NULL;
 
890
    val->enc_part.ciphertext.data = NULL;
 
891
    return retval;
719
892
}
720
893
 
721
894
 
722
895
/* arrays */
723
896
#define get_element(element,decoder)\
724
 
retval = decoder(&seqbuf,element);\
725
 
if(retval) return retval
726
 
     
 
897
retval = decoder(&seqbuf,&element);\
 
898
if (retval) clean_return(retval)
 
899
 
 
900
static void *
 
901
array_expand (void *array, int n_elts, size_t elt_size)
 
902
{
 
903
    size_t new_size;
 
904
 
 
905
    if (n_elts <= 0)
 
906
        return NULL;
 
907
    if ((unsigned int) n_elts > SIZE_MAX / elt_size)
 
908
        return NULL;
 
909
    new_size = n_elts * elt_size;
 
910
    if (new_size == 0)
 
911
        return NULL;
 
912
    if (new_size / elt_size != (unsigned int) n_elts)
 
913
        return NULL;
 
914
    return realloc(array, new_size);
 
915
}
 
916
 
727
917
#define array_append(array,size,element,type)\
728
 
size++;\
729
 
if (*(array) == NULL)\
730
 
     *(array) = (type**)malloc((size+1)*sizeof(type*));\
731
 
else\
732
 
  *(array) = (type**)realloc(*(array),\
733
 
                             (size+1)*sizeof(type*));\
734
 
if(*(array) == NULL) return ENOMEM;\
735
 
(*(array))[(size)-1] = elt
736
 
     
737
 
#define decode_array_body(type,decoder)\
 
918
  {\
 
919
    void *new_array = array_expand(*(array), (size)+2, sizeof(type*));\
 
920
    if (new_array == NULL) clean_return(ENOMEM);\
 
921
    *(array) = new_array;\
 
922
    (*(array))[(size)++] = elt;\
 
923
  }
 
924
 
 
925
/*
 
926
 * Function body for array decoders.  freefn is expected to look like
 
927
 * a krb5_free_ function, so we pass a null first argument.
 
928
 */
 
929
#define decode_array_body(type,decoder,freefn)\
738
930
  asn1_error_code retval;\
739
 
  type *elt;\
 
931
  type *elt = NULL, **array;\
 
932
  int size = 0, i; \
740
933
\
 
934
  array = *val = NULL;\
741
935
  { sequence_of(buf);\
742
 
    while(asn1buf_remains(&seqbuf,seqofindef) > 0){\
743
 
      alloc_field(elt,type);\
 
936
    while (asn1buf_remains(&seqbuf,seqofindef) > 0) {\
744
937
      get_element(elt,decoder);\
745
 
      array_append(val,size,elt,type);\
 
938
      array_append(&array,size,elt,type);\
 
939
      elt = NULL;\
746
940
    }\
747
 
    if (*val == NULL)\
748
 
        *val = (type **)malloc(sizeof(type*));\
749
 
    (*val)[size] = NULL;\
 
941
    if (array == NULL)\
 
942
        array = malloc(sizeof(type*));\
 
943
    array[size] = NULL;\
750
944
    end_sequence_of(buf);\
751
945
  }\
752
 
  cleanup()
 
946
  *val = array;\
 
947
  return 0;\
 
948
error_out:\
 
949
  if (elt)\
 
950
      freefn(NULL,elt);\
 
951
  for (i = 0; i < size; i++)\
 
952
      freefn(NULL,array[i]);\
 
953
  free(array);\
 
954
  return retval
753
955
 
 
956
static void free_authdata_elt(void *dummy, krb5_authdata *val)
 
957
{
 
958
    free(val->contents);
 
959
    free(val);
 
960
}
754
961
 
755
962
asn1_error_code asn1_decode_authorization_data(asn1buf *buf, krb5_authdata ***val)
756
963
{
757
 
  decode_array_body(krb5_authdata,asn1_decode_authdata_elt);
 
964
    decode_array_body(krb5_authdata,asn1_decode_authdata_elt_ptr,
 
965
                      free_authdata_elt);
758
966
}
759
967
 
760
968
asn1_error_code asn1_decode_authdata_elt(asn1buf *buf, krb5_authdata *val)
761
969
{
762
 
  setup();
763
 
  { begin_structure();
764
 
    get_field(val->ad_type,0,asn1_decode_authdatatype);
765
 
    get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
766
 
    end_structure();
767
 
    val->magic = KV5M_AUTHDATA;
768
 
  }
769
 
  cleanup();
 
970
    setup();
 
971
    val->contents = NULL;
 
972
    { begin_structure();
 
973
        get_field(val->ad_type,0,asn1_decode_authdatatype);
 
974
        get_lenfield(val->length,val->contents,1,asn1_decode_octetstring);
 
975
        end_structure();
 
976
        val->magic = KV5M_AUTHDATA;
 
977
    }
 
978
    return 0;
 
979
error_out:
 
980
    free(val->contents);
 
981
    val->contents = NULL;
 
982
    return retval;
 
983
}
 
984
 
 
985
asn1_error_code
 
986
asn1_decode_authdata_elt_ptr(asn1buf *buf, krb5_authdata **valptr)
 
987
{
 
988
    decode_ptr(krb5_authdata *, asn1_decode_authdata_elt);
770
989
}
771
990
 
772
991
asn1_error_code asn1_decode_host_addresses(asn1buf *buf, krb5_address ***val)
773
992
{
774
 
  decode_array_body(krb5_address,asn1_decode_host_address);
 
993
    decode_array_body(krb5_address,asn1_decode_host_address_ptr,
 
994
                      krb5_free_address);
775
995
}
776
996
 
777
997
asn1_error_code asn1_decode_sequence_of_ticket(asn1buf *buf, krb5_ticket ***val)
778
998
{
779
 
  decode_array_body(krb5_ticket,asn1_decode_ticket);
 
999
    decode_array_body(krb5_ticket,asn1_decode_ticket_ptr,krb5_free_ticket);
 
1000
}
 
1001
 
 
1002
static void free_cred_info(void *dummy, krb5_cred_info *val)
 
1003
{
 
1004
    krb5_free_keyblock(NULL, val->session);
 
1005
    krb5_free_principal(NULL, val->client);
 
1006
    krb5_free_principal(NULL, val->server);
 
1007
    krb5_free_addresses(NULL, val->caddrs);
 
1008
    free(val);
780
1009
}
781
1010
 
782
1011
asn1_error_code asn1_decode_sequence_of_krb_cred_info(asn1buf *buf, krb5_cred_info ***val)
783
1012
{
784
 
  decode_array_body(krb5_cred_info,asn1_decode_krb_cred_info);
 
1013
    decode_array_body(krb5_cred_info,asn1_decode_krb_cred_info_ptr,
 
1014
                      free_cred_info);
785
1015
}
786
1016
 
787
1017
asn1_error_code asn1_decode_krb_cred_info(asn1buf *buf, krb5_cred_info *val)
788
1018
{
789
 
  setup();
790
 
  { begin_structure();
791
 
    alloc_field(val->session,krb5_keyblock);
792
 
    get_field(*(val->session),0,asn1_decode_encryption_key);
793
 
    if(tagnum == 1){
794
 
      alloc_field(val->client,krb5_principal_data);
795
 
      opt_field(val->client,1,asn1_decode_realm,NULL);
796
 
      opt_field(val->client,2,asn1_decode_principal_name,NULL); }
797
 
    opt_field(val->flags,3,asn1_decode_ticket_flags,0);
798
 
    opt_field(val->times.authtime,4,asn1_decode_kerberos_time,0);
799
 
    opt_field(val->times.starttime,5,asn1_decode_kerberos_time,0);
800
 
    opt_field(val->times.endtime,6,asn1_decode_kerberos_time,0);
801
 
    opt_field(val->times.renew_till,7,asn1_decode_kerberos_time,0);
802
 
    if(tagnum == 8){
803
 
      alloc_field(val->server,krb5_principal_data);
804
 
      opt_field(val->server,8,asn1_decode_realm,NULL);
805
 
      opt_field(val->server,9,asn1_decode_principal_name,NULL); }
806
 
    opt_field(val->caddrs,10,asn1_decode_host_addresses,NULL);
807
 
    end_structure();
808
 
    val->magic = KV5M_CRED_INFO;
809
 
  }
810
 
  cleanup();
 
1019
    setup();
 
1020
    val->session = NULL;
 
1021
    val->client = NULL;
 
1022
    val->server = NULL;
 
1023
    val->caddrs = NULL;
 
1024
    { begin_structure();
 
1025
        get_field(val->session,0,asn1_decode_encryption_key_ptr);
 
1026
        if (tagnum == 1) {
 
1027
            alloc_principal(val->client);
 
1028
            opt_field(val->client,1,asn1_decode_realm,NULL);
 
1029
            opt_field(val->client,2,asn1_decode_principal_name,NULL); }
 
1030
        opt_field(val->flags,3,asn1_decode_ticket_flags,0);
 
1031
        opt_field(val->times.authtime,4,asn1_decode_kerberos_time,0);
 
1032
        opt_field(val->times.starttime,5,asn1_decode_kerberos_time,0);
 
1033
        opt_field(val->times.endtime,6,asn1_decode_kerberos_time,0);
 
1034
        opt_field(val->times.renew_till,7,asn1_decode_kerberos_time,0);
 
1035
        if (tagnum == 8) {
 
1036
            alloc_principal(val->server);
 
1037
            opt_field(val->server,8,asn1_decode_realm,NULL);
 
1038
            opt_field(val->server,9,asn1_decode_principal_name,NULL); }
 
1039
        opt_field(val->caddrs,10,asn1_decode_host_addresses,NULL);
 
1040
        end_structure();
 
1041
        val->magic = KV5M_CRED_INFO;
 
1042
    }
 
1043
    return 0;
 
1044
error_out:
 
1045
    krb5_free_keyblock(NULL, val->session);
 
1046
    krb5_free_principal(NULL, val->client);
 
1047
    krb5_free_principal(NULL, val->server);
 
1048
    krb5_free_addresses(NULL, val->caddrs);
 
1049
    val->session = NULL;
 
1050
    val->client = NULL;
 
1051
    val->server = NULL;
 
1052
    val->caddrs = NULL;
 
1053
    return retval;
 
1054
}
 
1055
 
 
1056
asn1_error_code
 
1057
asn1_decode_krb_cred_info_ptr(asn1buf *buf, krb5_cred_info **valptr)
 
1058
{
 
1059
    decode_ptr(krb5_cred_info *, asn1_decode_krb_cred_info);
 
1060
}
 
1061
 
 
1062
static void free_pa_data(void *dummy, krb5_pa_data *val)
 
1063
{
 
1064
    free(val->contents);
 
1065
    free(val);
811
1066
}
812
1067
 
813
1068
asn1_error_code asn1_decode_sequence_of_pa_data(asn1buf *buf, krb5_pa_data ***val)
814
1069
{
815
 
  decode_array_body(krb5_pa_data,asn1_decode_pa_data);
 
1070
    decode_array_body(krb5_pa_data,asn1_decode_pa_data_ptr,free_pa_data);
816
1071
}
817
1072
 
818
1073
asn1_error_code asn1_decode_pa_data(asn1buf *buf, krb5_pa_data *val)
819
1074
{
820
 
  setup();
821
 
  { begin_structure();
822
 
    get_field(val->pa_type,1,asn1_decode_int32);
823
 
    get_lenfield(val->length,val->contents,2,asn1_decode_octetstring);
824
 
    end_structure();
825
 
    val->magic = KV5M_PA_DATA;
826
 
  }
827
 
  cleanup();
 
1075
    setup();
 
1076
    val->contents = NULL;
 
1077
    { begin_structure();
 
1078
        get_field(val->pa_type,1,asn1_decode_int32);
 
1079
        get_lenfield(val->length,val->contents,2,asn1_decode_octetstring);
 
1080
        end_structure();
 
1081
        val->magic = KV5M_PA_DATA;
 
1082
    }
 
1083
    return 0;
 
1084
error_out:
 
1085
    free(val->contents);
 
1086
    val->contents = NULL;
 
1087
    return retval;
 
1088
}
 
1089
 
 
1090
asn1_error_code asn1_decode_pa_data_ptr(asn1buf *buf, krb5_pa_data **valptr)
 
1091
{
 
1092
    decode_ptr(krb5_pa_data *, asn1_decode_pa_data);
 
1093
}
 
1094
 
 
1095
static void free_last_req_entry(void *dummy, krb5_last_req_entry *val)
 
1096
{
 
1097
    free(val);
828
1098
}
829
1099
 
830
1100
asn1_error_code asn1_decode_last_req(asn1buf *buf, krb5_last_req_entry ***val)
831
1101
{
832
 
  decode_array_body(krb5_last_req_entry,asn1_decode_last_req_entry);
 
1102
    decode_array_body(krb5_last_req_entry,asn1_decode_last_req_entry_ptr,
 
1103
                      free_last_req_entry);
833
1104
}
834
1105
 
835
1106
asn1_error_code asn1_decode_last_req_entry(asn1buf *buf, krb5_last_req_entry *val)
836
1107
{
837
 
  setup();
838
 
  { begin_structure();
839
 
    get_field(val->lr_type,0,asn1_decode_int32);
840
 
    get_field(val->value,1,asn1_decode_kerberos_time);
841
 
    end_structure();
842
 
    val->magic = KV5M_LAST_REQ_ENTRY;
 
1108
    setup();
 
1109
    { begin_structure();
 
1110
        get_field(val->lr_type,0,asn1_decode_int32);
 
1111
        get_field(val->value,1,asn1_decode_kerberos_time);
 
1112
        end_structure();
 
1113
        val->magic = KV5M_LAST_REQ_ENTRY;
843
1114
#ifdef KRB5_GENEROUS_LR_TYPE
844
 
    /* If we are only a single byte wide and negative - fill in the
845
 
       other bits */
846
 
    if((val->lr_type & 0xffffff80U) == 0x80) val->lr_type |= 0xffffff00U;
 
1115
        /* If we are only a single byte wide and negative - fill in the
 
1116
           other bits */
 
1117
        if ((val->lr_type & 0xffffff80U) == 0x80) val->lr_type |= 0xffffff00U;
847
1118
#endif
848
 
  }
849
 
  cleanup();
 
1119
    }
 
1120
    return 0;
 
1121
error_out:
 
1122
    return retval;
 
1123
}
 
1124
 
 
1125
asn1_error_code
 
1126
asn1_decode_last_req_entry_ptr(asn1buf *buf, krb5_last_req_entry **valptr)
 
1127
{
 
1128
    decode_ptr(krb5_last_req_entry *, asn1_decode_last_req_entry);
850
1129
}
851
1130
 
852
1131
asn1_error_code asn1_decode_sequence_of_enctype(asn1buf *buf, int *num, krb5_enctype **val)
853
1132
{
854
 
  asn1_error_code retval;
855
 
  { sequence_of(buf);
856
 
    while(asn1buf_remains(&seqbuf,seqofindef) > 0){
857
 
      size++;
858
 
      if (*val == NULL)
859
 
        *val = (krb5_enctype*)malloc(size*sizeof(krb5_enctype));
860
 
      else
861
 
        *val = (krb5_enctype*)realloc(*val,size*sizeof(krb5_enctype));
862
 
      if(*val == NULL) return ENOMEM;
863
 
      retval = asn1_decode_enctype(&seqbuf,&((*val)[size-1]));
864
 
      if(retval) return retval;
 
1133
    int size = 0;
 
1134
    krb5_enctype *array = NULL, *new_array;
 
1135
 
 
1136
    asn1_error_code retval;
 
1137
    { sequence_of(buf);
 
1138
        while (asn1buf_remains(&seqbuf,seqofindef) > 0) {
 
1139
            size++;
 
1140
            new_array = realloc(array,size*sizeof(krb5_enctype));
 
1141
            if (new_array == NULL) clean_return(ENOMEM);
 
1142
            array = new_array;
 
1143
            retval = asn1_decode_enctype(&seqbuf,&array[size-1]);
 
1144
            if (retval) clean_return(retval);
 
1145
        }
 
1146
        end_sequence_of(buf);
865
1147
    }
866
1148
    *num = size;
867
 
    end_sequence_of(buf);
868
 
  }
869
 
  cleanup();
 
1149
    *val = array;
 
1150
    return 0;
 
1151
error_out:
 
1152
    free(array);
 
1153
    return retval;
870
1154
}
871
1155
 
872
1156
asn1_error_code asn1_decode_sequence_of_checksum(asn1buf *buf, krb5_checksum ***val)
873
1157
{
874
 
  decode_array_body(krb5_checksum, asn1_decode_checksum);
 
1158
    decode_array_body(krb5_checksum, asn1_decode_checksum_ptr,
 
1159
                      krb5_free_checksum);
 
1160
}
 
1161
 
 
1162
static void free_etype_info_entry(void *dummy, krb5_etype_info_entry *val)
 
1163
{
 
1164
    krb5_free_data_contents(NULL, &val->s2kparams);
 
1165
    free(val->salt);
 
1166
    free(val);
875
1167
}
876
1168
 
877
1169
static asn1_error_code asn1_decode_etype_info2_entry(asn1buf *buf, krb5_etype_info_entry *val )
878
1170
{
879
 
  setup();
880
 
  { begin_structure();
881
 
    get_field(val->etype,0,asn1_decode_enctype);
882
 
    if (tagnum == 1) {
883
 
            get_lenfield(val->length,val->salt,1,asn1_decode_generalstring);
884
 
    } else {
885
 
            val->length = KRB5_ETYPE_NO_SALT;
886
 
            val->salt = 0;
887
 
    }
888
 
    if ( tagnum ==2) {
889
 
      krb5_octet *params ;
890
 
      get_lenfield( val->s2kparams.length, params,
891
 
                      2, asn1_decode_octetstring);
892
 
      val->s2kparams.data = ( char *) params;
893
 
    } else {
894
 
        val->s2kparams.data = NULL;
895
 
        val->s2kparams.length = 0;
896
 
    }
897
 
    end_structure();
898
 
    val->magic = KV5M_ETYPE_INFO_ENTRY;
899
 
  }
900
 
  cleanup();
 
1171
    char *salt = NULL;
 
1172
    krb5_octet *params = NULL;
 
1173
    setup();
 
1174
    val->salt = NULL;
 
1175
    val->s2kparams.data = NULL;
 
1176
    { begin_structure();
 
1177
        get_field(val->etype,0,asn1_decode_enctype);
 
1178
        if (tagnum == 1) {
 
1179
            get_lenfield(val->length,salt,1,asn1_decode_generalstring);
 
1180
            val->salt = (krb5_octet *) salt;
 
1181
            salt = NULL;
 
1182
        } else
 
1183
            val->length = KRB5_ETYPE_NO_SALT;
 
1184
        if ( tagnum ==2) {
 
1185
            get_lenfield( val->s2kparams.length, params,
 
1186
                          2, asn1_decode_octetstring);
 
1187
            val->s2kparams.data = ( char *) params;
 
1188
            params = NULL;
 
1189
        } else
 
1190
            val->s2kparams.length = 0;
 
1191
        end_structure();
 
1192
        val->magic = KV5M_ETYPE_INFO_ENTRY;
 
1193
    }
 
1194
    return 0;
 
1195
error_out:
 
1196
    free(salt);
 
1197
    free(params);
 
1198
    krb5_free_data_contents(NULL, &val->s2kparams);
 
1199
    free(val->salt);
 
1200
    val->salt = NULL;
 
1201
    return retval;
 
1202
}
 
1203
 
 
1204
static asn1_error_code
 
1205
asn1_decode_etype_info2_entry_ptr(asn1buf *buf, krb5_etype_info_entry **valptr)
 
1206
{
 
1207
    decode_ptr(krb5_etype_info_entry *, asn1_decode_etype_info2_entry);
901
1208
}
902
1209
 
903
1210
static asn1_error_code asn1_decode_etype_info2_entry_1_3(asn1buf *buf, krb5_etype_info_entry *val )
904
1211
{
905
 
  setup();
906
 
  { begin_structure();
907
 
    get_field(val->etype,0,asn1_decode_enctype);
908
 
    if (tagnum == 1) {
909
 
            get_lenfield(val->length,val->salt,1,asn1_decode_octetstring);
910
 
    } else {
911
 
            val->length = KRB5_ETYPE_NO_SALT;
912
 
            val->salt = 0;
913
 
    }
914
 
    if ( tagnum ==2) {
915
 
      krb5_octet *params ;
916
 
      get_lenfield( val->s2kparams.length, params,
917
 
                      2, asn1_decode_octetstring);
918
 
      val->s2kparams.data = ( char *) params;
919
 
    } else {
920
 
        val->s2kparams.data = NULL;
921
 
        val->s2kparams.length = 0;
922
 
    }
923
 
    end_structure();
924
 
    val->magic = KV5M_ETYPE_INFO_ENTRY;
925
 
  }
926
 
  cleanup();
 
1212
    setup();
 
1213
    val->salt = NULL;
 
1214
    val->s2kparams.data = NULL;
 
1215
    { begin_structure();
 
1216
        get_field(val->etype,0,asn1_decode_enctype);
 
1217
        if (tagnum == 1) {
 
1218
            get_lenfield(val->length,val->salt,1,asn1_decode_octetstring);
 
1219
        } else
 
1220
            val->length = KRB5_ETYPE_NO_SALT;
 
1221
        if ( tagnum ==2) {
 
1222
            krb5_octet *params ;
 
1223
            get_lenfield( val->s2kparams.length, params,
 
1224
                          2, asn1_decode_octetstring);
 
1225
            val->s2kparams.data = ( char *) params;
 
1226
        } else
 
1227
            val->s2kparams.length = 0;
 
1228
        end_structure();
 
1229
        val->magic = KV5M_ETYPE_INFO_ENTRY;
 
1230
    }
 
1231
    return 0;
 
1232
error_out:
 
1233
    krb5_free_data_contents(NULL, &val->s2kparams);
 
1234
    free(val->salt);
 
1235
    val->salt = NULL;
 
1236
    return retval;
927
1237
}
928
1238
 
 
1239
static asn1_error_code
 
1240
asn1_decode_etype_info2_entry_1_3_ptr(asn1buf *buf,
 
1241
                                      krb5_etype_info_entry **valptr)
 
1242
{
 
1243
    decode_ptr(krb5_etype_info_entry *, asn1_decode_etype_info2_entry_1_3);
 
1244
}
929
1245
 
930
1246
static asn1_error_code asn1_decode_etype_info_entry(asn1buf *buf, krb5_etype_info_entry *val )
931
1247
{
932
 
  setup();
933
 
  { begin_structure();
934
 
    get_field(val->etype,0,asn1_decode_enctype);
935
 
    if (tagnum == 1) {
936
 
            get_lenfield(val->length,val->salt,1,asn1_decode_octetstring);
937
 
    } else {
938
 
            val->length = KRB5_ETYPE_NO_SALT;
939
 
            val->salt = 0;
 
1248
    setup();
 
1249
    val->salt = NULL;
 
1250
    val->s2kparams.data = NULL;
 
1251
    { begin_structure();
 
1252
        get_field(val->etype,0,asn1_decode_enctype);
 
1253
        if (tagnum == 1) {
 
1254
            get_lenfield(val->length,val->salt,1,asn1_decode_octetstring);
 
1255
        } else
 
1256
            val->length = KRB5_ETYPE_NO_SALT;
 
1257
        val->s2kparams.length = 0;
 
1258
 
 
1259
        end_structure();
 
1260
        val->magic = KV5M_ETYPE_INFO_ENTRY;
940
1261
    }
941
 
    val->s2kparams.data = NULL;
942
 
    val->s2kparams.length = 0;
943
 
    
944
 
    end_structure();
945
 
    val->magic = KV5M_ETYPE_INFO_ENTRY;
946
 
  }
947
 
  cleanup();
 
1262
    return 0;
 
1263
error_out:
 
1264
    free(val->salt);
 
1265
    val->salt = NULL;
 
1266
    return retval;
 
1267
}
 
1268
 
 
1269
static asn1_error_code
 
1270
asn1_decode_etype_info_entry_ptr(asn1buf *buf, krb5_etype_info_entry **valptr)
 
1271
{
 
1272
    decode_ptr(krb5_etype_info_entry *, asn1_decode_etype_info_entry);
948
1273
}
949
1274
 
950
1275
asn1_error_code asn1_decode_etype_info(asn1buf *buf, krb5_etype_info_entry ***val )
951
1276
{
952
 
  decode_array_body(krb5_etype_info_entry,asn1_decode_etype_info_entry);
 
1277
    decode_array_body(krb5_etype_info_entry,asn1_decode_etype_info_entry_ptr,
 
1278
                      free_etype_info_entry);
 
1279
}
 
1280
 
 
1281
static asn1_error_code decode_etype_info2_13(asn1buf *buf, krb5_etype_info_entry ***val)
 
1282
{
 
1283
    decode_array_body(krb5_etype_info_entry,
 
1284
                      asn1_decode_etype_info2_entry_1_3_ptr,
 
1285
                      free_etype_info_entry);
953
1286
}
954
1287
 
955
1288
asn1_error_code asn1_decode_etype_info2(asn1buf *buf, krb5_etype_info_entry ***val ,
956
 
                                        krb5_boolean v1_3_behavior)
 
1289
                                        krb5_boolean v1_3_behavior)
957
1290
{
958
 
    if (v1_3_behavior) {
959
 
        decode_array_body(krb5_etype_info_entry,
960
 
                          asn1_decode_etype_info2_entry_1_3);
961
 
    } else {
962
 
        decode_array_body(krb5_etype_info_entry,
963
 
                          asn1_decode_etype_info2_entry);
 
1291
    if (v1_3_behavior)
 
1292
        return decode_etype_info2_13(buf, val);
 
1293
    else {
 
1294
        decode_array_body(krb5_etype_info_entry,
 
1295
                          asn1_decode_etype_info2_entry_ptr,
 
1296
                          free_etype_info_entry);
964
1297
    }
965
1298
}
966
1299
 
967
1300
asn1_error_code asn1_decode_passwdsequence(asn1buf *buf, passwd_phrase_element *val)
968
1301
{
969
 
  setup();
970
 
  { begin_structure();
971
 
    alloc_field(val->passwd,krb5_data);
972
 
    get_lenfield(val->passwd->length,val->passwd->data,
973
 
                 0,asn1_decode_charstring);
974
 
    val->passwd->magic = KV5M_DATA;
975
 
    alloc_field(val->phrase,krb5_data);
976
 
    get_lenfield(val->phrase->length,val->phrase->data,
977
 
                 1,asn1_decode_charstring);
978
 
    val->phrase->magic = KV5M_DATA;
979
 
    end_structure();
980
 
    val->magic = KV5M_PASSWD_PHRASE_ELEMENT;
981
 
  }
982
 
  cleanup();
 
1302
    setup();
 
1303
    val->passwd = NULL;
 
1304
    val->phrase = NULL;
 
1305
    { begin_structure();
 
1306
        alloc_data(val->passwd);
 
1307
        get_lenfield(val->passwd->length,val->passwd->data,
 
1308
                     0,asn1_decode_charstring);
 
1309
        val->passwd->magic = KV5M_DATA;
 
1310
        alloc_data(val->phrase);
 
1311
        get_lenfield(val->phrase->length,val->phrase->data,
 
1312
                     1,asn1_decode_charstring);
 
1313
        val->phrase->magic = KV5M_DATA;
 
1314
        end_structure();
 
1315
        val->magic = KV5M_PASSWD_PHRASE_ELEMENT;
 
1316
    }
 
1317
    return 0;
 
1318
error_out:
 
1319
    krb5_free_data(NULL, val->passwd);
 
1320
    krb5_free_data(NULL, val->phrase);
 
1321
    val->passwd = NULL;
 
1322
    val->phrase = NULL;
 
1323
    return 0;
 
1324
}
 
1325
 
 
1326
asn1_error_code
 
1327
asn1_decode_passwdsequence_ptr(asn1buf *buf, passwd_phrase_element **valptr)
 
1328
{
 
1329
    decode_ptr(passwd_phrase_element *, asn1_decode_passwdsequence);
983
1330
}
984
1331
 
985
1332
asn1_error_code asn1_decode_sequence_of_passwdsequence(asn1buf *buf, passwd_phrase_element ***val)
986
1333
{
987
 
  decode_array_body(passwd_phrase_element,asn1_decode_passwdsequence);
 
1334
    decode_array_body(passwd_phrase_element,asn1_decode_passwdsequence_ptr,
 
1335
                      krb5_free_passwd_phrase_element);
988
1336
}
989
1337
 
990
1338
asn1_error_code asn1_decode_sam_flags(asn1buf *buf, krb5_flags *val)
992
1340
 
993
1341
#define opt_string(val,n,fn) opt_lenfield((val).length,(val).data,n,fn)
994
1342
#define opt_cksum(var,tagexpect,decoder)\
995
 
if(tagnum == (tagexpect)){\
 
1343
if (tagnum == (tagexpect)) {\
996
1344
  get_field_body(var,decoder); }\
997
1345
else var.length = 0
998
1346
 
999
1347
asn1_error_code asn1_decode_sam_challenge(asn1buf *buf, krb5_sam_challenge *val)
1000
1348
{
1001
 
  setup();
1002
 
  { begin_structure();
1003
 
    get_field(val->sam_type,0,asn1_decode_int32);
1004
 
    get_field(val->sam_flags,1,asn1_decode_sam_flags);
1005
 
    opt_string(val->sam_type_name,2,asn1_decode_charstring);
1006
 
    opt_string(val->sam_track_id,3,asn1_decode_charstring);
1007
 
    opt_string(val->sam_challenge_label,4,asn1_decode_charstring);
1008
 
    opt_string(val->sam_challenge,5,asn1_decode_charstring);
1009
 
    opt_string(val->sam_response_prompt,6,asn1_decode_charstring);
1010
 
    opt_string(val->sam_pk_for_sad,7,asn1_decode_charstring);
1011
 
    opt_field(val->sam_nonce,8,asn1_decode_int32,0);
1012
 
    opt_cksum(val->sam_cksum,9,asn1_decode_checksum);
1013
 
    end_structure();
1014
 
    val->magic = KV5M_SAM_CHALLENGE;
1015
 
  }
1016
 
  cleanup();
 
1349
    setup();
 
1350
    val->sam_type_name.data = NULL;
 
1351
    val->sam_track_id.data = NULL;
 
1352
    val->sam_challenge_label.data = NULL;
 
1353
    val->sam_response_prompt.data = NULL;
 
1354
    val->sam_pk_for_sad.data = NULL;
 
1355
    val->sam_cksum.contents = NULL;
 
1356
    { begin_structure();
 
1357
        get_field(val->sam_type,0,asn1_decode_int32);
 
1358
        get_field(val->sam_flags,1,asn1_decode_sam_flags);
 
1359
        opt_string(val->sam_type_name,2,asn1_decode_charstring);
 
1360
        opt_string(val->sam_track_id,3,asn1_decode_charstring);
 
1361
        opt_string(val->sam_challenge_label,4,asn1_decode_charstring);
 
1362
        opt_string(val->sam_challenge,5,asn1_decode_charstring);
 
1363
        opt_string(val->sam_response_prompt,6,asn1_decode_charstring);
 
1364
        opt_string(val->sam_pk_for_sad,7,asn1_decode_charstring);
 
1365
        opt_field(val->sam_nonce,8,asn1_decode_int32,0);
 
1366
        opt_cksum(val->sam_cksum,9,asn1_decode_checksum);
 
1367
        end_structure();
 
1368
        val->magic = KV5M_SAM_CHALLENGE;
 
1369
    }
 
1370
    return 0;
 
1371
error_out:
 
1372
    krb5_free_sam_challenge_contents(NULL, val);
 
1373
    return retval;
1017
1374
}
1018
1375
asn1_error_code asn1_decode_sam_challenge_2(asn1buf *buf, krb5_sam_challenge_2 *val)
1019
1376
{
1020
 
  setup();
1021
 
  { char *save, *end;
1022
 
    size_t alloclen;
1023
 
    begin_structure();
1024
 
    if (tagnum != 0) return ASN1_MISSING_FIELD;
1025
 
    if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) 
1026
 
      return ASN1_BAD_ID;
1027
 
    save = subbuf.next;
1028
 
    { sequence_of_no_tagvars(&subbuf);
1029
 
      unused_var(size);
1030
 
      end_sequence_of_no_tagvars(&subbuf);
1031
 
    }
1032
 
    end = subbuf.next;
1033
 
    alloclen = end - save;
1034
 
    if ((val->sam_challenge_2_body.data = (char *) malloc(alloclen)) == NULL)
1035
 
      return ENOMEM;
1036
 
    val->sam_challenge_2_body.length = alloclen;
1037
 
    memcpy(val->sam_challenge_2_body.data, save, alloclen);
1038
 
    next_tag();
1039
 
    get_field(val->sam_cksum, 1, asn1_decode_sequence_of_checksum);
1040
 
    end_structure();
1041
 
  }
1042
 
  cleanup();
 
1377
    krb5_checksum **cksump;
 
1378
    setup();
 
1379
    val->sam_challenge_2_body.data = NULL;
 
1380
    val->sam_cksum = NULL;
 
1381
    { char *save, *end;
 
1382
        size_t alloclen;
 
1383
        begin_structure();
 
1384
        if (tagnum != 0) clean_return(ASN1_MISSING_FIELD);
 
1385
        if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)
 
1386
            clean_return(ASN1_BAD_ID);
 
1387
        save = subbuf.next;
 
1388
        { sequence_of_no_tagvars(&subbuf);
 
1389
            end_sequence_of_no_tagvars(&subbuf);
 
1390
        }
 
1391
        end = subbuf.next;
 
1392
        alloclen = end - save;
 
1393
        val->sam_challenge_2_body.data = malloc(alloclen);
 
1394
        if (!val->sam_challenge_2_body.data)
 
1395
            clean_return(ENOMEM);
 
1396
        val->sam_challenge_2_body.length = alloclen;
 
1397
        memcpy(val->sam_challenge_2_body.data, save, alloclen);
 
1398
        next_tag();
 
1399
        get_field(val->sam_cksum, 1, asn1_decode_sequence_of_checksum);
 
1400
        end_structure();
 
1401
    }
 
1402
    return 0;
 
1403
error_out:
 
1404
    krb5_free_data_contents(NULL, &val->sam_challenge_2_body);
 
1405
    if (val->sam_cksum) {
 
1406
        for (cksump = val->sam_cksum; *cksump; cksump++)
 
1407
            krb5_free_checksum(NULL, *cksump);
 
1408
        free(val->sam_cksum);
 
1409
        val->sam_cksum = NULL;
 
1410
    }
 
1411
    return retval;
1043
1412
}
1044
1413
asn1_error_code asn1_decode_sam_challenge_2_body(asn1buf *buf, krb5_sam_challenge_2_body *val)
1045
1414
{
1046
 
  setup();
1047
 
  { begin_structure();
1048
 
    get_field(val->sam_type,0,asn1_decode_int32);
1049
 
    get_field(val->sam_flags,1,asn1_decode_sam_flags);
1050
 
    opt_string(val->sam_type_name,2,asn1_decode_charstring);
1051
 
    opt_string(val->sam_track_id,3,asn1_decode_charstring);
1052
 
    opt_string(val->sam_challenge_label,4,asn1_decode_charstring);
1053
 
    opt_string(val->sam_challenge,5,asn1_decode_charstring);
1054
 
    opt_string(val->sam_response_prompt,6,asn1_decode_charstring);
1055
 
    opt_string(val->sam_pk_for_sad,7,asn1_decode_charstring);
1056
 
    get_field(val->sam_nonce,8,asn1_decode_int32);
1057
 
    get_field(val->sam_etype, 9, asn1_decode_int32);
1058
 
    end_structure();
1059
 
    val->magic = KV5M_SAM_CHALLENGE;
1060
 
  }
1061
 
  cleanup();
 
1415
    setup();
 
1416
    val->sam_type_name.data = NULL;
 
1417
    val->sam_track_id.data = NULL;
 
1418
    val->sam_challenge_label.data = NULL;
 
1419
    val->sam_challenge.data = NULL;
 
1420
    val->sam_response_prompt.data = NULL;
 
1421
    val->sam_pk_for_sad.data = NULL;
 
1422
    { begin_structure();
 
1423
        get_field(val->sam_type,0,asn1_decode_int32);
 
1424
        get_field(val->sam_flags,1,asn1_decode_sam_flags);
 
1425
        opt_string(val->sam_type_name,2,asn1_decode_charstring);
 
1426
        opt_string(val->sam_track_id,3,asn1_decode_charstring);
 
1427
        opt_string(val->sam_challenge_label,4,asn1_decode_charstring);
 
1428
        opt_string(val->sam_challenge,5,asn1_decode_charstring);
 
1429
        opt_string(val->sam_response_prompt,6,asn1_decode_charstring);
 
1430
        opt_string(val->sam_pk_for_sad,7,asn1_decode_charstring);
 
1431
        get_field(val->sam_nonce,8,asn1_decode_int32);
 
1432
        get_field(val->sam_etype, 9, asn1_decode_int32);
 
1433
        end_structure();
 
1434
        val->magic = KV5M_SAM_CHALLENGE;
 
1435
    }
 
1436
    return 0;
 
1437
error_out:
 
1438
    krb5_free_sam_challenge_2_body_contents(NULL, val);
 
1439
    return retval;
1062
1440
}
1063
1441
asn1_error_code asn1_decode_enc_sam_key(asn1buf *buf, krb5_sam_key *val)
1064
1442
{
1065
 
  setup();
1066
 
  { begin_structure();
1067
 
    /* alloc_field(val->sam_key,krb5_keyblock); */
1068
 
    get_field(val->sam_key,0,asn1_decode_encryption_key);
1069
 
    end_structure();
1070
 
    val->magic = KV5M_SAM_KEY;
1071
 
  }
1072
 
  cleanup();
 
1443
    setup();
 
1444
    val->sam_key.contents = NULL;
 
1445
    { begin_structure();
 
1446
        get_field(val->sam_key,0,asn1_decode_encryption_key);
 
1447
        end_structure();
 
1448
        val->magic = KV5M_SAM_KEY;
 
1449
    }
 
1450
    return 0;
 
1451
error_out:
 
1452
    krb5_free_keyblock_contents(NULL, &val->sam_key);
 
1453
    return retval;
1073
1454
}
1074
1455
 
1075
1456
asn1_error_code asn1_decode_enc_sam_response_enc(asn1buf *buf, krb5_enc_sam_response_enc *val)
1076
1457
{
1077
 
  setup();
1078
 
  { begin_structure();
1079
 
    opt_field(val->sam_nonce,0,asn1_decode_int32,0);
1080
 
    opt_field(val->sam_timestamp,1,asn1_decode_kerberos_time,0);
1081
 
    opt_field(val->sam_usec,2,asn1_decode_int32,0);
1082
 
    opt_string(val->sam_sad,3,asn1_decode_charstring);
1083
 
    end_structure();
1084
 
    val->magic = KV5M_ENC_SAM_RESPONSE_ENC;
1085
 
  }
1086
 
  cleanup();
 
1458
    setup();
 
1459
    val->sam_sad.data = NULL;
 
1460
    { begin_structure();
 
1461
        opt_field(val->sam_nonce,0,asn1_decode_int32,0);
 
1462
        opt_field(val->sam_timestamp,1,asn1_decode_kerberos_time,0);
 
1463
        opt_field(val->sam_usec,2,asn1_decode_int32,0);
 
1464
        opt_string(val->sam_sad,3,asn1_decode_charstring);
 
1465
        end_structure();
 
1466
        val->magic = KV5M_ENC_SAM_RESPONSE_ENC;
 
1467
    }
 
1468
    return 0;
 
1469
error_out:
 
1470
    krb5_free_enc_sam_response_enc_contents(NULL, val);
 
1471
    return retval;
1087
1472
}
1088
1473
 
1089
1474
asn1_error_code asn1_decode_enc_sam_response_enc_2(asn1buf *buf, krb5_enc_sam_response_enc_2 *val)
1090
1475
{
1091
 
  setup();
1092
 
  { begin_structure();
1093
 
    get_field(val->sam_nonce,0,asn1_decode_int32);
1094
 
    opt_string(val->sam_sad,1,asn1_decode_charstring);
1095
 
    end_structure();
1096
 
    val->magic = KV5M_ENC_SAM_RESPONSE_ENC_2;
1097
 
  }
1098
 
  cleanup();
 
1476
    setup();
 
1477
    val->sam_sad.data = NULL;
 
1478
    { begin_structure();
 
1479
        get_field(val->sam_nonce,0,asn1_decode_int32);
 
1480
        opt_string(val->sam_sad,1,asn1_decode_charstring);
 
1481
        end_structure();
 
1482
        val->magic = KV5M_ENC_SAM_RESPONSE_ENC_2;
 
1483
    }
 
1484
    return 0;
 
1485
error_out:
 
1486
    krb5_free_enc_sam_response_enc_2_contents(NULL, val);
 
1487
    return retval;
1099
1488
}
1100
1489
 
1101
1490
#define opt_encfield(fld,tag,fn) \
1102
 
    if(tagnum == tag){ \
 
1491
    if (tagnum == tag) { \
1103
1492
      get_field(fld,tag,fn); } \
1104
 
    else{\
 
1493
    else {\
1105
1494
      fld.magic = 0;\
1106
1495
      fld.enctype = 0;\
1107
1496
      fld.kvno = 0;\
1111
1500
 
1112
1501
asn1_error_code asn1_decode_sam_response(asn1buf *buf, krb5_sam_response *val)
1113
1502
{
1114
 
  setup();
1115
 
  { begin_structure();
1116
 
    get_field(val->sam_type,0,asn1_decode_int32);
1117
 
    get_field(val->sam_flags,1,asn1_decode_sam_flags);
1118
 
    opt_string(val->sam_track_id,2,asn1_decode_charstring);
1119
 
    opt_encfield(val->sam_enc_key,3,asn1_decode_encrypted_data);
1120
 
    get_field(val->sam_enc_nonce_or_ts,4,asn1_decode_encrypted_data);
1121
 
    opt_field(val->sam_nonce,5,asn1_decode_int32,0);
1122
 
    opt_field(val->sam_patimestamp,6,asn1_decode_kerberos_time,0);
1123
 
    end_structure();
1124
 
    val->magic = KV5M_SAM_RESPONSE;
1125
 
  }
1126
 
  cleanup();
 
1503
    setup();
 
1504
    val->sam_track_id.data = NULL;
 
1505
    val->sam_enc_key.ciphertext.data = NULL;
 
1506
    val->sam_enc_nonce_or_ts.ciphertext.data = NULL;
 
1507
    { begin_structure();
 
1508
        get_field(val->sam_type,0,asn1_decode_int32);
 
1509
        get_field(val->sam_flags,1,asn1_decode_sam_flags);
 
1510
        opt_string(val->sam_track_id,2,asn1_decode_charstring);
 
1511
        opt_encfield(val->sam_enc_key,3,asn1_decode_encrypted_data);
 
1512
        get_field(val->sam_enc_nonce_or_ts,4,asn1_decode_encrypted_data);
 
1513
        opt_field(val->sam_nonce,5,asn1_decode_int32,0);
 
1514
        opt_field(val->sam_patimestamp,6,asn1_decode_kerberos_time,0);
 
1515
        end_structure();
 
1516
        val->magic = KV5M_SAM_RESPONSE;
 
1517
    }
 
1518
    return 0;
 
1519
error_out:
 
1520
    krb5_free_sam_response_contents(NULL, val);
 
1521
    return retval;
1127
1522
}
1128
1523
 
1129
1524
asn1_error_code asn1_decode_sam_response_2(asn1buf *buf, krb5_sam_response_2 *val)
1130
1525
{
1131
 
  setup();
1132
 
  { begin_structure();
1133
 
    get_field(val->sam_type,0,asn1_decode_int32);
1134
 
    get_field(val->sam_flags,1,asn1_decode_sam_flags);
1135
 
    opt_string(val->sam_track_id,2,asn1_decode_charstring);
1136
 
    get_field(val->sam_enc_nonce_or_sad,3,asn1_decode_encrypted_data);
1137
 
    get_field(val->sam_nonce,4,asn1_decode_int32);
1138
 
    end_structure();
1139
 
    val->magic = KV5M_SAM_RESPONSE;
1140
 
  }
1141
 
  cleanup();
 
1526
    setup();
 
1527
    val->sam_track_id.data = NULL;
 
1528
    val->sam_enc_nonce_or_sad.ciphertext.data = NULL;
 
1529
    { begin_structure();
 
1530
        get_field(val->sam_type,0,asn1_decode_int32);
 
1531
        get_field(val->sam_flags,1,asn1_decode_sam_flags);
 
1532
        opt_string(val->sam_track_id,2,asn1_decode_charstring);
 
1533
        get_field(val->sam_enc_nonce_or_sad,3,asn1_decode_encrypted_data);
 
1534
        get_field(val->sam_nonce,4,asn1_decode_int32);
 
1535
        end_structure();
 
1536
        val->magic = KV5M_SAM_RESPONSE;
 
1537
    }
 
1538
    return 0;
 
1539
error_out:
 
1540
    krb5_free_sam_response_2_contents(NULL, val);
 
1541
    return retval;
1142
1542
}
1143
1543
 
1144
1544
 
1145
1545
asn1_error_code asn1_decode_predicted_sam_response(asn1buf *buf, krb5_predicted_sam_response *val)
1146
1546
{
1147
 
  setup();
1148
 
  { begin_structure();
1149
 
    get_field(val->sam_key,0,asn1_decode_encryption_key);
1150
 
    get_field(val->sam_flags,1,asn1_decode_sam_flags);
1151
 
    get_field(val->stime,2,asn1_decode_kerberos_time);
1152
 
    get_field(val->susec,3,asn1_decode_int32);
1153
 
    alloc_field(val->client,krb5_principal_data);
1154
 
    get_field(val->client,4,asn1_decode_realm);
1155
 
    get_field(val->client,5,asn1_decode_principal_name);
1156
 
    opt_string(val->msd,6,asn1_decode_charstring); /* should be octet */
1157
 
    end_structure();
1158
 
    val->magic = KV5M_PREDICTED_SAM_RESPONSE;
1159
 
  }
1160
 
  cleanup();
1161
 
}
1162
 
 
 
1547
    setup();
 
1548
    val->sam_key.contents = NULL;
 
1549
    val->client = NULL;
 
1550
    val->msd.data = NULL;
 
1551
    { begin_structure();
 
1552
        get_field(val->sam_key,0,asn1_decode_encryption_key);
 
1553
        get_field(val->sam_flags,1,asn1_decode_sam_flags);
 
1554
        get_field(val->stime,2,asn1_decode_kerberos_time);
 
1555
        get_field(val->susec,3,asn1_decode_int32);
 
1556
        alloc_principal(val->client);
 
1557
        get_field(val->client,4,asn1_decode_realm);
 
1558
        get_field(val->client,5,asn1_decode_principal_name);
 
1559
        opt_string(val->msd,6,asn1_decode_charstring); /* should be octet */
 
1560
        end_structure();
 
1561
        val->magic = KV5M_PREDICTED_SAM_RESPONSE;
 
1562
    }
 
1563
    return 0;
 
1564
error_out:
 
1565
    krb5_free_predicted_sam_response_contents(NULL, val);
 
1566
    return retval;
 
1567
}
 
1568
 
 
1569
asn1_error_code asn1_decode_setpw_req(asn1buf *buf, krb5_data *newpasswd, krb5_principal *principal)
 
1570
{
 
1571
    krb5_principal princ = NULL;
 
1572
    setup();
 
1573
    *principal = NULL;
 
1574
 
 
1575
    newpasswd->data = NULL;
 
1576
    { begin_structure();
 
1577
        get_lenfield(newpasswd->length, newpasswd->data, 0, asn1_decode_charstring);
 
1578
        if (tagnum == 1) {
 
1579
            alloc_principal(princ);
 
1580
            opt_field(princ, 1, asn1_decode_principal_name, 0);
 
1581
            opt_field(princ, 2, asn1_decode_realm, 0);
 
1582
        }
 
1583
        end_structure();
 
1584
    }
 
1585
    *principal = princ;
 
1586
    return 0;
 
1587
error_out:
 
1588
    krb5_free_data_contents(NULL, newpasswd);
 
1589
    krb5_free_principal(NULL, princ);
 
1590
    return retval;
 
1591
}
 
1592
 
 
1593
asn1_error_code asn1_decode_pa_for_user(asn1buf *buf, krb5_pa_for_user *val)
 
1594
{
 
1595
    setup();
 
1596
    val->user = NULL;
 
1597
    val->cksum.contents = NULL;
 
1598
    val->auth_package.data = NULL;
 
1599
    { begin_structure();
 
1600
        alloc_principal(val->user);
 
1601
        get_field(val->user,0,asn1_decode_principal_name);
 
1602
        get_field(val->user,1,asn1_decode_realm);
 
1603
        get_field(val->cksum,2,asn1_decode_checksum);
 
1604
        get_lenfield(val->auth_package.length,val->auth_package.data,3,asn1_decode_generalstring);
 
1605
        end_structure();
 
1606
    }
 
1607
    return 0;
 
1608
error_out:
 
1609
    krb5_free_principal(NULL, val->user);
 
1610
    krb5_free_checksum_contents(NULL, &val->cksum);
 
1611
    krb5_free_data_contents(NULL, &val->auth_package);
 
1612
    val->user = NULL;
 
1613
    return retval;
 
1614
}
 
1615
 
 
1616
asn1_error_code asn1_decode_pa_pac_req(asn1buf *buf, krb5_pa_pac_req *val)
 
1617
{
 
1618
    setup();
 
1619
    { begin_structure();
 
1620
        get_field(val->include_pac,0,asn1_decode_boolean);
 
1621
        end_structure();
 
1622
    }
 
1623
    return 0;
 
1624
error_out:
 
1625
    return retval;
 
1626
}
 
1627
 
 
1628
asn1_error_code asn1_decode_fast_armor
 
1629
(asn1buf *buf, krb5_fast_armor *val)
 
1630
{
 
1631
    setup();
 
1632
    val->armor_value.data = NULL;
 
1633
    {begin_structure();
 
1634
    get_field(val->armor_type, 0, asn1_decode_int32);
 
1635
    get_lenfield(val->armor_value.length, val->armor_value.data,
 
1636
                 1, asn1_decode_charstring);
 
1637
    end_structure();
 
1638
    }
 
1639
    return 0;
 
1640
 error_out:
 
1641
    krb5_free_data_contents( NULL, &val->armor_value);
 
1642
    return retval;
 
1643
}
 
1644
 
 
1645
asn1_error_code asn1_decode_fast_armor_ptr
 
1646
(asn1buf *buf, krb5_fast_armor **valptr)
 
1647
{
 
1648
    decode_ptr(krb5_fast_armor *, asn1_decode_fast_armor);
 
1649
}
 
1650
 
 
1651
asn1_error_code asn1_decode_fast_finished
 
1652
(asn1buf *buf, krb5_fast_finished *val)
 
1653
{
 
1654
    setup();
 
1655
    val->client = NULL;
 
1656
    val->ticket_checksum.contents = NULL;
 
1657
    {begin_structure();
 
1658
    get_field(val->timestamp, 0, asn1_decode_kerberos_time);
 
1659
    get_field(val->usec, 1, asn1_decode_int32);
 
1660
    alloc_field(val->client);
 
1661
    get_field(val->client, 2, asn1_decode_realm);
 
1662
    get_field(val->client, 3, asn1_decode_principal_name);
 
1663
    get_field(val->ticket_checksum, 4, asn1_decode_checksum);
 
1664
    end_structure();
 
1665
    }
 
1666
    return 0;
 
1667
 error_out:
 
1668
    krb5_free_principal(NULL, val->client);
 
1669
    krb5_free_checksum_contents( NULL, &val->ticket_checksum);
 
1670
    return retval;
 
1671
}
 
1672
asn1_error_code asn1_decode_fast_finished_ptr
 
1673
(asn1buf *buf, krb5_fast_finished **valptr)
 
1674
{
 
1675
    decode_ptr( krb5_fast_finished *, asn1_decode_fast_finished);
 
1676
}
 
1677
 
 
1678
  
 
1679
#ifndef DISABLE_PKINIT
1163
1680
/* PKINIT */
1164
1681
 
1165
1682
asn1_error_code asn1_decode_external_principal_identifier(asn1buf *buf, krb5_external_principal_identifier *val)
1166
1683
{
1167
1684
    setup();
 
1685
    val->subjectName.data = NULL;
 
1686
    val->issuerAndSerialNumber.data = NULL;
 
1687
    val->subjectKeyIdentifier.data = NULL;
1168
1688
    {
1169
 
      begin_structure();
1170
 
      opt_implicit_octet_string(val->subjectName.length, val->subjectName.data, 0);
1171
 
      opt_implicit_octet_string(val->issuerAndSerialNumber.length, val->issuerAndSerialNumber.data, 1);
1172
 
      opt_implicit_octet_string(val->subjectKeyIdentifier.length, val->subjectKeyIdentifier.data, 2);
1173
 
      end_structure();
 
1689
        begin_structure();
 
1690
        opt_implicit_octet_string(val->subjectName.length, val->subjectName.data, 0);
 
1691
        opt_implicit_octet_string(val->issuerAndSerialNumber.length, val->issuerAndSerialNumber.data, 1);
 
1692
        opt_implicit_octet_string(val->subjectKeyIdentifier.length, val->subjectKeyIdentifier.data, 2);
 
1693
        end_structure();
1174
1694
    }
1175
 
    cleanup();
 
1695
    return 0;
 
1696
error_out:
 
1697
    free(val->subjectName.data);
 
1698
    free(val->issuerAndSerialNumber.data);
 
1699
    free(val->subjectKeyIdentifier.data);
 
1700
    val->subjectName.data = NULL;
 
1701
    val->issuerAndSerialNumber.data = NULL;
 
1702
    val->subjectKeyIdentifier.data = NULL;
 
1703
    return retval;
 
1704
}
 
1705
 
 
1706
asn1_error_code
 
1707
asn1_decode_external_principal_identifier_ptr
 
1708
        (asn1buf *buf,
 
1709
         krb5_external_principal_identifier **valptr)
 
1710
{
 
1711
    decode_ptr(krb5_external_principal_identifier *,
 
1712
               asn1_decode_external_principal_identifier);
 
1713
}
 
1714
 
 
1715
static void
 
1716
free_external_principal_identifier(void *dummy,
 
1717
                                   krb5_external_principal_identifier *val)
 
1718
{
 
1719
    free(val->subjectName.data);
 
1720
    free(val->issuerAndSerialNumber.data);
 
1721
    free(val->subjectKeyIdentifier.data);
 
1722
    free(val);
1176
1723
}
1177
1724
 
1178
1725
asn1_error_code asn1_decode_sequence_of_external_principal_identifier(asn1buf *buf, krb5_external_principal_identifier ***val)
1179
1726
{
1180
 
    decode_array_body(krb5_external_principal_identifier,asn1_decode_external_principal_identifier);
 
1727
    decode_array_body(krb5_external_principal_identifier,
 
1728
                      asn1_decode_external_principal_identifier_ptr,
 
1729
                      free_external_principal_identifier);
1181
1730
}
1182
1731
 
1183
1732
asn1_error_code asn1_decode_pa_pk_as_req(asn1buf *buf, krb5_pa_pk_as_req *val)
1184
1733
{
1185
 
  setup();
1186
 
  {
1187
 
    begin_structure();
1188
 
    get_implicit_octet_string(val->signedAuthPack.length, val->signedAuthPack.data, 0);
1189
 
    opt_field(val->trustedCertifiers, 1, asn1_decode_sequence_of_external_principal_identifier, NULL);
1190
 
    opt_implicit_octet_string(val->kdcPkId.length, val->kdcPkId.data, 2);
1191
 
    end_structure();
1192
 
  }
1193
 
  cleanup();
 
1734
    setup();
 
1735
    val->signedAuthPack.data = NULL;
 
1736
    val->trustedCertifiers = NULL;
 
1737
    val->kdcPkId.data = NULL;
 
1738
    {
 
1739
        begin_structure();
 
1740
        get_implicit_octet_string(val->signedAuthPack.length, val->signedAuthPack.data, 0);
 
1741
        opt_field(val->trustedCertifiers, 1, asn1_decode_sequence_of_external_principal_identifier, NULL);
 
1742
        opt_implicit_octet_string(val->kdcPkId.length, val->kdcPkId.data, 2);
 
1743
        end_structure();
 
1744
    }
 
1745
    return 0;
 
1746
error_out:
 
1747
    free(val->signedAuthPack.data);
 
1748
    free(val->trustedCertifiers);
 
1749
    free(val->kdcPkId.data);
 
1750
    val->signedAuthPack.data = NULL;
 
1751
    val->trustedCertifiers = NULL;
 
1752
    val->kdcPkId.data = NULL;
 
1753
    return retval;
1194
1754
}
1195
1755
 
1196
 
#if 0   /* XXX   This needs to be tested!!! XXX */
 
1756
#if 0   /* XXX   This needs to be tested!!! XXX */
1197
1757
asn1_error_code asn1_decode_trusted_ca(asn1buf *buf, krb5_trusted_ca *val)
1198
1758
{
1199
1759
    setup();
1200
 
    { 
1201
 
      char *start, *end;
1202
 
      size_t alloclen;
 
1760
    val->choice = choice_trusted_cas_UNKNOWN;
 
1761
    {
 
1762
        char *start, *end;
 
1763
        size_t alloclen;
1203
1764
 
1204
 
      begin_explicit_choice();
1205
 
      if (t.tagnum == choice_trusted_cas_principalName) {
1206
 
        val->choice = choice_trusted_cas_principalName;
1207
 
      } else if (t.tagnum == choice_trusted_cas_caName) {
1208
 
        val->choice = choice_trusted_cas_caName;
1209
 
        start = subbuf.next;
1210
 
        {
1211
 
          sequence_of_no_tagvars(&subbuf);
1212
 
          unused_var(size);
1213
 
          end_sequence_of_no_tagvars(&subbuf);
1214
 
        }
1215
 
        end = subbuf.next;
1216
 
        alloclen = end - start;
1217
 
        val->u.caName.data = malloc(alloclen);
1218
 
        if (val->u.caName.data == NULL)
1219
 
          return ENOMEM;
1220
 
        memcpy(val->u.caName.data, start, alloclen);
1221
 
        val->u.caName.length = alloclen;
1222
 
        next_tag();
1223
 
      } else if (t.tagnum == choice_trusted_cas_issuerAndSerial) {
1224
 
        val->choice = choice_trusted_cas_issuerAndSerial;
1225
 
        start = subbuf.next;
1226
 
        {
1227
 
          sequence_of_no_tagvars(&subbuf);
1228
 
          unused_var(size);
1229
 
          end_sequence_of_no_tagvars(&subbuf);
1230
 
        }
1231
 
        end = subbuf.next;
1232
 
        alloclen = end - start;
1233
 
        val->u.issuerAndSerial.data = malloc(alloclen);
1234
 
        if (val->u.issuerAndSerial.data == NULL)
1235
 
          return ENOMEM;
1236
 
        memcpy(val->u.issuerAndSerial.data, start, alloclen);
1237
 
        val->u.issuerAndSerial.length = alloclen;
1238
 
        next_tag();
1239
 
      } else return ASN1_BAD_ID;
1240
 
      end_explicit_choice();
 
1765
        begin_explicit_choice();
 
1766
        if (t.tagnum == choice_trusted_cas_principalName) {
 
1767
            val->choice = choice_trusted_cas_principalName;
 
1768
        } else if (t.tagnum == choice_trusted_cas_caName) {
 
1769
            val->choice = choice_trusted_cas_caName;
 
1770
            val->u.caName.data = NULL;
 
1771
            start = subbuf.next;
 
1772
            {
 
1773
                sequence_of_no_tagvars(&subbuf);
 
1774
                unused_var(size);
 
1775
                end_sequence_of_no_tagvars(&subbuf);
 
1776
            }
 
1777
            end = subbuf.next;
 
1778
            alloclen = end - start;
 
1779
            val->u.caName.data = malloc(alloclen);
 
1780
            if (val->u.caName.data == NULL)
 
1781
                clean_return(ENOMEM);
 
1782
            memcpy(val->u.caName.data, start, alloclen);
 
1783
            val->u.caName.length = alloclen;
 
1784
            next_tag();
 
1785
        } else if (t.tagnum == choice_trusted_cas_issuerAndSerial) {
 
1786
            val->choice = choice_trusted_cas_issuerAndSerial;
 
1787
            val->u.issuerAndSerial.data = NULL;
 
1788
            start = subbuf.next;
 
1789
            {
 
1790
                sequence_of_no_tagvars(&subbuf);
 
1791
                unused_var(size);
 
1792
                end_sequence_of_no_tagvars(&subbuf);
 
1793
            }
 
1794
            end = subbuf.next;
 
1795
            alloclen = end - start;
 
1796
            val->u.issuerAndSerial.data = malloc(alloclen);
 
1797
            if (val->u.issuerAndSerial.data == NULL)
 
1798
                clean_return(ENOMEM);
 
1799
            memcpy(val->u.issuerAndSerial.data, start, alloclen);
 
1800
            val->u.issuerAndSerial.length = alloclen;
 
1801
            next_tag();
 
1802
        } else clean_return(ASN1_BAD_ID);
 
1803
        end_explicit_choice();
1241
1804
    }
1242
 
    cleanup();
 
1805
    return 0;
 
1806
error_out:
 
1807
    if (val->choice == choice_trusted_cas_caName)
 
1808
        free(val->u.caName.data);
 
1809
    else if (val->choice == choice_trusted_cas_issuerAndSerial)
 
1810
        free(val->u.issuerAndSerial.data);
 
1811
    val->choice = choice_trusted_cas_UNKNOWN;
 
1812
    return retval;
1243
1813
}
1244
1814
#else
1245
1815
asn1_error_code asn1_decode_trusted_ca(asn1buf *buf, krb5_trusted_ca *val)
1246
1816
{
1247
1817
    setup();
 
1818
    val->choice = choice_trusted_cas_UNKNOWN;
1248
1819
    { begin_choice();
1249
 
      if (tagnum == choice_trusted_cas_principalName) {
1250
 
        val->choice = choice_trusted_cas_principalName;
1251
 
        asn1_decode_krb5_principal_name(&subbuf, &(val->u.principalName));
1252
 
      } else if (tagnum == choice_trusted_cas_caName) {
1253
 
        val->choice = choice_trusted_cas_caName;
1254
 
        get_implicit_octet_string(val->u.caName.length, val->u.caName.data, choice_trusted_cas_caName);
1255
 
      } else if (tagnum == choice_trusted_cas_issuerAndSerial) {
1256
 
        val->choice = choice_trusted_cas_issuerAndSerial;
1257
 
        get_implicit_octet_string(val->u.issuerAndSerial.length, val->u.issuerAndSerial.data,
1258
 
                                  choice_trusted_cas_issuerAndSerial);
1259
 
      } else return ASN1_BAD_ID;
1260
 
      end_choice();
 
1820
        if (tagnum == choice_trusted_cas_principalName) {
 
1821
            val->choice = choice_trusted_cas_principalName;
 
1822
            val->u.principalName = NULL;
 
1823
            asn1_decode_krb5_principal_name(&subbuf, &(val->u.principalName));
 
1824
        } else if (tagnum == choice_trusted_cas_caName) {
 
1825
            val->choice = choice_trusted_cas_caName;
 
1826
            val->u.caName.data = NULL;
 
1827
            get_implicit_octet_string(val->u.caName.length, val->u.caName.data, choice_trusted_cas_caName);
 
1828
        } else if (tagnum == choice_trusted_cas_issuerAndSerial) {
 
1829
            val->choice = choice_trusted_cas_issuerAndSerial;
 
1830
            val->u.issuerAndSerial.data = NULL;
 
1831
            get_implicit_octet_string(val->u.issuerAndSerial.length, val->u.issuerAndSerial.data,
 
1832
                                      choice_trusted_cas_issuerAndSerial);
 
1833
        } else clean_return(ASN1_BAD_ID);
 
1834
        end_choice();
1261
1835
    }
1262
 
    cleanup();
 
1836
    return 0;
 
1837
error_out:
 
1838
    if (val->choice == choice_trusted_cas_caName)
 
1839
        free(val->u.caName.data);
 
1840
    else if (val->choice == choice_trusted_cas_issuerAndSerial)
 
1841
        free(val->u.issuerAndSerial.data);
 
1842
    val->choice = choice_trusted_cas_UNKNOWN;
 
1843
    return retval;
1263
1844
}
1264
1845
#endif
1265
1846
 
 
1847
asn1_error_code
 
1848
asn1_decode_trusted_ca_ptr(asn1buf *buf, krb5_trusted_ca **valptr)
 
1849
{
 
1850
    decode_ptr(krb5_trusted_ca *, asn1_decode_trusted_ca);
 
1851
}
 
1852
 
 
1853
static void free_trusted_ca(void *dummy, krb5_trusted_ca *val)
 
1854
{
 
1855
    if (val->choice == choice_trusted_cas_caName)
 
1856
        free(val->u.caName.data);
 
1857
    else if (val->choice == choice_trusted_cas_issuerAndSerial)
 
1858
        free(val->u.issuerAndSerial.data);
 
1859
    free(val);
 
1860
}
 
1861
 
1266
1862
asn1_error_code asn1_decode_sequence_of_trusted_ca(asn1buf *buf, krb5_trusted_ca ***val)
1267
1863
{
1268
 
    decode_array_body(krb5_trusted_ca, asn1_decode_trusted_ca);
 
1864
    decode_array_body(krb5_trusted_ca, asn1_decode_trusted_ca_ptr,
 
1865
                      free_trusted_ca);
1269
1866
}
1270
1867
 
1271
1868
asn1_error_code asn1_decode_pa_pk_as_req_draft9(asn1buf *buf, krb5_pa_pk_as_req_draft9 *val)
1272
1869
{
1273
 
  setup();
1274
 
  { begin_structure();
1275
 
    get_implicit_octet_string(val->signedAuthPack.length, val->signedAuthPack.data, 0);
1276
 
    opt_field(val->trustedCertifiers, 1, asn1_decode_sequence_of_trusted_ca, NULL);
1277
 
    opt_lenfield(val->kdcCert.length, val->kdcCert.data, 2, asn1_decode_octetstring);
1278
 
    opt_lenfield(val->encryptionCert.length, val->encryptionCert.data, 2, asn1_decode_octetstring);
1279
 
    end_structure();
1280
 
  }
1281
 
  cleanup();
 
1870
    int i;
 
1871
    setup();
 
1872
    val->signedAuthPack.data = NULL;
 
1873
    val->kdcCert.data = NULL;
 
1874
    val->encryptionCert.data = NULL;
 
1875
    val->trustedCertifiers = NULL;
 
1876
    { begin_structure();
 
1877
        get_implicit_octet_string(val->signedAuthPack.length, val->signedAuthPack.data, 0);
 
1878
        opt_field(val->trustedCertifiers, 1, asn1_decode_sequence_of_trusted_ca, NULL);
 
1879
        opt_lenfield(val->kdcCert.length, val->kdcCert.data, 2, asn1_decode_octetstring);
 
1880
        opt_lenfield(val->encryptionCert.length, val->encryptionCert.data, 2, asn1_decode_octetstring);
 
1881
        end_structure();
 
1882
    }
 
1883
    return 0;
 
1884
error_out:
 
1885
    free(val->signedAuthPack.data);
 
1886
    free(val->kdcCert.data);
 
1887
    free(val->encryptionCert.data);
 
1888
    if (val->trustedCertifiers) {
 
1889
        for (i = 0; val->trustedCertifiers[i]; i++)
 
1890
            free_trusted_ca(NULL, val->trustedCertifiers[i]);
 
1891
        free(val->trustedCertifiers);
 
1892
    }
 
1893
    val->signedAuthPack.data = NULL;
 
1894
    val->kdcCert.data = NULL;
 
1895
    val->encryptionCert.data = NULL;
 
1896
    val->trustedCertifiers = NULL;
 
1897
    return retval;
1282
1898
}
1283
1899
 
1284
1900
asn1_error_code asn1_decode_dh_rep_info(asn1buf *buf, krb5_dh_rep_info *val)
1285
1901
{
1286
1902
    setup();
 
1903
    val->dhSignedData.data = NULL;
 
1904
    val->serverDHNonce.data = NULL;
1287
1905
    { begin_structure();
1288
 
      get_implicit_octet_string(val->dhSignedData.length, val->dhSignedData.data, 0);
 
1906
        get_implicit_octet_string(val->dhSignedData.length, val->dhSignedData.data, 0);
1289
1907
 
1290
 
      opt_lenfield(val->serverDHNonce.length, val->serverDHNonce.data, 1, asn1_decode_octetstring);
1291
 
      end_structure();
 
1908
        opt_lenfield(val->serverDHNonce.length, val->serverDHNonce.data, 1, asn1_decode_octetstring);
 
1909
        end_structure();
1292
1910
    }
1293
 
    cleanup();
 
1911
    return 0;
 
1912
error_out:
 
1913
    free(val->dhSignedData.data);
 
1914
    free(val->serverDHNonce.data);
 
1915
    val->dhSignedData.data = NULL;
 
1916
    val->serverDHNonce.data = NULL;
 
1917
    return retval;
1294
1918
}
1295
1919
 
1296
1920
asn1_error_code asn1_decode_pk_authenticator(asn1buf *buf, krb5_pk_authenticator *val)
1297
1921
{
1298
1922
    setup();
 
1923
    val->paChecksum.contents = NULL;
1299
1924
    { begin_structure();
1300
 
      get_field(val->cusec, 0, asn1_decode_int32);
1301
 
      get_field(val->ctime, 1, asn1_decode_kerberos_time);
1302
 
      get_field(val->nonce, 2, asn1_decode_int32);
1303
 
      opt_lenfield(val->paChecksum.length, val->paChecksum.contents, 3, asn1_decode_octetstring);
1304
 
      end_structure();
 
1925
        get_field(val->cusec, 0, asn1_decode_int32);
 
1926
        get_field(val->ctime, 1, asn1_decode_kerberos_time);
 
1927
        get_field(val->nonce, 2, asn1_decode_int32);
 
1928
        opt_lenfield(val->paChecksum.length, val->paChecksum.contents, 3, asn1_decode_octetstring);
 
1929
        end_structure();
1305
1930
    }
1306
 
    cleanup();
 
1931
    return 0;
 
1932
error_out:
 
1933
    krb5_free_checksum_contents(NULL, &val->paChecksum);
 
1934
    return retval;
1307
1935
}
1308
1936
 
1309
1937
asn1_error_code asn1_decode_pk_authenticator_draft9(asn1buf *buf, krb5_pk_authenticator_draft9 *val)
1310
1938
{
1311
1939
    setup();
 
1940
    val->kdcName = NULL;
 
1941
    val->kdcRealm.data = NULL;
1312
1942
    { begin_structure();
1313
 
      alloc_field(val->kdcName,krb5_principal_data);
1314
 
      get_field(val->kdcName, 0, asn1_decode_principal_name); 
1315
 
      get_field(val->kdcName, 1, asn1_decode_realm); 
1316
 
      get_field(val->cusec, 2, asn1_decode_int32);
1317
 
      get_field(val->ctime, 3, asn1_decode_kerberos_time);
1318
 
      get_field(val->nonce, 4, asn1_decode_int32);
1319
 
      end_structure();
 
1943
        alloc_principal(val->kdcName);
 
1944
        get_field(val->kdcName, 0, asn1_decode_principal_name);
 
1945
        get_field(val->kdcName, 1, asn1_decode_realm);
 
1946
        get_field(val->cusec, 2, asn1_decode_int32);
 
1947
        get_field(val->ctime, 3, asn1_decode_kerberos_time);
 
1948
        get_field(val->nonce, 4, asn1_decode_int32);
 
1949
        end_structure();
1320
1950
    }
1321
 
    cleanup();
 
1951
    return 0;
 
1952
error_out:
 
1953
    krb5_free_principal(NULL, val->kdcName);
 
1954
    return retval;
1322
1955
}
1323
1956
 
1324
1957
asn1_error_code asn1_decode_algorithm_identifier(asn1buf *buf,  krb5_algorithm_identifier *val) {
1325
1958
 
1326
 
  setup();
1327
 
  { begin_structure_no_tag();
1328
 
    /*
1329
 
     * Forbid indefinite encoding because we don't read enough tag
1330
 
     * information from the trailing octets ("ANY DEFINED BY") to
1331
 
     * synchronize EOC tags, etc.
1332
 
     */
1333
 
    if (seqindef) return ASN1_BAD_FORMAT;
1334
 
    /*
1335
 
     * Set up tag variables because we don't actually call anything
1336
 
     * that fetches tag info for us; it's all buried in the decoder
1337
 
     * primitives.
1338
 
     */
1339
 
    tagnum = ASN1_TAGNUM_CEILING;
1340
 
    asn1class = UNIVERSAL;
1341
 
    construction = PRIMITIVE;
1342
 
    taglen = 0;
1343
 
    indef = 0;
1344
 
    retval = asn1_decode_oid(&subbuf, &val->algorithm.length, 
1345
 
                             &val->algorithm.data);
1346
 
    if(retval) return retval;
1347
 
    val->parameters.length = 0;
 
1959
    setup();
 
1960
    val->algorithm.data = NULL;
1348
1961
    val->parameters.data = NULL;
1349
 
 
1350
 
    if(length > subbuf.next - subbuf.base) {
1351
 
      unsigned int size = length - (subbuf.next - subbuf.base);
1352
 
      retval = asn1buf_remove_octetstring(&subbuf, size, 
1353
 
                                          &val->parameters.data);
1354
 
      if(retval) return retval;
1355
 
      val->parameters.length = size;
 
1962
    { begin_structure_no_tag();
 
1963
        /*
 
1964
         * Forbid indefinite encoding because we don't read enough tag
 
1965
         * information from the trailing octets ("ANY DEFINED BY") to
 
1966
         * synchronize EOC tags, etc.
 
1967
         */
 
1968
        if (seqindef) clean_return(ASN1_BAD_FORMAT);
 
1969
        /*
 
1970
         * Set up tag variables because we don't actually call anything
 
1971
         * that fetches tag info for us; it's all buried in the decoder
 
1972
         * primitives.
 
1973
         */
 
1974
        tagnum = ASN1_TAGNUM_CEILING;
 
1975
        asn1class = UNIVERSAL;
 
1976
        construction = PRIMITIVE;
 
1977
        taglen = 0;
 
1978
        indef = 0;
 
1979
        retval = asn1_decode_oid(&subbuf, &val->algorithm.length,
 
1980
                                 &val->algorithm.data);
 
1981
        if (retval) clean_return(retval);
 
1982
        val->parameters.length = 0;
 
1983
        val->parameters.data = NULL;
 
1984
 
 
1985
        assert(subbuf.next >= subbuf.base);
 
1986
        if (length > (size_t)(subbuf.next - subbuf.base)) {
 
1987
            unsigned int size = length - (subbuf.next - subbuf.base);
 
1988
            retval = asn1buf_remove_octetstring(&subbuf, size,
 
1989
                                                &val->parameters.data);
 
1990
            if (retval) clean_return(retval);
 
1991
            val->parameters.length = size;
 
1992
        }
 
1993
 
 
1994
        end_structure();
1356
1995
    }
1357
 
    
1358
 
    end_structure();
1359
 
  }
1360
 
  cleanup();      
 
1996
    return 0;
 
1997
error_out:
 
1998
    free(val->algorithm.data);
 
1999
    free(val->parameters.data);
 
2000
    val->algorithm.data = NULL;
 
2001
    val->parameters.data = NULL;
 
2002
    return retval;
 
2003
}
 
2004
 
 
2005
asn1_error_code
 
2006
asn1_decode_algorithm_identifier_ptr(asn1buf *buf,
 
2007
                                     krb5_algorithm_identifier **valptr)
 
2008
{
 
2009
    decode_ptr(krb5_algorithm_identifier *, asn1_decode_algorithm_identifier);
1361
2010
}
1362
2011
 
1363
2012
asn1_error_code asn1_decode_subject_pk_info(asn1buf *buf, krb5_subject_pk_info *val)
1364
2013
{
1365
2014
    asn1_octet unused;
1366
2015
    setup();
 
2016
    val->algorithm.algorithm.data = NULL;
 
2017
    val->algorithm.parameters.data = NULL;
 
2018
    val->subjectPublicKey.data = NULL;
1367
2019
    { begin_structure_no_tag();
1368
2020
 
1369
 
      retval = asn1_decode_algorithm_identifier(&subbuf, &val->algorithm);
1370
 
      if (retval) return retval;
1371
 
 
1372
 
      /* SubjectPublicKey encoded as a BIT STRING */
1373
 
      next_tag();
1374
 
      if (asn1class != UNIVERSAL || construction != PRIMITIVE ||
1375
 
          tagnum != ASN1_BITSTRING)
1376
 
        return ASN1_BAD_ID;
1377
 
 
1378
 
      retval = asn1buf_remove_octet(&subbuf, &unused);
1379
 
      if(retval) return retval;
1380
 
 
1381
 
      /* Number of unused bits must be between 0 and 7. */
1382
 
      /* What to do if unused is not zero? */
1383
 
      if (unused > 7) return ASN1_BAD_FORMAT;
1384
 
      taglen--;
1385
 
 
1386
 
      val->subjectPublicKey.length = 0;
1387
 
      val->subjectPublicKey.data = NULL;
1388
 
      retval = asn1buf_remove_octetstring(&subbuf, taglen, 
1389
 
                                          &val->subjectPublicKey.data);
1390
 
      if(retval) return retval;
1391
 
      val->subjectPublicKey.length = taglen;
1392
 
      /*
1393
 
       * We didn't call any macro that does next_tag(); do so now to
1394
 
       * preload tag of any trailing encodings.
1395
 
       */
1396
 
      next_tag();
1397
 
      end_structure();
 
2021
        retval = asn1_decode_algorithm_identifier(&subbuf, &val->algorithm);
 
2022
        if (retval) clean_return(retval);
 
2023
 
 
2024
        /* SubjectPublicKey encoded as a BIT STRING */
 
2025
        next_tag();
 
2026
        if (asn1class != UNIVERSAL || construction != PRIMITIVE ||
 
2027
            tagnum != ASN1_BITSTRING)
 
2028
            clean_return(ASN1_BAD_ID);
 
2029
 
 
2030
        retval = asn1buf_remove_octet(&subbuf, &unused);
 
2031
        if (retval) clean_return(retval);
 
2032
 
 
2033
        /* Number of unused bits must be between 0 and 7. */
 
2034
        /* What to do if unused is not zero? */
 
2035
        if (unused > 7) clean_return(ASN1_BAD_FORMAT);
 
2036
        taglen--;
 
2037
 
 
2038
        val->subjectPublicKey.length = 0;
 
2039
        val->subjectPublicKey.data = NULL;
 
2040
        retval = asn1buf_remove_octetstring(&subbuf, taglen,
 
2041
                                            &val->subjectPublicKey.data);
 
2042
        if (retval) clean_return(retval);
 
2043
        val->subjectPublicKey.length = taglen;
 
2044
        /*
 
2045
         * We didn't call any macro that does next_tag(); do so now to
 
2046
         * preload tag of any trailing encodings.
 
2047
         */
 
2048
        next_tag();
 
2049
        end_structure();
1398
2050
    }
1399
 
    cleanup();
 
2051
    return 0;
 
2052
error_out:
 
2053
    free(val->algorithm.algorithm.data);
 
2054
    free(val->algorithm.parameters.data);
 
2055
    free(val->subjectPublicKey.data);
 
2056
    val->algorithm.algorithm.data = NULL;
 
2057
    val->algorithm.parameters.data = NULL;
 
2058
    val->subjectPublicKey.data = NULL;
 
2059
    return 0;
 
2060
}
 
2061
 
 
2062
static void
 
2063
free_algorithm_identifier(void *dummy, krb5_algorithm_identifier *val)
 
2064
{
 
2065
    free(val->algorithm.data);
 
2066
    free(val->parameters.data);
 
2067
    free(val);
1400
2068
}
1401
2069
 
1402
2070
asn1_error_code asn1_decode_sequence_of_algorithm_identifier(asn1buf *buf, krb5_algorithm_identifier ***val)
1403
2071
{
1404
 
    decode_array_body(krb5_algorithm_identifier, asn1_decode_algorithm_identifier);
 
2072
    decode_array_body(krb5_algorithm_identifier,
 
2073
                      asn1_decode_algorithm_identifier_ptr,
 
2074
                      free_algorithm_identifier);
1405
2075
}
1406
2076
 
1407
2077
asn1_error_code asn1_decode_kdc_dh_key_info (asn1buf *buf, krb5_kdc_dh_key_info *val)
1408
2078
{
1409
2079
    setup();
 
2080
    val->subjectPublicKey.data = NULL;
1410
2081
    { begin_structure();
1411
 
      retval = asn1buf_remove_octetstring(&subbuf, taglen, &val->subjectPublicKey.data);
1412
 
      if(retval) return retval;
1413
 
      val->subjectPublicKey.length = taglen;
1414
 
      next_tag();
1415
 
      get_field(val->nonce, 1, asn1_decode_int32);
1416
 
      opt_field(val->dhKeyExpiration, 2, asn1_decode_kerberos_time, 0);
1417
 
      end_structure();
 
2082
        retval = asn1buf_remove_octetstring(&subbuf, taglen, &val->subjectPublicKey.data);
 
2083
        if (retval) clean_return(retval);
 
2084
        val->subjectPublicKey.length = taglen;
 
2085
        next_tag();
 
2086
        get_field(val->nonce, 1, asn1_decode_int32);
 
2087
        opt_field(val->dhKeyExpiration, 2, asn1_decode_kerberos_time, 0);
 
2088
        end_structure();
1418
2089
    }
1419
 
    cleanup();
 
2090
    return 0;
 
2091
error_out:
 
2092
    free(val->subjectPublicKey.data);
 
2093
    val->subjectPublicKey.data = NULL;
 
2094
    return retval;
1420
2095
}
1421
2096
 
1422
2097
asn1_error_code asn1_decode_reply_key_pack (asn1buf *buf, krb5_reply_key_pack *val)
1423
2098
{
1424
2099
    setup();
 
2100
    val->replyKey.contents = NULL;
 
2101
    val->asChecksum.contents = NULL;
1425
2102
    { begin_structure();
1426
 
      get_field(val->replyKey, 0, asn1_decode_encryption_key);
1427
 
      get_field(val->asChecksum, 1, asn1_decode_checksum); 
1428
 
      end_structure();
 
2103
        get_field(val->replyKey, 0, asn1_decode_encryption_key);
 
2104
        get_field(val->asChecksum, 1, asn1_decode_checksum);
 
2105
        end_structure();
1429
2106
    }
1430
 
    cleanup();
 
2107
    return 0;
 
2108
error_out:
 
2109
    free(val->replyKey.contents);
 
2110
    free(val->asChecksum.contents);
 
2111
    val->replyKey.contents = NULL;
 
2112
    val->asChecksum.contents = NULL;
 
2113
    return retval;
1431
2114
}
1432
2115
 
1433
2116
asn1_error_code asn1_decode_reply_key_pack_draft9 (asn1buf *buf, krb5_reply_key_pack_draft9 *val)
1434
2117
{
1435
2118
    setup();
 
2119
    val->replyKey.contents = NULL;
1436
2120
    { begin_structure();
1437
 
      get_field(val->replyKey, 0, asn1_decode_encryption_key);
1438
 
      get_field(val->nonce, 1, asn1_decode_int32); 
1439
 
      end_structure();
 
2121
        get_field(val->replyKey, 0, asn1_decode_encryption_key);
 
2122
        get_field(val->nonce, 1, asn1_decode_int32);
 
2123
        end_structure();
1440
2124
    }
1441
 
    cleanup();
 
2125
    return 0;
 
2126
error_out:
 
2127
    free(val->replyKey.contents);
 
2128
    val->replyKey.contents = NULL;
 
2129
    return retval;
1442
2130
}
1443
2131
 
1444
2132
 
1445
2133
asn1_error_code asn1_decode_krb5_principal_name (asn1buf *buf, krb5_principal *val)
1446
2134
{
 
2135
    int i;
1447
2136
    setup();
 
2137
    (*val)->realm.data = NULL;
 
2138
    (*val)->data = NULL;
1448
2139
    { begin_structure();
1449
 
      get_field(*val, 0, asn1_decode_realm);
1450
 
      get_field(*val, 1, asn1_decode_principal_name);
1451
 
      end_structure();
1452
 
    }
1453
 
    cleanup();
 
2140
        get_field(*val, 0, asn1_decode_realm);
 
2141
        get_field(*val, 1, asn1_decode_principal_name);
 
2142
        end_structure();
 
2143
    }
 
2144
    return 0;
 
2145
error_out:
 
2146
    krb5_free_data_contents(NULL, &(*val)->realm);
 
2147
    if ((*val)->data) {
 
2148
        for (i = 0; i < (*val)->length; i++)
 
2149
            krb5_free_data_contents(NULL, &(*val)->data[i]);
 
2150
        free((*val)->data);
 
2151
    }
 
2152
    (*val)->realm.data = NULL;
 
2153
    (*val)->data = NULL;
 
2154
    return retval;
1454
2155
}
1455
2156
 
1456
2157
asn1_error_code asn1_decode_auth_pack(asn1buf *buf, krb5_auth_pack *val)
1457
2158
{
 
2159
    int i;
1458
2160
    setup();
 
2161
    val->clientPublicValue = NULL;
 
2162
    val->pkAuthenticator.paChecksum.contents = NULL;
 
2163
    val->supportedCMSTypes = NULL;
 
2164
    val->clientDHNonce.data = NULL;
1459
2165
    { begin_structure();
1460
 
      get_field(val->pkAuthenticator, 0, asn1_decode_pk_authenticator);
1461
 
      if (tagnum == 1) { alloc_field(val->clientPublicValue, krb5_subject_pk_info); }      
1462
 
      /* can't call opt_field because it does decoder(&subbuf, &(val)); */
1463
 
      if (asn1buf_remains(&subbuf, seqindef)) {                             
1464
 
        if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)  
1465
 
            && (tagnum || taglen || asn1class != UNIVERSAL))                
1466
 
          return ASN1_BAD_ID;                                               
1467
 
        if (tagnum == 1) {                                        
1468
 
          retval = asn1_decode_subject_pk_info(&subbuf, 
1469
 
                                               val->clientPublicValue);
1470
 
          if (!taglen && indef) { get_eoc(); }
1471
 
          next_tag();
1472
 
        } else val->clientPublicValue = NULL;  
1473
 
      }      
1474
 
      /* can't call opt_field because it does decoder(&subbuf, &(val)); */
1475
 
      if (asn1buf_remains(&subbuf, seqindef)) {
1476
 
        if (tagnum == 2) {
1477
 
          asn1_decode_sequence_of_algorithm_identifier(&subbuf, &val->supportedCMSTypes);
1478
 
          if (!taglen && indef) { get_eoc(); }
1479
 
          next_tag();
1480
 
        } else val->supportedCMSTypes = NULL;
1481
 
      }
1482
 
      opt_lenfield(val->clientDHNonce.length, val->clientDHNonce.data, 3, asn1_decode_octetstring);
1483
 
      end_structure();
1484
 
    }
1485
 
    cleanup();
 
2166
        get_field(val->pkAuthenticator, 0, asn1_decode_pk_authenticator);
 
2167
        if (tagnum == 1) {
 
2168
            alloc_field(val->clientPublicValue);
 
2169
            val->clientPublicValue->algorithm.algorithm.data = NULL;
 
2170
            val->clientPublicValue->algorithm.parameters.data = NULL;
 
2171
            val->clientPublicValue->subjectPublicKey.data = NULL;
 
2172
        }
 
2173
        /* can't call opt_field because it does decoder(&subbuf, &(val)); */
 
2174
        if (asn1buf_remains(&subbuf, seqindef)) {
 
2175
            if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)
 
2176
                && (tagnum || taglen || asn1class != UNIVERSAL))
 
2177
                clean_return(ASN1_BAD_ID);
 
2178
            if (tagnum == 1) {
 
2179
                retval = asn1_decode_subject_pk_info(&subbuf,
 
2180
                                                     val->clientPublicValue);
 
2181
                if (retval) clean_return(retval);
 
2182
                if (!taglen && indef) { get_eoc(); }
 
2183
                next_tag();
 
2184
            } else val->clientPublicValue = NULL;
 
2185
        }
 
2186
        /* can't call opt_field because it does decoder(&subbuf, &(val)); */
 
2187
        if (asn1buf_remains(&subbuf, seqindef)) {
 
2188
            if (tagnum == 2) {
 
2189
                retval = asn1_decode_sequence_of_algorithm_identifier(&subbuf, &val->supportedCMSTypes);
 
2190
                if (retval) clean_return(retval);
 
2191
                if (!taglen && indef) { get_eoc(); }
 
2192
                next_tag();
 
2193
            } else val->supportedCMSTypes = NULL;
 
2194
        }
 
2195
        opt_lenfield(val->clientDHNonce.length, val->clientDHNonce.data, 3, asn1_decode_octetstring);
 
2196
        end_structure();
 
2197
    }
 
2198
    return 0;
 
2199
error_out:
 
2200
    if (val->clientPublicValue) {
 
2201
        free(val->clientPublicValue->algorithm.algorithm.data);
 
2202
        free(val->clientPublicValue->algorithm.parameters.data);
 
2203
        free(val->clientPublicValue->subjectPublicKey.data);
 
2204
        free(val->clientPublicValue);
 
2205
    }
 
2206
    free(val->pkAuthenticator.paChecksum.contents);
 
2207
    if (val->supportedCMSTypes) {
 
2208
        for (i = 0; val->supportedCMSTypes[i]; i++)
 
2209
            free_algorithm_identifier(NULL, val->supportedCMSTypes[i]);
 
2210
        free(val->supportedCMSTypes);
 
2211
    }
 
2212
    free(val->clientDHNonce.data);
 
2213
    val->clientPublicValue = NULL;
 
2214
    val->pkAuthenticator.paChecksum.contents = NULL;
 
2215
    val->supportedCMSTypes = NULL;
 
2216
    val->clientDHNonce.data = NULL;
 
2217
    return retval;
1486
2218
}
1487
2219
 
1488
2220
asn1_error_code asn1_decode_auth_pack_draft9(asn1buf *buf, krb5_auth_pack_draft9 *val)
1489
2221
{
1490
2222
    setup();
 
2223
    val->pkAuthenticator.kdcName = NULL;
 
2224
    val->clientPublicValue = NULL;
1491
2225
    { begin_structure();
1492
 
      get_field(val->pkAuthenticator, 0, asn1_decode_pk_authenticator_draft9);
1493
 
      if (tagnum == 1) {
1494
 
        alloc_field(val->clientPublicValue, krb5_subject_pk_info);      
1495
 
        /* can't call opt_field because it does decoder(&subbuf, &(val)); */
1496
 
        if (asn1buf_remains(&subbuf, seqindef)) {                             
1497
 
          if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)  
1498
 
            && (tagnum || taglen || asn1class != UNIVERSAL))                
1499
 
            return ASN1_BAD_ID;                                               
1500
 
          if (tagnum == 1) {                                        
1501
 
            retval = asn1_decode_subject_pk_info(&subbuf, 
1502
 
                                                 val->clientPublicValue);
1503
 
            if (!taglen && indef) { get_eoc(); }
1504
 
            next_tag();
1505
 
          } else val->clientPublicValue = NULL;  
1506
 
        }
1507
 
      }
1508
 
      end_structure();
1509
 
    }
1510
 
    cleanup();
 
2226
        get_field(val->pkAuthenticator, 0, asn1_decode_pk_authenticator_draft9);
 
2227
        if (tagnum == 1) {
 
2228
            alloc_field(val->clientPublicValue);
 
2229
            val->clientPublicValue->algorithm.algorithm.data = NULL;
 
2230
            val->clientPublicValue->algorithm.parameters.data = NULL;
 
2231
            val->clientPublicValue->subjectPublicKey.data = NULL;
 
2232
            /* can't call opt_field because it does decoder(&subbuf, &(val)); */
 
2233
            if (asn1buf_remains(&subbuf, seqindef)) {
 
2234
                if ((asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED)
 
2235
                    && (tagnum || taglen || asn1class != UNIVERSAL))
 
2236
                    clean_return(ASN1_BAD_ID);
 
2237
                if (tagnum == 1) {
 
2238
                    retval = asn1_decode_subject_pk_info(&subbuf,
 
2239
                                                         val->clientPublicValue);
 
2240
                    if (retval) clean_return(retval);
 
2241
                    if (!taglen && indef) { get_eoc(); }
 
2242
                    next_tag();
 
2243
                } else val->clientPublicValue = NULL;
 
2244
            }
 
2245
        }
 
2246
        end_structure();
 
2247
    }
 
2248
    return 0;
 
2249
error_out:
 
2250
    free(val->pkAuthenticator.kdcName);
 
2251
    if (val->clientPublicValue) {
 
2252
        free(val->clientPublicValue->algorithm.algorithm.data);
 
2253
        free(val->clientPublicValue->algorithm.parameters.data);
 
2254
        free(val->clientPublicValue->subjectPublicKey.data);
 
2255
        free(val->clientPublicValue);
 
2256
    }
 
2257
    val->pkAuthenticator.kdcName = NULL;
 
2258
    val->clientPublicValue = NULL;
 
2259
    return retval;
1511
2260
}
1512
2261
 
1513
2262
asn1_error_code asn1_decode_pa_pk_as_rep(asn1buf *buf, krb5_pa_pk_as_rep *val)
1514
2263
{
1515
 
  setup();
1516
 
  { begin_choice();
1517
 
    if (tagnum == choice_pa_pk_as_rep_dhInfo) {
1518
 
      val->choice = choice_pa_pk_as_rep_dhInfo;
1519
 
      get_field_body(val->u.dh_Info, asn1_decode_dh_rep_info);
1520
 
    } else if (tagnum == choice_pa_pk_as_rep_encKeyPack) {
1521
 
      val->choice = choice_pa_pk_as_rep_encKeyPack;
1522
 
      get_implicit_octet_string(val->u.encKeyPack.length, val->u.encKeyPack.data,
1523
 
                                choice_pa_pk_as_rep_encKeyPack);
1524
 
    } else {
1525
 
      val->choice = choice_pa_pk_as_rep_UNKNOWN;
1526
 
    }
1527
 
    end_choice();
1528
 
  }
1529
 
  cleanup();
 
2264
    setup();
 
2265
    val->choice = choice_pa_pk_as_rep_UNKNOWN;
 
2266
    { begin_choice();
 
2267
        if (tagnum == choice_pa_pk_as_rep_dhInfo) {
 
2268
            val->choice = choice_pa_pk_as_rep_dhInfo;
 
2269
            val->u.dh_Info.dhSignedData.data = NULL;
 
2270
            val->u.dh_Info.serverDHNonce.data = NULL;
 
2271
            get_field_body(val->u.dh_Info, asn1_decode_dh_rep_info);
 
2272
        } else if (tagnum == choice_pa_pk_as_rep_encKeyPack) {
 
2273
            val->choice = choice_pa_pk_as_rep_encKeyPack;
 
2274
            val->u.encKeyPack.data = NULL;
 
2275
            get_implicit_octet_string(val->u.encKeyPack.length, val->u.encKeyPack.data,
 
2276
                                      choice_pa_pk_as_rep_encKeyPack);
 
2277
        } else {
 
2278
            val->choice = choice_pa_pk_as_rep_UNKNOWN;
 
2279
        }
 
2280
        end_choice();
 
2281
    }
 
2282
    return 0;
 
2283
error_out:
 
2284
    if (val->choice == choice_pa_pk_as_rep_dhInfo) {
 
2285
        free(val->u.dh_Info.dhSignedData.data);
 
2286
        free(val->u.dh_Info.serverDHNonce.data);
 
2287
    } else if (val->choice == choice_pa_pk_as_rep_encKeyPack) {
 
2288
        free(val->u.encKeyPack.data);
 
2289
    }
 
2290
    val->choice = choice_pa_pk_as_rep_UNKNOWN;
 
2291
    return retval;
1530
2292
}
1531
2293
 
1532
2294
asn1_error_code asn1_decode_pa_pk_as_rep_draft9(asn1buf *buf, krb5_pa_pk_as_rep_draft9 *val)
1533
2295
{
1534
 
  setup();
1535
 
  { begin_structure();
1536
 
    if (tagnum == choice_pa_pk_as_rep_draft9_dhSignedData) {
1537
 
      val->choice = choice_pa_pk_as_rep_draft9_dhSignedData;
1538
 
      get_lenfield(val->u.dhSignedData.length, val->u.dhSignedData.data,
1539
 
                    choice_pa_pk_as_rep_draft9_dhSignedData, asn1_decode_octetstring);
1540
 
    } else if (tagnum == choice_pa_pk_as_rep_draft9_encKeyPack) {
1541
 
      val->choice = choice_pa_pk_as_rep_draft9_encKeyPack;
1542
 
      get_lenfield(val->u.encKeyPack.length, val->u.encKeyPack.data,
1543
 
                    choice_pa_pk_as_rep_draft9_encKeyPack, asn1_decode_octetstring);
1544
 
    } else {
1545
 
      val->choice = choice_pa_pk_as_rep_draft9_UNKNOWN;
 
2296
    setup();
 
2297
    val->choice = choice_pa_pk_as_rep_draft9_UNKNOWN;
 
2298
    { begin_structure();
 
2299
        if (tagnum == choice_pa_pk_as_rep_draft9_dhSignedData) {
 
2300
            val->choice = choice_pa_pk_as_rep_draft9_dhSignedData;
 
2301
            val->u.dhSignedData.data = NULL;
 
2302
            get_lenfield(val->u.dhSignedData.length, val->u.dhSignedData.data,
 
2303
                         choice_pa_pk_as_rep_draft9_dhSignedData, asn1_decode_octetstring);
 
2304
        } else if (tagnum == choice_pa_pk_as_rep_draft9_encKeyPack) {
 
2305
            val->choice = choice_pa_pk_as_rep_draft9_encKeyPack;
 
2306
            val->u.encKeyPack.data = NULL;
 
2307
            get_lenfield(val->u.encKeyPack.length, val->u.encKeyPack.data,
 
2308
                         choice_pa_pk_as_rep_draft9_encKeyPack, asn1_decode_octetstring);
 
2309
        } else {
 
2310
            val->choice = choice_pa_pk_as_rep_draft9_UNKNOWN;
 
2311
        }
 
2312
        end_structure();
1546
2313
    }
1547
 
    end_structure();
1548
 
  }
1549
 
  cleanup();
 
2314
    return 0;
 
2315
error_out:
 
2316
    if (val->choice == choice_pa_pk_as_rep_draft9_dhSignedData)
 
2317
        free(val->u.dhSignedData.data);
 
2318
    else if (val->choice == choice_pa_pk_as_rep_draft9_encKeyPack)
 
2319
        free(val->u.encKeyPack.data);
 
2320
    val->choice = choice_pa_pk_as_rep_draft9_UNKNOWN;
 
2321
    return retval;
 
2322
}
 
2323
 
 
2324
#endif /* DISABLE_PKINIT */
 
2325
 
 
2326
static void free_typed_data(void *dummy, krb5_typed_data *val)
 
2327
{
 
2328
    free(val->data);
 
2329
    free(val);
1550
2330
}
1551
2331
 
1552
2332
asn1_error_code asn1_decode_sequence_of_typed_data(asn1buf *buf, krb5_typed_data ***val)
1553
2333
{
1554
 
    decode_array_body(krb5_typed_data,asn1_decode_typed_data);
1555
 
}
1556
 
 
1557
 
asn1_error_code asn1_decode_typed_data(asn1buf *buf, krb5_typed_data *val) 
1558
 
{
1559
 
  setup();
1560
 
  { begin_structure();
1561
 
    get_field(val->type,0,asn1_decode_int32);
1562
 
    get_lenfield(val->length,val->data,1,asn1_decode_octetstring);
1563
 
    end_structure();
1564
 
  }
1565
 
  cleanup();
 
2334
    decode_array_body(krb5_typed_data,asn1_decode_typed_data_ptr,
 
2335
                      free_typed_data);
 
2336
}
 
2337
 
 
2338
asn1_error_code asn1_decode_typed_data(asn1buf *buf, krb5_typed_data *val)
 
2339
{
 
2340
    setup();
 
2341
    val->data = NULL;
 
2342
    { begin_structure();
 
2343
        get_field(val->type,0,asn1_decode_int32);
 
2344
        get_lenfield(val->length,val->data,1,asn1_decode_octetstring);
 
2345
        end_structure();
 
2346
    }
 
2347
    return 0;
 
2348
error_out:
 
2349
    free(val->data);
 
2350
    val->data = NULL;
 
2351
    return retval;
 
2352
}
 
2353
 
 
2354
asn1_error_code
 
2355
asn1_decode_typed_data_ptr(asn1buf *buf, krb5_typed_data **valptr)
 
2356
{
 
2357
    decode_ptr(krb5_typed_data *, asn1_decode_typed_data);
1566
2358
}