~ubuntu-branches/ubuntu/utopic/dropbear/utopic-proposed

« back to all changes in this revision

Viewing changes to libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_ex.c

  • Committer: Bazaar Package Importer
  • Author(s): Gerrit Pape, Matt Johnston, Gerrit Pape
  • Date: 2008-03-27 20:08:06 UTC
  • mfrom: (1.4.1 upstream) (9 hardy)
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20080327200806-c1hhdgt3ht2gk496
Tags: 0.51-1
[ Matt Johnston ]
* New upstream release.
  - Wait until a process exits before the server closes a connection,
    so that an exit code can be sent. This fixes problems with exit
    codes not being returned, which could cause scp to fail (closes:
    #448397, #472483).

[ Gerrit Pape ]
* debian/dropbear.postinst: don't print an error message if the
  update-service program is not installed (thx Matt).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
 
2
 *
 
3
 * LibTomCrypt is a library that provides various cryptographic
 
4
 * algorithms in a highly modular and flexible manner.
 
5
 *
 
6
 * The library is free for all purposes without any express
 
7
 * guarantee it works.
 
8
 *
 
9
 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
 
10
 */
 
11
#include "tomcrypt.h"
 
12
#include <stdarg.h>
 
13
 
 
14
 
 
15
/**
 
16
  @file der_encode_sequence_ex.c
 
17
  ASN.1 DER, encode a SEQUENCE, Tom St Denis
 
18
*/
 
19
 
 
20
#ifdef LTC_DER
 
21
 
 
22
/**
 
23
   Encode a SEQUENCE
 
24
   @param list      The list of items to encode
 
25
   @param inlen     The number of items in the list
 
26
   @param out       [out] The destination 
 
27
   @param outlen    [in/out] The size of the output
 
28
   @param type_of   LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF
 
29
   @return CRYPT_OK on success
 
30
*/
 
31
int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
 
32
                           unsigned char *out,  unsigned long *outlen, int type_of) 
 
33
{
 
34
   int           err, type;
 
35
   unsigned long size, x, y, z, i;
 
36
   void          *data;
 
37
 
 
38
   LTC_ARGCHK(list    != NULL);
 
39
   LTC_ARGCHK(out     != NULL);
 
40
   LTC_ARGCHK(outlen  != NULL);
 
41
 
 
42
   /* get size of output that will be required */
 
43
   y = 0;
 
44
   for (i = 0; i < inlen; i++) {
 
45
       type = list[i].type;
 
46
       size = list[i].size;
 
47
       data = list[i].data;
 
48
 
 
49
       if (type == LTC_ASN1_EOL) { 
 
50
          break;
 
51
       }
 
52
 
 
53
       switch (type) {
 
54
            case LTC_ASN1_BOOLEAN:
 
55
               if ((err = der_length_boolean(&x)) != CRYPT_OK) {
 
56
                  goto LBL_ERR;
 
57
               }
 
58
               y += x;
 
59
               break;
 
60
 
 
61
           case LTC_ASN1_INTEGER:
 
62
               if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
 
63
                  goto LBL_ERR;
 
64
               }
 
65
               y += x;
 
66
               break;
 
67
 
 
68
           case LTC_ASN1_SHORT_INTEGER:
 
69
               if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) {
 
70
                  goto LBL_ERR;
 
71
               }
 
72
               y += x;
 
73
               break;
 
74
 
 
75
           case LTC_ASN1_BIT_STRING:
 
76
               if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
 
77
                  goto LBL_ERR;
 
78
               }
 
79
               y += x;
 
80
               break;
 
81
 
 
82
           case LTC_ASN1_OCTET_STRING:
 
83
               if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
 
84
                  goto LBL_ERR;
 
85
               }
 
86
               y += x;
 
87
               break;
 
88
 
 
89
           case LTC_ASN1_NULL:
 
90
               y += 2;
 
91
               break;
 
92
 
 
93
           case LTC_ASN1_OBJECT_IDENTIFIER:
 
94
               if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
 
95
                  goto LBL_ERR;
 
96
               }
 
97
               y += x;
 
98
               break;
 
99
 
 
100
           case LTC_ASN1_IA5_STRING:
 
101
               if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
 
102
                  goto LBL_ERR;
 
103
               }
 
104
               y += x;
 
105
               break;
 
106
 
 
107
           case LTC_ASN1_PRINTABLE_STRING:
 
108
               if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
 
109
                  goto LBL_ERR;
 
110
               }
 
111
               y += x;
 
112
               break;
 
113
 
 
114
           case LTC_ASN1_UTF8_STRING:
 
115
               if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
 
116
                  goto LBL_ERR;
 
117
               }
 
118
               y += x;
 
119
               break;
 
120
 
 
121
           case LTC_ASN1_UTCTIME:
 
122
               if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
 
123
                  goto LBL_ERR;
 
124
               }
 
125
               y += x;
 
126
               break;
 
127
 
 
128
           case LTC_ASN1_SET:
 
129
           case LTC_ASN1_SETOF:
 
130
           case LTC_ASN1_SEQUENCE:
 
131
               if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
 
132
                  goto LBL_ERR;
 
133
               }
 
134
               y += x;
 
135
               break;
 
136
          
 
137
           default:
 
138
               err = CRYPT_INVALID_ARG;
 
139
               goto LBL_ERR;
 
140
       }
 
141
   }
 
142
 
 
143
   /* calc header size */
 
144
   z = y;
 
145
   if (y < 128) {
 
146
      y += 2;
 
147
   } else if (y < 256) {
 
148
      /* 0x30 0x81 LL */
 
149
      y += 3;
 
150
   } else if (y < 65536UL) {
 
151
      /* 0x30 0x82 LL LL */
 
152
      y += 4;
 
153
   } else if (y < 16777216UL) {
 
154
      /* 0x30 0x83 LL LL LL */
 
155
      y += 5;
 
156
   } else {
 
157
      err = CRYPT_INVALID_ARG;
 
158
      goto LBL_ERR;
 
159
   }
 
160
 
 
161
   /* too big ? */
 
162
   if (*outlen < y) {
 
163
      *outlen = y;
 
164
      err = CRYPT_BUFFER_OVERFLOW;
 
165
      goto LBL_ERR;
 
166
   }
 
167
 
 
168
   /* store header */
 
169
   x = 0;
 
170
   out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31;
 
171
      
 
172
   if (z < 128) {
 
173
      out[x++] = (unsigned char)z;
 
174
   } else if (z < 256) {
 
175
      out[x++] = 0x81;
 
176
      out[x++] = (unsigned char)z;
 
177
   } else if (z < 65536UL) {
 
178
      out[x++] = 0x82;
 
179
      out[x++] = (unsigned char)((z>>8UL)&255);
 
180
      out[x++] = (unsigned char)(z&255);
 
181
   } else if (z < 16777216UL) {
 
182
      out[x++] = 0x83;
 
183
      out[x++] = (unsigned char)((z>>16UL)&255);
 
184
      out[x++] = (unsigned char)((z>>8UL)&255);
 
185
      out[x++] = (unsigned char)(z&255);
 
186
   }
 
187
 
 
188
   /* store data */
 
189
   *outlen -= x;
 
190
   for (i = 0; i < inlen; i++) {
 
191
       type = list[i].type;
 
192
       size = list[i].size;
 
193
       data = list[i].data;
 
194
 
 
195
       if (type == LTC_ASN1_EOL) { 
 
196
          break;
 
197
       }
 
198
 
 
199
       switch (type) {
 
200
            case LTC_ASN1_BOOLEAN:
 
201
               z = *outlen;
 
202
               if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) {
 
203
                  goto LBL_ERR;
 
204
               }
 
205
               x       += z;
 
206
               *outlen -= z;
 
207
               break;
 
208
          
 
209
           case LTC_ASN1_INTEGER:
 
210
               z = *outlen;
 
211
               if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
 
212
                  goto LBL_ERR;
 
213
               }
 
214
               x       += z;
 
215
               *outlen -= z;
 
216
               break;
 
217
 
 
218
           case LTC_ASN1_SHORT_INTEGER:
 
219
               z = *outlen;
 
220
               if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) {
 
221
                  goto LBL_ERR;
 
222
               }
 
223
               x       += z;
 
224
               *outlen -= z;
 
225
               break;
 
226
 
 
227
           case LTC_ASN1_BIT_STRING:
 
228
               z = *outlen;
 
229
               if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
 
230
                  goto LBL_ERR;
 
231
               }
 
232
               x       += z;
 
233
               *outlen -= z;
 
234
               break;
 
235
 
 
236
           case LTC_ASN1_OCTET_STRING:
 
237
               z = *outlen;
 
238
               if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
 
239
                  goto LBL_ERR;
 
240
               }
 
241
               x       += z;
 
242
               *outlen -= z;
 
243
               break;
 
244
 
 
245
           case LTC_ASN1_NULL:
 
246
               out[x++] = 0x05;
 
247
               out[x++] = 0x00;
 
248
               *outlen -= 2;
 
249
               break;
 
250
 
 
251
           case LTC_ASN1_OBJECT_IDENTIFIER:
 
252
               z = *outlen;
 
253
               if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) {
 
254
                  goto LBL_ERR;
 
255
               }
 
256
               x       += z;
 
257
               *outlen -= z;
 
258
               break;
 
259
 
 
260
           case LTC_ASN1_IA5_STRING:
 
261
               z = *outlen;
 
262
               if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) {
 
263
                  goto LBL_ERR;
 
264
               }
 
265
               x       += z;
 
266
               *outlen -= z;
 
267
               break;
 
268
          
 
269
           case LTC_ASN1_PRINTABLE_STRING:
 
270
               z = *outlen;
 
271
               if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) {
 
272
                  goto LBL_ERR;
 
273
               }
 
274
               x       += z;
 
275
               *outlen -= z;
 
276
               break;
 
277
 
 
278
           case LTC_ASN1_UTF8_STRING:
 
279
               z = *outlen;
 
280
               if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) {
 
281
                  goto LBL_ERR;
 
282
               }
 
283
               x       += z;
 
284
               *outlen -= z;
 
285
               break;
 
286
 
 
287
           case LTC_ASN1_UTCTIME:
 
288
               z = *outlen;
 
289
               if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
 
290
                  goto LBL_ERR;
 
291
               }
 
292
               x       += z;
 
293
               *outlen -= z;
 
294
               break;
 
295
 
 
296
           case LTC_ASN1_SET:
 
297
               z = *outlen;
 
298
               if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) {
 
299
                  goto LBL_ERR;
 
300
               }
 
301
               x       += z;
 
302
               *outlen -= z;
 
303
               break;
 
304
 
 
305
           case LTC_ASN1_SETOF:
 
306
               z = *outlen;
 
307
               if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) {
 
308
                  goto LBL_ERR;
 
309
               }
 
310
               x       += z;
 
311
               *outlen -= z;
 
312
               break;
 
313
 
 
314
           case LTC_ASN1_SEQUENCE:
 
315
               z = *outlen;
 
316
               if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) {
 
317
                  goto LBL_ERR;
 
318
               }
 
319
               x       += z;
 
320
               *outlen -= z;
 
321
               break;
 
322
           
 
323
           default:
 
324
               err = CRYPT_INVALID_ARG;
 
325
               goto LBL_ERR;
 
326
       }
 
327
   }
 
328
   *outlen = x;
 
329
   err = CRYPT_OK;   
 
330
 
 
331
LBL_ERR:
 
332
   return err;
 
333
}
 
334
 
 
335
#endif