cifs-utils: add autoconf test for WBC_ID_TYPE_BOTH
[jlayton/cifs-utils.git] / asn1.c
1 /* 
2    Unix SMB/CIFS implementation.
3    simple ASN1 routines
4    Copyright (C) Andrew Tridgell 2001
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <string.h>
21 #include <talloc.h>
22 #include <stdint.h>
23
24 #include "replace.h"
25 #include "data_blob.h"
26 #include "asn1.h"
27
28 /* allocate an asn1 structure */
29 struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx)
30 {
31         struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data);
32         return ret;
33 }
34
35 /* free an asn1 structure */
36 void asn1_free(struct asn1_data *data)
37 {
38         talloc_free(data);
39 }
40
41 /* write to the ASN1 buffer, advancing the buffer pointer */
42 bool asn1_write(struct asn1_data *data, const void *p, int len)
43 {
44         if (data->has_error)
45                 return false;
46         if (data->length < (size_t)data->ofs + len) {
47                 uint8_t *newp;
48                 newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len);
49                 if (!newp) {
50                         asn1_free(data);
51                         data->has_error = true;
52                         return false;
53                 }
54                 data->data = newp;
55                 data->length = data->ofs+len;
56         }
57         memcpy(data->data + data->ofs, p, len);
58         data->ofs += len;
59         return true;
60 }
61
62 /* useful fn for writing a uint8_t */
63 bool asn1_write_uint8(struct asn1_data *data, uint8_t v)
64 {
65         return asn1_write(data, &v, 1);
66 }
67
68 /* push a tag onto the asn1 data buffer. Used for nested structures */
69 bool asn1_push_tag(struct asn1_data *data, uint8_t tag)
70 {
71         struct nesting *nesting;
72
73         asn1_write_uint8(data, tag);
74         nesting = talloc(data, struct nesting);
75         if (!nesting) {
76                 data->has_error = true;
77                 return false;
78         }
79
80         nesting->start = data->ofs;
81         nesting->next = data->nesting;
82         data->nesting = nesting;
83         return asn1_write_uint8(data, 0xff);
84 }
85
86 /* pop a tag */
87 bool asn1_pop_tag(struct asn1_data *data)
88 {
89         struct nesting *nesting;
90         size_t len;
91
92         nesting = data->nesting;
93
94         if (!nesting) {
95                 data->has_error = true;
96                 return false;
97         }
98         len = data->ofs - (nesting->start+1);
99         /* yes, this is ugly. We don't know in advance how many bytes the length
100            of a tag will take, so we assumed 1 byte. If we were wrong then we 
101            need to correct our mistake */
102         if (len > 0xFFFFFF) {
103                 data->data[nesting->start] = 0x84;
104                 if (!asn1_write_uint8(data, 0)) return false;
105                 if (!asn1_write_uint8(data, 0)) return false;
106                 if (!asn1_write_uint8(data, 0)) return false;
107                 if (!asn1_write_uint8(data, 0)) return false;
108                 memmove(data->data+nesting->start+5, data->data+nesting->start+1, len);
109                 data->data[nesting->start+1] = (len>>24) & 0xFF;
110                 data->data[nesting->start+2] = (len>>16) & 0xFF;
111                 data->data[nesting->start+3] = (len>>8) & 0xFF;
112                 data->data[nesting->start+4] = len&0xff;
113         } else if (len > 0xFFFF) {
114                 data->data[nesting->start] = 0x83;
115                 if (!asn1_write_uint8(data, 0)) return false;
116                 if (!asn1_write_uint8(data, 0)) return false;
117                 if (!asn1_write_uint8(data, 0)) return false;
118                 memmove(data->data+nesting->start+4, data->data+nesting->start+1, len);
119                 data->data[nesting->start+1] = (len>>16) & 0xFF;
120                 data->data[nesting->start+2] = (len>>8) & 0xFF;
121                 data->data[nesting->start+3] = len&0xff;
122         } else if (len > 255) {
123                 data->data[nesting->start] = 0x82;
124                 if (!asn1_write_uint8(data, 0)) return false;
125                 if (!asn1_write_uint8(data, 0)) return false;
126                 memmove(data->data+nesting->start+3, data->data+nesting->start+1, len);
127                 data->data[nesting->start+1] = len>>8;
128                 data->data[nesting->start+2] = len&0xff;
129         } else if (len > 127) {
130                 data->data[nesting->start] = 0x81;
131                 if (!asn1_write_uint8(data, 0)) return false;
132                 memmove(data->data+nesting->start+2, data->data+nesting->start+1, len);
133                 data->data[nesting->start+1] = len;
134         } else {
135                 data->data[nesting->start] = len;
136         }
137
138         data->nesting = nesting->next;
139         talloc_free(nesting);
140         return true;
141 }
142
143 /* "i" is the one's complement representation, as is the normal result of an
144  * implicit signed->unsigned conversion */
145
146 static bool push_int_bigendian(struct asn1_data *data, unsigned int i, bool negative)
147 {
148         uint8_t lowest = i & 0xFF;
149
150         i = i >> 8;
151         if (i != 0)
152                 if (!push_int_bigendian(data, i, negative))
153                         return false;
154
155         if (data->nesting->start+1 == data->ofs) {
156
157                 /* We did not write anything yet, looking at the highest
158                  * valued byte */
159
160                 if (negative) {
161                         /* Don't write leading 0xff's */
162                         if (lowest == 0xFF)
163                                 return true;
164
165                         if ((lowest & 0x80) == 0) {
166                                 /* The only exception for a leading 0xff is if
167                                  * the highest bit is 0, which would indicate
168                                  * a positive value */
169                                 if (!asn1_write_uint8(data, 0xff))
170                                         return false;
171                         }
172                 } else {
173                         if (lowest & 0x80) {
174                                 /* The highest bit of a positive integer is 1,
175                                  * this would indicate a negative number. Push
176                                  * a 0 to indicate a positive one */
177                                 if (!asn1_write_uint8(data, 0))
178                                         return false;
179                         }
180                 }
181         }
182
183         return asn1_write_uint8(data, lowest);
184 }
185
186 /* write an Integer without the tag framing. Needed for example for the LDAP
187  * Abandon Operation */
188
189 bool asn1_write_implicit_Integer(struct asn1_data *data, int i)
190 {
191         if (i == -1) {
192                 /* -1 is special as it consists of all-0xff bytes. In
193                     push_int_bigendian this is the only case that is not
194                     properly handled, as all 0xff bytes would be handled as
195                     leading ones to be ignored. */
196                 return asn1_write_uint8(data, 0xff);
197         } else {
198                 return push_int_bigendian(data, i, i<0);
199         }
200 }
201
202
203 /* write an integer */
204 bool asn1_write_Integer(struct asn1_data *data, int i)
205 {
206         if (!asn1_push_tag(data, ASN1_INTEGER)) return false;
207         if (!asn1_write_implicit_Integer(data, i)) return false;
208         return asn1_pop_tag(data);
209 }
210
211 /* write a BIT STRING */
212 bool asn1_write_BitString(struct asn1_data *data, const void *p, size_t length, uint8_t padding)
213 {
214         if (!asn1_push_tag(data, ASN1_BIT_STRING)) return false;
215         if (!asn1_write_uint8(data, padding)) return false;
216         if (!asn1_write(data, p, length)) return false;
217         return asn1_pop_tag(data);
218 }
219
220 bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID)
221 {
222         unsigned int v, v2;
223         const char *p = (const char *)OID;
224         char *newp;
225         int i;
226
227         v = strtoul(p, &newp, 10);
228         if (newp[0] != '.') return false;
229         p = newp + 1;
230
231         v2 = strtoul(p, &newp, 10);
232         if (newp[0] != '.') return false;
233         p = newp + 1;
234
235         /*the ber representation can't use more space then the string one */
236         *blob = data_blob_talloc(mem_ctx, NULL, strlen(OID));
237         if (!blob->data) return false;
238
239         blob->data[0] = 40*v + v2;
240
241         i = 1;
242         while (*p) {
243                 v = strtoul(p, &newp, 10);
244                 if (newp[0] == '.') {
245                         p = newp + 1;
246                 } else if (newp[0] == '\0') {
247                         p = newp;
248                 } else {
249                         data_blob_free(blob);
250                         return false;
251                 }
252                 if (v >= (1<<28)) blob->data[i++] = (0x80 | ((v>>28)&0x7f));
253                 if (v >= (1<<21)) blob->data[i++] = (0x80 | ((v>>21)&0x7f));
254                 if (v >= (1<<14)) blob->data[i++] = (0x80 | ((v>>14)&0x7f));
255                 if (v >= (1<<7)) blob->data[i++] = (0x80 | ((v>>7)&0x7f));
256                 blob->data[i++] = (v&0x7f);
257         }
258
259         blob->length = i;
260
261         return true;
262 }
263
264 /* write an object ID to a ASN1 buffer */
265 bool asn1_write_OID(struct asn1_data *data, const char *OID)
266 {
267         DATA_BLOB blob;
268
269         if (!asn1_push_tag(data, ASN1_OID)) return false;
270
271         if (!ber_write_OID_String(NULL, &blob, OID)) {
272                 data->has_error = true;
273                 return false;
274         }
275
276         if (!asn1_write(data, blob.data, blob.length)) {
277                 data_blob_free(&blob);
278                 data->has_error = true;
279                 return false;
280         }
281         data_blob_free(&blob);
282         return asn1_pop_tag(data);
283 }
284
285 /* write an octet string */
286 bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length)
287 {
288         asn1_push_tag(data, ASN1_OCTET_STRING);
289         asn1_write(data, p, length);
290         asn1_pop_tag(data);
291         return !data->has_error;
292 }
293
294 /* write a LDAP string */
295 bool asn1_write_LDAPString(struct asn1_data *data, const char *s)
296 {
297         asn1_write(data, s, strlen(s));
298         return !data->has_error;
299 }
300
301 /* write a LDAP string from a DATA_BLOB */
302 bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s)
303 {
304         asn1_write(data, s->data, s->length);
305         return !data->has_error;
306 }
307
308 /* write a general string */
309 bool asn1_write_GeneralString(struct asn1_data *data, const char *s)
310 {
311         asn1_push_tag(data, ASN1_GENERAL_STRING);
312         asn1_write_LDAPString(data, s);
313         asn1_pop_tag(data);
314         return !data->has_error;
315 }
316
317 bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob)
318 {
319         asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num));
320         asn1_write(data, blob->data, blob->length);
321         asn1_pop_tag(data);
322         return !data->has_error;
323 }
324
325 /* write a BOOLEAN */
326 bool asn1_write_BOOLEAN(struct asn1_data *data, bool v)
327 {
328         asn1_push_tag(data, ASN1_BOOLEAN);
329         asn1_write_uint8(data, v ? 0xFF : 0);
330         asn1_pop_tag(data);
331         return !data->has_error;
332 }
333
334 bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v)
335 {
336         uint8_t tmp = 0;
337         asn1_start_tag(data, ASN1_BOOLEAN);
338         asn1_read_uint8(data, &tmp);
339         if (tmp == 0xFF) {
340                 *v = true;
341         } else {
342                 *v = false;
343         }
344         asn1_end_tag(data);
345         return !data->has_error;
346 }
347
348 /* write a BOOLEAN in a simple context */
349 bool asn1_write_BOOLEAN_context(struct asn1_data *data, bool v, int context)
350 {
351         asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(context));
352         asn1_write_uint8(data, v ? 0xFF : 0);
353         asn1_pop_tag(data);
354         return !data->has_error;
355 }
356
357 bool asn1_read_BOOLEAN_context(struct asn1_data *data, bool *v, int context)
358 {
359         uint8_t tmp = 0;
360         asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(context));
361         asn1_read_uint8(data, &tmp);
362         if (tmp == 0xFF) {
363                 *v = true;
364         } else {
365                 *v = false;
366         }
367         asn1_end_tag(data);
368         return !data->has_error;
369 }
370
371 /* check a BOOLEAN */
372 bool asn1_check_BOOLEAN(struct asn1_data *data, bool v)
373 {
374         uint8_t b = 0;
375
376         asn1_read_uint8(data, &b);
377         if (b != ASN1_BOOLEAN) {
378                 data->has_error = true;
379                 return false;
380         }
381         asn1_read_uint8(data, &b);
382         if (b != v) {
383                 data->has_error = true;
384                 return false;
385         }
386         return !data->has_error;
387 }
388
389
390 /* load a struct asn1_data structure with a lump of data, ready to be parsed */
391 bool asn1_load(struct asn1_data *data, DATA_BLOB blob)
392 {
393         ZERO_STRUCTP(data);
394         data->data = (uint8_t *)talloc_memdup(data, blob.data, blob.length);
395         if (!data->data) {
396                 data->has_error = true;
397                 return false;
398         }
399         data->length = blob.length;
400         return true;
401 }
402
403 /* Peek into an ASN1 buffer, not advancing the pointer */
404 bool asn1_peek(struct asn1_data *data, void *p, int len)
405 {
406         if (data->has_error)
407                 return false;
408
409         if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len)
410                 return false;
411
412         if ((size_t)data->ofs + len > data->length) {
413                 /* we need to mark the buffer as consumed, so the caller knows
414                    this was an out of data error, and not a decode error */
415                 data->ofs = data->length;
416                 return false;
417         }
418
419         memcpy(p, data->data + data->ofs, len);
420         return true;
421 }
422
423 /* read from a ASN1 buffer, advancing the buffer pointer */
424 bool asn1_read(struct asn1_data *data, void *p, int len)
425 {
426         if (!asn1_peek(data, p, len)) {
427                 data->has_error = true;
428                 return false;
429         }
430
431         data->ofs += len;
432         return true;
433 }
434
435 /* read a uint8_t from a ASN1 buffer */
436 bool asn1_read_uint8(struct asn1_data *data, uint8_t *v)
437 {
438         return asn1_read(data, v, 1);
439 }
440
441 bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v)
442 {
443         return asn1_peek(data, v, 1);
444 }
445
446 bool asn1_peek_tag(struct asn1_data *data, uint8_t tag)
447 {
448         uint8_t b;
449
450         if (asn1_tag_remaining(data) <= 0) {
451                 return false;
452         }
453
454         if (!asn1_peek_uint8(data, &b))
455                 return false;
456
457         return (b == tag);
458 }
459
460 /* start reading a nested asn1 structure */
461 bool asn1_start_tag(struct asn1_data *data, uint8_t tag)
462 {
463         uint8_t b;
464         struct nesting *nesting;
465         
466         if (!asn1_read_uint8(data, &b))
467                 return false;
468
469         if (b != tag) {
470                 data->has_error = true;
471                 return false;
472         }
473         nesting = talloc(data, struct nesting);
474         if (!nesting) {
475                 data->has_error = true;
476                 return false;
477         }
478
479         if (!asn1_read_uint8(data, &b)) {
480                 return false;
481         }
482
483         if (b & 0x80) {
484                 int n = b & 0x7f;
485                 if (!asn1_read_uint8(data, &b))
486                         return false;
487                 nesting->taglen = b;
488                 while (n > 1) {
489                         if (!asn1_read_uint8(data, &b)) 
490                                 return false;
491                         nesting->taglen = (nesting->taglen << 8) | b;
492                         n--;
493                 }
494         } else {
495                 nesting->taglen = b;
496         }
497         nesting->start = data->ofs;
498         nesting->next = data->nesting;
499         data->nesting = nesting;
500         if (asn1_tag_remaining(data) == -1) {
501                 return false;
502         }
503         return !data->has_error;
504 }
505
506 /* stop reading a tag */
507 bool asn1_end_tag(struct asn1_data *data)
508 {
509         struct nesting *nesting;
510
511         /* make sure we read it all */
512         if (asn1_tag_remaining(data) != 0) {
513                 data->has_error = true;
514                 return false;
515         }
516
517         nesting = data->nesting;
518
519         if (!nesting) {
520                 data->has_error = true;
521                 return false;
522         }
523
524         data->nesting = nesting->next;
525         talloc_free(nesting);
526         return true;
527 }
528
529 /* work out how many bytes are left in this nested tag */
530 int asn1_tag_remaining(struct asn1_data *data)
531 {
532         int remaining;
533         if (data->has_error) {
534                 return -1;
535         }
536
537         if (!data->nesting) {
538                 data->has_error = true;
539                 return -1;
540         }
541         remaining = data->nesting->taglen - (data->ofs - data->nesting->start);
542         if (remaining < 0) {
543                 data->has_error = true;
544                 return -1;
545         }
546         if ((size_t)remaining > data->length - data->ofs) {
547                 data->has_error = true;
548                 return -1;
549         }
550         return remaining;
551 }
552
553 /**
554  * Internal implementation for reading binary OIDs
555  * Reading is done as far in the buffer as valid OID
556  * till buffer ends or not valid sub-identifier is found.
557  */
558 static bool _ber_read_OID_String_impl(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
559                                         const char **OID, size_t *bytes_eaten)
560 {
561         unsigned int i;
562         uint8_t *b;
563         unsigned int v;
564         char *tmp_oid = NULL;
565
566         if (blob.length < 2) return false;
567
568         b = blob.data;
569
570         tmp_oid = talloc_asprintf(mem_ctx, "%u",  b[0]/40);
571         if (!tmp_oid) goto nomem;
572         tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u",  b[0]%40);
573         if (!tmp_oid) goto nomem;
574
575         for(i = 1, v = 0; i < blob.length; i++) {
576                 v = (v<<7) | (b[i]&0x7f);
577                 if ( ! (b[i] & 0x80)) {
578                         tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u",  v);
579                         v = 0;
580                         if (bytes_eaten)
581                                 *bytes_eaten = i+1;
582                 }
583                 if (!tmp_oid) goto nomem;
584         }
585
586         *OID = tmp_oid;
587         return true;
588
589 nomem:
590         return false;
591 }
592
593 /* read an object ID from a data blob */
594 bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID)
595 {
596         size_t bytes_eaten = 0;
597
598         if (!_ber_read_OID_String_impl(mem_ctx, blob, OID, &bytes_eaten))
599                 return false;
600
601         return (bytes_eaten == blob.length);
602 }
603
604 /* read an object ID from a ASN1 buffer */
605 bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID)
606 {
607         DATA_BLOB blob;
608         int len;
609
610         if (!asn1_start_tag(data, ASN1_OID)) return false;
611
612         len = asn1_tag_remaining(data);
613         if (len < 0) {
614                 data->has_error = true;
615                 return false;
616         }
617
618         blob = data_blob(NULL, len);
619         if (!blob.data) {
620                 data->has_error = true;
621                 return false;
622         }
623
624         asn1_read(data, blob.data, len);
625         asn1_end_tag(data);
626         if (data->has_error) {
627                 data_blob_free(&blob);
628                 return false;
629         }
630
631         if (!ber_read_OID_String(mem_ctx, blob, OID)) {
632                 data->has_error = true;
633                 data_blob_free(&blob);
634                 return false;
635         }
636
637         data_blob_free(&blob);
638         return true;
639 }
640
641 /* check that the next object ID is correct */
642 bool asn1_check_OID(struct asn1_data *data, const char *OID)
643 {
644         const char *id;
645
646         if (!asn1_read_OID(data, data, &id)) return false;
647
648         if (strcmp(id, OID) != 0) {
649                 talloc_free(discard_const(id));
650                 data->has_error = true;
651                 return false;
652         }
653         talloc_free(discard_const(id));
654         return true;
655 }
656
657 /* read a LDAPString from a ASN1 buffer */
658 bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
659 {
660         int len;
661         len = asn1_tag_remaining(data);
662         if (len < 0) {
663                 data->has_error = true;
664                 return false;
665         }
666         *s = talloc_array(mem_ctx, char, len+1);
667         if (! *s) {
668                 data->has_error = true;
669                 return false;
670         }
671         asn1_read(data, *s, len);
672         (*s)[len] = 0;
673         return !data->has_error;
674 }
675
676
677 /* read a GeneralString from a ASN1 buffer */
678 bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
679 {
680         if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return false;
681         if (!asn1_read_LDAPString(data, mem_ctx, s)) return false;
682         return asn1_end_tag(data);
683 }
684
685
686 /* read a octet string blob */
687 bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
688 {
689         int len;
690         ZERO_STRUCTP(blob);
691         if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return false;
692         len = asn1_tag_remaining(data);
693         if (len < 0) {
694                 data->has_error = true;
695                 return false;
696         }
697         *blob = data_blob_talloc(mem_ctx, NULL, len+1);
698         if (!blob->data) {
699                 data->has_error = true;
700                 return false;
701         }
702         asn1_read(data, blob->data, len);
703         asn1_end_tag(data);
704         blob->length--;
705         blob->data[len] = 0;
706         
707         if (data->has_error) {
708                 data_blob_free(blob);
709                 *blob = data_blob_null;
710                 return false;
711         }
712         return true;
713 }
714
715 bool asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob)
716 {
717         int len;
718         ZERO_STRUCTP(blob);
719         if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false;
720         len = asn1_tag_remaining(data);
721         if (len < 0) {
722                 data->has_error = true;
723                 return false;
724         }
725         *blob = data_blob(NULL, len);
726         if ((len != 0) && (!blob->data)) {
727                 data->has_error = true;
728                 return false;
729         }
730         asn1_read(data, blob->data, len);
731         asn1_end_tag(data);
732         return !data->has_error;
733 }
734
735 /* read an integer without tag*/
736 bool asn1_read_implicit_Integer(struct asn1_data *data, int *i)
737 {
738         uint8_t b;
739         *i = 0;
740
741         while (!data->has_error && asn1_tag_remaining(data)>0) {
742                 if (!asn1_read_uint8(data, &b)) return false;
743                 *i = (*i << 8) + b;
744         }
745         return !data->has_error;        
746         
747 }
748
749 /* read an integer */
750 bool asn1_read_Integer(struct asn1_data *data, int *i)
751 {
752         *i = 0;
753
754         if (!asn1_start_tag(data, ASN1_INTEGER)) return false;
755         if (!asn1_read_implicit_Integer(data, i)) return false;
756         return asn1_end_tag(data);      
757 }
758
759 /* read a BIT STRING */
760 bool asn1_read_BitString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint8_t *padding)
761 {
762         int len;
763         ZERO_STRUCTP(blob);
764         if (!asn1_start_tag(data, ASN1_BIT_STRING)) return false;
765         len = asn1_tag_remaining(data);
766         if (len < 0) {
767                 data->has_error = true;
768                 return false;
769         }
770         if (!asn1_read_uint8(data, padding)) return false;
771
772         *blob = data_blob_talloc(mem_ctx, NULL, len);
773         if (!blob->data) {
774                 data->has_error = true;
775                 return false;
776         }
777         if (asn1_read(data, blob->data, len - 1)) {
778                 blob->length--;
779                 blob->data[len] = 0;
780                 asn1_end_tag(data);
781         }
782
783         if (data->has_error) {
784                 data_blob_free(blob);
785                 *blob = data_blob_null;
786                 *padding = 0;
787                 return false;
788         }
789         return true;
790 }
791
792 /* read an integer */
793 bool asn1_read_enumerated(struct asn1_data *data, int *v)
794 {
795         *v = 0;
796         
797         if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;
798         while (!data->has_error && asn1_tag_remaining(data)>0) {
799                 uint8_t b;
800                 asn1_read_uint8(data, &b);
801                 *v = (*v << 8) + b;
802         }
803         return asn1_end_tag(data);      
804 }
805
806 /* check a enumerated value is correct */
807 bool asn1_check_enumerated(struct asn1_data *data, int v)
808 {
809         uint8_t b;
810         if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;
811         asn1_read_uint8(data, &b);
812         asn1_end_tag(data);
813
814         if (v != b)
815                 data->has_error = false;
816
817         return !data->has_error;
818 }
819
820 /* write an enumerated value to the stream */
821 bool asn1_write_enumerated(struct asn1_data *data, uint8_t v)
822 {
823         if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false;
824         asn1_write_uint8(data, v);
825         asn1_pop_tag(data);
826         return !data->has_error;
827 }
828
829 /*
830   Get us the data just written without copying
831 */
832 bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob)
833 {
834         if (asn1->has_error) {
835                 return false;
836         }
837         if (asn1->nesting != NULL) {
838                 return false;
839         }
840         blob->data = asn1->data;
841         blob->length = asn1->length;
842         return true;
843 }
844
845 /*
846   Fill in an asn1 struct without making a copy
847 */
848 void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len)
849 {
850         ZERO_STRUCTP(data);
851         data->data = buf;
852         data->length = len;
853 }
854