asn1: fix use-after-free in asn1_write
[mat/samba.git] / lib / util / 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 "includes.h"
21 #include "../lib/util/asn1.h"
22
23 /* allocate an asn1 structure */
24 struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx)
25 {
26         struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data);
27         if (ret == NULL) {
28                 DEBUG(0,("asn1_init failed! out of memory\n"));
29         }
30         return ret;
31 }
32
33 /* free an asn1 structure */
34 void asn1_free(struct asn1_data *data)
35 {
36         talloc_free(data);
37 }
38
39 /* write to the ASN1 buffer, advancing the buffer pointer */
40 bool asn1_write(struct asn1_data *data, const void *p, int len)
41 {
42         if (data->has_error) return false;
43         if (data->length < data->ofs+len) {
44                 uint8_t *newp;
45                 newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len);
46                 if (!newp) {
47                         data->has_error = true;
48                         return false;
49                 }
50                 data->data = newp;
51                 data->length = data->ofs+len;
52         }
53         memcpy(data->data + data->ofs, p, len);
54         data->ofs += len;
55         return true;
56 }
57
58 /* useful fn for writing a uint8_t */
59 bool asn1_write_uint8(struct asn1_data *data, uint8_t v)
60 {
61         return asn1_write(data, &v, 1);
62 }
63
64 /* push a tag onto the asn1 data buffer. Used for nested structures */
65 bool asn1_push_tag(struct asn1_data *data, uint8_t tag)
66 {
67         struct nesting *nesting;
68
69         asn1_write_uint8(data, tag);
70         nesting = talloc(data, struct nesting);
71         if (!nesting) {
72                 data->has_error = true;
73                 return false;
74         }
75
76         nesting->start = data->ofs;
77         nesting->next = data->nesting;
78         data->nesting = nesting;
79         return asn1_write_uint8(data, 0xff);
80 }
81
82 /* pop a tag */
83 bool asn1_pop_tag(struct asn1_data *data)
84 {
85         struct nesting *nesting;
86         size_t len;
87
88         nesting = data->nesting;
89
90         if (!nesting) {
91                 data->has_error = true;
92                 return false;
93         }
94         len = data->ofs - (nesting->start+1);
95         /* yes, this is ugly. We don't know in advance how many bytes the length
96            of a tag will take, so we assumed 1 byte. If we were wrong then we 
97            need to correct our mistake */
98         if (len > 0xFFFFFF) {
99                 data->data[nesting->start] = 0x84;
100                 if (!asn1_write_uint8(data, 0)) return false;
101                 if (!asn1_write_uint8(data, 0)) return false;
102                 if (!asn1_write_uint8(data, 0)) return false;
103                 if (!asn1_write_uint8(data, 0)) return false;
104                 memmove(data->data+nesting->start+5, data->data+nesting->start+1, len);
105                 data->data[nesting->start+1] = (len>>24) & 0xFF;
106                 data->data[nesting->start+2] = (len>>16) & 0xFF;
107                 data->data[nesting->start+3] = (len>>8) & 0xFF;
108                 data->data[nesting->start+4] = len&0xff;
109         } else if (len > 0xFFFF) {
110                 data->data[nesting->start] = 0x83;
111                 if (!asn1_write_uint8(data, 0)) return false;
112                 if (!asn1_write_uint8(data, 0)) return false;
113                 if (!asn1_write_uint8(data, 0)) return false;
114                 memmove(data->data+nesting->start+4, data->data+nesting->start+1, len);
115                 data->data[nesting->start+1] = (len>>16) & 0xFF;
116                 data->data[nesting->start+2] = (len>>8) & 0xFF;
117                 data->data[nesting->start+3] = len&0xff;
118         } else if (len > 255) {
119                 data->data[nesting->start] = 0x82;
120                 if (!asn1_write_uint8(data, 0)) return false;
121                 if (!asn1_write_uint8(data, 0)) return false;
122                 memmove(data->data+nesting->start+3, data->data+nesting->start+1, len);
123                 data->data[nesting->start+1] = len>>8;
124                 data->data[nesting->start+2] = len&0xff;
125         } else if (len > 127) {
126                 data->data[nesting->start] = 0x81;
127                 if (!asn1_write_uint8(data, 0)) return false;
128                 memmove(data->data+nesting->start+2, data->data+nesting->start+1, len);
129                 data->data[nesting->start+1] = len;
130         } else {
131                 data->data[nesting->start] = len;
132         }
133
134         data->nesting = nesting->next;
135         talloc_free(nesting);
136         return true;
137 }
138
139 /* "i" is the one's complement representation, as is the normal result of an
140  * implicit signed->unsigned conversion */
141
142 static bool push_int_bigendian(struct asn1_data *data, unsigned int i, bool negative)
143 {
144         uint8_t lowest = i & 0xFF;
145
146         i = i >> 8;
147         if (i != 0)
148                 if (!push_int_bigendian(data, i, negative))
149                         return false;
150
151         if (data->nesting->start+1 == data->ofs) {
152
153                 /* We did not write anything yet, looking at the highest
154                  * valued byte */
155
156                 if (negative) {
157                         /* Don't write leading 0xff's */
158                         if (lowest == 0xFF)
159                                 return true;
160
161                         if ((lowest & 0x80) == 0) {
162                                 /* The only exception for a leading 0xff is if
163                                  * the highest bit is 0, which would indicate
164                                  * a positive value */
165                                 if (!asn1_write_uint8(data, 0xff))
166                                         return false;
167                         }
168                 } else {
169                         if (lowest & 0x80) {
170                                 /* The highest bit of a positive integer is 1,
171                                  * this would indicate a negative number. Push
172                                  * a 0 to indicate a positive one */
173                                 if (!asn1_write_uint8(data, 0))
174                                         return false;
175                         }
176                 }
177         }
178
179         return asn1_write_uint8(data, lowest);
180 }
181
182 /* write an Integer without the tag framing. Needed for example for the LDAP
183  * Abandon Operation */
184
185 bool asn1_write_implicit_Integer(struct asn1_data *data, int i)
186 {
187         if (i == -1) {
188                 /* -1 is special as it consists of all-0xff bytes. In
189                     push_int_bigendian this is the only case that is not
190                     properly handled, as all 0xff bytes would be handled as
191                     leading ones to be ignored. */
192                 return asn1_write_uint8(data, 0xff);
193         } else {
194                 return push_int_bigendian(data, i, i<0);
195         }
196 }
197
198
199 /* write an integer */
200 bool asn1_write_Integer(struct asn1_data *data, int i)
201 {
202         if (!asn1_push_tag(data, ASN1_INTEGER)) return false;
203         if (!asn1_write_implicit_Integer(data, i)) return false;
204         return asn1_pop_tag(data);
205 }
206
207 /* write a BIT STRING */
208 bool asn1_write_BitString(struct asn1_data *data, const void *p, size_t length, uint8_t padding)
209 {
210         if (!asn1_push_tag(data, ASN1_BIT_STRING)) return false;
211         if (!asn1_write_uint8(data, padding)) return false;
212         if (!asn1_write(data, p, length)) return false;
213         return asn1_pop_tag(data);
214 }
215
216 bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID)
217 {
218         unsigned int v, v2;
219         const char *p = (const char *)OID;
220         char *newp;
221         int i;
222
223         if (!isdigit(*p)) return false;
224         v = strtoul(p, &newp, 10);
225         if (newp[0] != '.') return false;
226         p = newp + 1;
227
228         if (!isdigit(*p)) return false;
229         v2 = strtoul(p, &newp, 10);
230         if (newp[0] != '.') return false;
231         p = newp + 1;
232
233         /*the ber representation can't use more space then the string one */
234         *blob = data_blob_talloc(mem_ctx, NULL, strlen(OID));
235         if (!blob->data) return false;
236
237         blob->data[0] = 40*v + v2;
238
239         i = 1;
240         while (*p) {
241                 if (!isdigit(*p)) return false;
242                 v = strtoul(p, &newp, 10);
243                 if (newp[0] == '.') {
244                         p = newp + 1;
245                         /* check for empty last component */
246                         if (!*p) return false;
247                 } else if (newp[0] == '\0') {
248                         p = newp;
249                 } else {
250                         data_blob_free(blob);
251                         return false;
252                 }
253                 if (v >= (1<<28)) blob->data[i++] = (0x80 | ((v>>28)&0x7f));
254                 if (v >= (1<<21)) blob->data[i++] = (0x80 | ((v>>21)&0x7f));
255                 if (v >= (1<<14)) blob->data[i++] = (0x80 | ((v>>14)&0x7f));
256                 if (v >= (1<<7)) blob->data[i++] = (0x80 | ((v>>7)&0x7f));
257                 blob->data[i++] = (v&0x7f);
258         }
259
260         blob->length = i;
261
262         return true;
263 }
264
265 /**
266  * Serialize partial OID string.
267  * Partial OIDs are in the form:
268  *   1:2.5.6:0x81
269  *   1:2.5.6:0x8182
270  */
271 bool ber_write_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *partial_oid)
272 {
273         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
274         char *oid = talloc_strdup(tmp_ctx, partial_oid);
275         char *p;
276
277         /* truncate partial part so ber_write_OID_String() works */
278         p = strchr(oid, ':');
279         if (p) {
280                 *p = '\0';
281                 p++;
282         }
283
284         if (!ber_write_OID_String(mem_ctx, blob, oid)) {
285                 talloc_free(tmp_ctx);
286                 return false;
287         }
288
289         /* Add partially encoded sub-identifier */
290         if (p) {
291                 DATA_BLOB tmp_blob = strhex_to_data_blob(tmp_ctx, p);
292                 if (!data_blob_append(mem_ctx, blob, tmp_blob.data,
293                                       tmp_blob.length)) {
294                         talloc_free(tmp_ctx);
295                         return false;
296                 }
297         }
298
299         talloc_free(tmp_ctx);
300
301         return true;
302 }
303
304 /* write an object ID to a ASN1 buffer */
305 bool asn1_write_OID(struct asn1_data *data, const char *OID)
306 {
307         DATA_BLOB blob;
308
309         if (!asn1_push_tag(data, ASN1_OID)) return false;
310
311         if (!ber_write_OID_String(NULL, &blob, OID)) {
312                 data->has_error = true;
313                 return false;
314         }
315
316         if (!asn1_write(data, blob.data, blob.length)) {
317                 data_blob_free(&blob);
318                 data->has_error = true;
319                 return false;
320         }
321         data_blob_free(&blob);
322         return asn1_pop_tag(data);
323 }
324
325 /* write an octet string */
326 bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length)
327 {
328         asn1_push_tag(data, ASN1_OCTET_STRING);
329         asn1_write(data, p, length);
330         asn1_pop_tag(data);
331         return !data->has_error;
332 }
333
334 /* write a LDAP string */
335 bool asn1_write_LDAPString(struct asn1_data *data, const char *s)
336 {
337         asn1_write(data, s, strlen(s));
338         return !data->has_error;
339 }
340
341 /* write a LDAP string from a DATA_BLOB */
342 bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s)
343 {
344         asn1_write(data, s->data, s->length);
345         return !data->has_error;
346 }
347
348 /* write a general string */
349 bool asn1_write_GeneralString(struct asn1_data *data, const char *s)
350 {
351         asn1_push_tag(data, ASN1_GENERAL_STRING);
352         asn1_write_LDAPString(data, s);
353         asn1_pop_tag(data);
354         return !data->has_error;
355 }
356
357 bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob)
358 {
359         asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num));
360         asn1_write(data, blob->data, blob->length);
361         asn1_pop_tag(data);
362         return !data->has_error;
363 }
364
365 /* write a BOOLEAN */
366 bool asn1_write_BOOLEAN(struct asn1_data *data, bool v)
367 {
368         asn1_push_tag(data, ASN1_BOOLEAN);
369         asn1_write_uint8(data, v ? 0xFF : 0);
370         asn1_pop_tag(data);
371         return !data->has_error;
372 }
373
374 bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v)
375 {
376         uint8_t tmp = 0;
377         asn1_start_tag(data, ASN1_BOOLEAN);
378         asn1_read_uint8(data, &tmp);
379         if (tmp == 0xFF) {
380                 *v = true;
381         } else {
382                 *v = false;
383         }
384         asn1_end_tag(data);
385         return !data->has_error;
386 }
387
388 /* write a BOOLEAN in a simple context */
389 bool asn1_write_BOOLEAN_context(struct asn1_data *data, bool v, int context)
390 {
391         asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(context));
392         asn1_write_uint8(data, v ? 0xFF : 0);
393         asn1_pop_tag(data);
394         return !data->has_error;
395 }
396
397 bool asn1_read_BOOLEAN_context(struct asn1_data *data, bool *v, int context)
398 {
399         uint8_t tmp = 0;
400         asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(context));
401         asn1_read_uint8(data, &tmp);
402         if (tmp == 0xFF) {
403                 *v = true;
404         } else {
405                 *v = false;
406         }
407         asn1_end_tag(data);
408         return !data->has_error;
409 }
410
411 /* check a BOOLEAN */
412 bool asn1_check_BOOLEAN(struct asn1_data *data, bool v)
413 {
414         uint8_t b = 0;
415
416         asn1_read_uint8(data, &b);
417         if (b != ASN1_BOOLEAN) {
418                 data->has_error = true;
419                 return false;
420         }
421         asn1_read_uint8(data, &b);
422         if (b != v) {
423                 data->has_error = true;
424                 return false;
425         }
426         return !data->has_error;
427 }
428
429
430 /* load a struct asn1_data structure with a lump of data, ready to be parsed */
431 bool asn1_load(struct asn1_data *data, DATA_BLOB blob)
432 {
433         ZERO_STRUCTP(data);
434         data->data = (uint8_t *)talloc_memdup(data, blob.data, blob.length);
435         if (!data->data) {
436                 data->has_error = true;
437                 return false;
438         }
439         data->length = blob.length;
440         return true;
441 }
442
443 /* Peek into an ASN1 buffer, not advancing the pointer */
444 bool asn1_peek(struct asn1_data *data, void *p, int len)
445 {
446         if (data->has_error)
447                 return false;
448
449         if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len)
450                 return false;
451
452         if (data->ofs + len > data->length) {
453                 /* we need to mark the buffer as consumed, so the caller knows
454                    this was an out of data error, and not a decode error */
455                 data->ofs = data->length;
456                 return false;
457         }
458
459         memcpy(p, data->data + data->ofs, len);
460         return true;
461 }
462
463 /* read from a ASN1 buffer, advancing the buffer pointer */
464 bool asn1_read(struct asn1_data *data, void *p, int len)
465 {
466         if (!asn1_peek(data, p, len)) {
467                 data->has_error = true;
468                 return false;
469         }
470
471         data->ofs += len;
472         return true;
473 }
474
475 /* read a uint8_t from a ASN1 buffer */
476 bool asn1_read_uint8(struct asn1_data *data, uint8_t *v)
477 {
478         return asn1_read(data, v, 1);
479 }
480
481 bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v)
482 {
483         return asn1_peek(data, v, 1);
484 }
485
486 bool asn1_peek_tag(struct asn1_data *data, uint8_t tag)
487 {
488         uint8_t b;
489
490         if (asn1_tag_remaining(data) <= 0) {
491                 return false;
492         }
493
494         if (!asn1_peek_uint8(data, &b))
495                 return false;
496
497         return (b == tag);
498 }
499
500 /*
501  * just get the needed size the tag would consume
502  */
503 bool asn1_peek_tag_needed_size(struct asn1_data *data, uint8_t tag, size_t *size)
504 {
505         off_t start_ofs = data->ofs;
506         uint8_t b;
507         size_t taglen = 0;
508
509         if (data->has_error) {
510                 return false;
511         }
512
513         if (!asn1_read_uint8(data, &b)) {
514                 data->ofs = start_ofs;
515                 data->has_error = false;
516                 return false;
517         }
518
519         if (b != tag) {
520                 data->ofs = start_ofs;
521                 data->has_error = false;
522                 return false;
523         }
524
525         if (!asn1_read_uint8(data, &b)) {
526                 data->ofs = start_ofs;
527                 data->has_error = false;
528                 return false;
529         }
530
531         if (b & 0x80) {
532                 int n = b & 0x7f;
533                 if (!asn1_read_uint8(data, &b)) {
534                         data->ofs = start_ofs;
535                         data->has_error = false;
536                         return false;
537                 }
538                 if (n > 4) {
539                         /*
540                          * We should not allow more than 4 bytes
541                          * for the encoding of the tag length.
542                          *
543                          * Otherwise we'd overflow the taglen
544                          * variable on 32 bit systems.
545                          */
546                         data->ofs = start_ofs;
547                         data->has_error = false;
548                         return false;
549                 }
550                 taglen = b;
551                 while (n > 1) {
552                         if (!asn1_read_uint8(data, &b)) {
553                                 data->ofs = start_ofs;
554                                 data->has_error = false;
555                                 return false;
556                         }
557                         taglen = (taglen << 8) | b;
558                         n--;
559                 }
560         } else {
561                 taglen = b;
562         }
563
564         *size = (data->ofs - start_ofs) + taglen;
565
566         data->ofs = start_ofs;
567         data->has_error = false;
568         return true;
569 }
570
571 /* start reading a nested asn1 structure */
572 bool asn1_start_tag(struct asn1_data *data, uint8_t tag)
573 {
574         uint8_t b;
575         struct nesting *nesting;
576         
577         if (!asn1_read_uint8(data, &b))
578                 return false;
579
580         if (b != tag) {
581                 data->has_error = true;
582                 return false;
583         }
584         nesting = talloc(data, struct nesting);
585         if (!nesting) {
586                 data->has_error = true;
587                 return false;
588         }
589
590         if (!asn1_read_uint8(data, &b)) {
591                 return false;
592         }
593
594         if (b & 0x80) {
595                 int n = b & 0x7f;
596                 if (!asn1_read_uint8(data, &b))
597                         return false;
598                 nesting->taglen = b;
599                 while (n > 1) {
600                         if (!asn1_read_uint8(data, &b)) 
601                                 return false;
602                         nesting->taglen = (nesting->taglen << 8) | b;
603                         n--;
604                 }
605         } else {
606                 nesting->taglen = b;
607         }
608         nesting->start = data->ofs;
609         nesting->next = data->nesting;
610         data->nesting = nesting;
611         if (asn1_tag_remaining(data) == -1) {
612                 return false;
613         }
614         return !data->has_error;
615 }
616
617 /* stop reading a tag */
618 bool asn1_end_tag(struct asn1_data *data)
619 {
620         struct nesting *nesting;
621
622         /* make sure we read it all */
623         if (asn1_tag_remaining(data) != 0) {
624                 data->has_error = true;
625                 return false;
626         }
627
628         nesting = data->nesting;
629
630         if (!nesting) {
631                 data->has_error = true;
632                 return false;
633         }
634
635         data->nesting = nesting->next;
636         talloc_free(nesting);
637         return true;
638 }
639
640 /* work out how many bytes are left in this nested tag */
641 int asn1_tag_remaining(struct asn1_data *data)
642 {
643         int remaining;
644         if (data->has_error) {
645                 return -1;
646         }
647
648         if (!data->nesting) {
649                 data->has_error = true;
650                 return -1;
651         }
652         remaining = data->nesting->taglen - (data->ofs - data->nesting->start);
653         if (remaining > (data->length - data->ofs)) {
654                 data->has_error = true;
655                 return -1;
656         }
657         return remaining;
658 }
659
660 /**
661  * Internal implementation for reading binary OIDs
662  * Reading is done as far in the buffer as valid OID
663  * till buffer ends or not valid sub-identifier is found.
664  */
665 static bool _ber_read_OID_String_impl(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
666                                       char **OID, size_t *bytes_eaten)
667 {
668         int i;
669         uint8_t *b;
670         unsigned int v;
671         char *tmp_oid = NULL;
672
673         if (blob.length < 2) return false;
674
675         b = blob.data;
676
677         tmp_oid = talloc_asprintf(mem_ctx, "%u",  b[0]/40);
678         if (!tmp_oid) goto nomem;
679         tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u",  b[0]%40);
680         if (!tmp_oid) goto nomem;
681
682         if (bytes_eaten != NULL) {
683                 *bytes_eaten = 0;
684         }
685
686         for(i = 1, v = 0; i < blob.length; i++) {
687                 v = (v<<7) | (b[i]&0x7f);
688                 if ( ! (b[i] & 0x80)) {
689                         tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u",  v);
690                         v = 0;
691                         if (bytes_eaten)
692                                 *bytes_eaten = i+1;
693                 }
694                 if (!tmp_oid) goto nomem;
695         }
696
697         *OID = tmp_oid;
698         return true;
699
700 nomem:
701         return false;
702 }
703
704 /* read an object ID from a data blob */
705 bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, char **OID)
706 {
707         size_t bytes_eaten;
708
709         if (!_ber_read_OID_String_impl(mem_ctx, blob, OID, &bytes_eaten))
710                 return false;
711
712         return (bytes_eaten == blob.length);
713 }
714
715 /**
716  * Deserialize partial OID string.
717  * Partial OIDs are in the form:
718  *   1:2.5.6:0x81
719  *   1:2.5.6:0x8182
720  */
721 bool ber_read_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
722                                  char **partial_oid)
723 {
724         size_t bytes_left;
725         size_t bytes_eaten;
726         char *identifier = NULL;
727         char *tmp_oid = NULL;
728
729         if (!_ber_read_OID_String_impl(mem_ctx, blob, &tmp_oid, &bytes_eaten))
730                 return false;
731
732         if (bytes_eaten < blob.length) {
733                 bytes_left = blob.length - bytes_eaten;
734                 identifier = hex_encode_talloc(mem_ctx, &blob.data[bytes_eaten], bytes_left);
735                 if (!identifier)        goto nomem;
736
737                 *partial_oid = talloc_asprintf_append_buffer(tmp_oid, ":0x%s", identifier);
738                 if (!*partial_oid)      goto nomem;
739                 TALLOC_FREE(identifier);
740         } else {
741                 *partial_oid = tmp_oid;
742         }
743
744         return true;
745
746 nomem:
747         TALLOC_FREE(identifier);
748         TALLOC_FREE(tmp_oid);
749         return false;
750 }
751
752 /* read an object ID from a ASN1 buffer */
753 bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **OID)
754 {
755         DATA_BLOB blob;
756         int len;
757
758         if (!asn1_start_tag(data, ASN1_OID)) return false;
759
760         len = asn1_tag_remaining(data);
761         if (len < 0) {
762                 data->has_error = true;
763                 return false;
764         }
765
766         blob = data_blob(NULL, len);
767         if (!blob.data) {
768                 data->has_error = true;
769                 return false;
770         }
771
772         asn1_read(data, blob.data, len);
773         asn1_end_tag(data);
774         if (data->has_error) {
775                 data_blob_free(&blob);
776                 return false;
777         }
778
779         if (!ber_read_OID_String(mem_ctx, blob, OID)) {
780                 data->has_error = true;
781                 data_blob_free(&blob);
782                 return false;
783         }
784
785         data_blob_free(&blob);
786         return true;
787 }
788
789 /* check that the next object ID is correct */
790 bool asn1_check_OID(struct asn1_data *data, const char *OID)
791 {
792         char *id;
793
794         if (!asn1_read_OID(data, data, &id)) return false;
795
796         if (strcmp(id, OID) != 0) {
797                 talloc_free(id);
798                 data->has_error = true;
799                 return false;
800         }
801         talloc_free(id);
802         return true;
803 }
804
805 /* read a LDAPString from a ASN1 buffer */
806 bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
807 {
808         int len;
809         len = asn1_tag_remaining(data);
810         if (len < 0) {
811                 data->has_error = true;
812                 return false;
813         }
814         *s = talloc_array(mem_ctx, char, len+1);
815         if (! *s) {
816                 data->has_error = true;
817                 return false;
818         }
819         asn1_read(data, *s, len);
820         (*s)[len] = 0;
821         return !data->has_error;
822 }
823
824
825 /* read a GeneralString from a ASN1 buffer */
826 bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
827 {
828         if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return false;
829         if (!asn1_read_LDAPString(data, mem_ctx, s)) return false;
830         return asn1_end_tag(data);
831 }
832
833
834 /* read a octet string blob */
835 bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
836 {
837         int len;
838         ZERO_STRUCTP(blob);
839         if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return false;
840         len = asn1_tag_remaining(data);
841         if (len < 0) {
842                 data->has_error = true;
843                 return false;
844         }
845         *blob = data_blob_talloc(mem_ctx, NULL, len+1);
846         if (!blob->data || blob->length < len) {
847                 data->has_error = true;
848                 return false;
849         }
850         asn1_read(data, blob->data, len);
851         asn1_end_tag(data);
852         blob->length--;
853         blob->data[len] = 0;
854         
855         if (data->has_error) {
856                 data_blob_free(blob);
857                 *blob = data_blob_null;
858                 return false;
859         }
860         return true;
861 }
862
863 bool asn1_read_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob)
864 {
865         int len;
866         ZERO_STRUCTP(blob);
867         if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false;
868         len = asn1_tag_remaining(data);
869         if (len < 0) {
870                 data->has_error = true;
871                 return false;
872         }
873         *blob = data_blob(NULL, len);
874         if ((len != 0) && (!blob->data)) {
875                 data->has_error = true;
876                 return false;
877         }
878         asn1_read(data, blob->data, len);
879         asn1_end_tag(data);
880         return !data->has_error;
881 }
882
883 /* read an integer without tag*/
884 bool asn1_read_implicit_Integer(struct asn1_data *data, int *i)
885 {
886         uint8_t b;
887         bool first_byte = true;
888         *i = 0;
889
890         while (!data->has_error && asn1_tag_remaining(data)>0) {
891                 if (!asn1_read_uint8(data, &b)) return false;
892                 if (first_byte) {
893                         if (b & 0x80) {
894                                 /* Number is negative.
895                                    Set i to -1 for sign extend. */
896                                 *i = -1;
897                         }
898                         first_byte = false;
899                 }
900                 *i = (*i << 8) + b;
901         }
902         return !data->has_error;        
903         
904 }
905
906 /* read an integer */
907 bool asn1_read_Integer(struct asn1_data *data, int *i)
908 {
909         *i = 0;
910
911         if (!asn1_start_tag(data, ASN1_INTEGER)) return false;
912         if (!asn1_read_implicit_Integer(data, i)) return false;
913         return asn1_end_tag(data);      
914 }
915
916 /* read a BIT STRING */
917 bool asn1_read_BitString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint8_t *padding)
918 {
919         int len;
920         ZERO_STRUCTP(blob);
921         if (!asn1_start_tag(data, ASN1_BIT_STRING)) return false;
922         len = asn1_tag_remaining(data);
923         if (len < 0) {
924                 data->has_error = true;
925                 return false;
926         }
927         if (!asn1_read_uint8(data, padding)) return false;
928
929         *blob = data_blob_talloc(mem_ctx, NULL, len+1);
930         if (!blob->data || blob->length < len) {
931                 data->has_error = true;
932                 return false;
933         }
934         if (asn1_read(data, blob->data, len - 1)) {
935                 blob->length--;
936                 blob->data[len] = 0;
937                 asn1_end_tag(data);
938         }
939
940         if (data->has_error) {
941                 data_blob_free(blob);
942                 *blob = data_blob_null;
943                 *padding = 0;
944                 return false;
945         }
946         return true;
947 }
948
949 /* read an integer */
950 bool asn1_read_enumerated(struct asn1_data *data, int *v)
951 {
952         *v = 0;
953         
954         if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;
955         while (!data->has_error && asn1_tag_remaining(data)>0) {
956                 uint8_t b;
957                 asn1_read_uint8(data, &b);
958                 *v = (*v << 8) + b;
959         }
960         return asn1_end_tag(data);      
961 }
962
963 /* check a enumerated value is correct */
964 bool asn1_check_enumerated(struct asn1_data *data, int v)
965 {
966         uint8_t b;
967         if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;
968         asn1_read_uint8(data, &b);
969         asn1_end_tag(data);
970
971         if (v != b)
972                 data->has_error = false;
973
974         return !data->has_error;
975 }
976
977 /* write an enumerated value to the stream */
978 bool asn1_write_enumerated(struct asn1_data *data, uint8_t v)
979 {
980         if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false;
981         asn1_write_uint8(data, v);
982         asn1_pop_tag(data);
983         return !data->has_error;
984 }
985
986 /*
987   Get us the data just written without copying
988 */
989 bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob)
990 {
991         if (asn1->has_error) {
992                 return false;
993         }
994         if (asn1->nesting != NULL) {
995                 return false;
996         }
997         blob->data = asn1->data;
998         blob->length = asn1->length;
999         return true;
1000 }
1001
1002 /*
1003   Fill in an asn1 struct without making a copy
1004 */
1005 void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len)
1006 {
1007         ZERO_STRUCTP(data);
1008         data->data = buf;
1009         data->length = len;
1010 }
1011
1012 /*
1013   check if a ASN.1 blob is a full tag
1014 */
1015 NTSTATUS asn1_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
1016 {
1017         struct asn1_data *asn1 = asn1_init(NULL);
1018         int size;
1019
1020         NT_STATUS_HAVE_NO_MEMORY(asn1);
1021
1022         asn1->data = blob.data;
1023         asn1->length = blob.length;
1024         asn1_start_tag(asn1, tag);
1025         if (asn1->has_error) {
1026                 talloc_free(asn1);
1027                 return STATUS_MORE_ENTRIES;
1028         }
1029         size = asn1_tag_remaining(asn1) + asn1->ofs;
1030
1031         talloc_free(asn1);
1032
1033         if (size > blob.length) {
1034                 return STATUS_MORE_ENTRIES;
1035         }
1036
1037         *packet_size = size;
1038         return NT_STATUS_OK;
1039 }
1040
1041 NTSTATUS asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
1042 {
1043         struct asn1_data asn1;
1044         size_t size;
1045         bool ok;
1046
1047         ZERO_STRUCT(asn1);
1048         asn1.data = blob.data;
1049         asn1.length = blob.length;
1050
1051         ok = asn1_peek_tag_needed_size(&asn1, tag, &size);
1052         if (!ok) {
1053                 return NT_STATUS_INVALID_BUFFER_SIZE;
1054         }
1055
1056         if (size > blob.length) {
1057                 *packet_size = size;
1058                 return STATUS_MORE_ENTRIES;
1059         }               
1060
1061         *packet_size = size;
1062         return NT_STATUS_OK;
1063 }