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