suricata
util-decode-der.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011-2015 ANSSI
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /**
29  * \file
30  *
31  * \author Pierre Chifflier <pierre.chifflier@ssi.gouv.fr>
32  *
33  */
34 
35 /*
36  * An ASN.1 Parser for DER-encoded structures.
37  * This parser is not written to be complete or fast, but is rather
38  * focused on stability and security.
39  * It does not support all ASN.1 structure, only a meaningful subset
40  * to decode x509v3 certificates (See RFC 3280).
41  *
42  * References (like 8.19.4) are relative to the ISO/IEC 8825-1:2003 document
43  *
44  */
45 
46 #include "suricata-common.h"
47 #include "util-decode-der.h"
48 #include "util-validate.h"
49 
50 #define MAX_OID_LENGTH 256
51 
52 static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer,
53  uint32_t size, uint8_t depth,
54  uint32_t *errcode) __attribute__((nonnull));
55 static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer,
56  uint32_t size, uint8_t depth,
57  uint32_t *errcode) __attribute__((nonnull));
58 static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer,
59  uint32_t size, uint8_t depth,
60  uint32_t *errcode) __attribute__((nonnull));
61 static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer,
62  uint32_t size, uint8_t depth,
63  uint32_t *errcode) __attribute__((nonnull));
64 static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer,
65  uint32_t size, uint8_t depth,
66  uint32_t *errcode) __attribute__((nonnull));
67 static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer,
68  uint32_t size, uint8_t depth,
69  uint32_t *errcode) __attribute__((nonnull));
70 static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer,
71  uint32_t max_size, uint8_t depth,
72  uint32_t *errcode) __attribute__((nonnull));
73 static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer,
74  uint32_t size, uint8_t depth,
75  uint32_t *errcode) __attribute__((nonnull));
76 static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer,
77  uint32_t size, uint8_t depth,
78  uint32_t *errcode) __attribute__((nonnull));
79 static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer,
80  uint32_t size, uint8_t depth,
81  uint32_t *errcode) __attribute__((nonnull));
82 static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer,
83  uint32_t size, uint8_t depth,
84  uint32_t *errcode) __attribute__((nonnull));
85 static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer,
86  uint32_t size, uint8_t depth,
87  uint32_t *errcode) __attribute__((nonnull));
88 static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer,
89  uint32_t size, uint8_t depth,
90  uint32_t *errcode) __attribute__((nonnull));
91 static Asn1Generic * DecodeAsn1DerGeneralizedTime(const unsigned char *buffer,
92  uint32_t size, uint8_t depth,
93  uint32_t *errcode) __attribute__((nonnull));
94 static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer,
95  uint32_t max_size, uint8_t depth,
96  int seq_index, uint32_t *errcode) __attribute__((nonnull));
97 
98 static Asn1Generic * Asn1GenericNew(void)
99 {
100  Asn1Generic *obj;
101 
102  obj = SCMalloc(sizeof(Asn1Generic));
103  if (obj != NULL)
104  memset(obj, 0, sizeof(Asn1Generic));
105 
106  return obj;
107 }
108 
109 /**
110  * \retval r 0 ok, -1 error
111  */
112 static int Asn1SequenceAppend(Asn1Generic *seq, Asn1Generic *node)
113 {
114  Asn1Generic *it, *new_container;
115 
116  if (seq->data == NULL) {
117  seq->data = node;
118  return 0;
119  }
120 
121  new_container = Asn1GenericNew();
122  if (new_container == NULL)
123  return -1;
124  new_container->data = node;
125 
126  for (it=seq; it->next != NULL; it=it->next)
127  ;
128 
129  it->next = new_container;
130  return 0;
131 }
132 
133 static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer,
134  uint32_t max_size, uint8_t depth,
135  int seq_index, uint32_t *errcode)
136 {
137  const unsigned char *d_ptr = buffer;
138  uint32_t numbytes, el_max_size;
139  Asn1ElementType el;
140  uint8_t c;
141  uint32_t i;
142  Asn1Generic *child;
143  uint8_t el_type;
144 
145  /* refuse excessive recursion */
146  if (unlikely(depth == 255)) {
147  *errcode = ERR_DER_RECURSION_LIMIT;
148  return NULL;
149  }
150  if (max_size < 2) {
151  *errcode = ERR_DER_INVALID_SIZE;
152  return NULL;
153  }
154 
155  el.cls = (d_ptr[0] & 0xc0) >> 6;
156  el.pc = (d_ptr[0] & 0x20) >> 5;
157  el.tag = (d_ptr[0] & 0x1f);
158 
159  el_type = el.tag;
160 
161  if (el.tag == 0x1f) {
162  *errcode = ERR_DER_INVALID_TAG;
163  return NULL;
164  }
165 
166  switch (el.cls) {
168  /* get element type from definition, see:
169  http://www.ietf.org/rfc/rfc3280.txt */
170  if (depth == 2 && el.tag == 0) {
171  /* TBSCertificate */
172  el_type = ASN1_SEQUENCE;
173  break;
174  }
175  if (depth == 2 && el.tag == 1) {
176  /* issuerUniqueID */
177  el_type = ASN1_BITSTRING;
178  break;
179  }
180  if (depth == 2 && el.tag == 2) {
181  /* subjectUniqueID */
182  el_type = ASN1_BITSTRING;
183  break;
184  }
185  if (depth == 2 && el.tag == 3) {
186  /* extensions */
187  el_type = ASN1_SEQUENCE;
188  break;
189  }
190  /* unknown context specific value - do not decode */
191  break;
192  };
193 
194  el_max_size = max_size - (d_ptr-buffer);
195  switch (el_type) {
196  case ASN1_INTEGER:
197  child = DecodeAsn1DerInteger(d_ptr, el_max_size, depth+1, errcode);
198  break;
199  case ASN1_BOOLEAN:
200  child = DecodeAsn1DerBoolean(d_ptr, el_max_size, depth+1, errcode);
201  break;
202  case ASN1_NULL:
203  child = DecodeAsn1DerNull(d_ptr, el_max_size, depth+1, errcode);
204  break;
205  case ASN1_BITSTRING:
206  child = DecodeAsn1DerBitstring(d_ptr, el_max_size, depth+1,
207  errcode);
208  break;
209  case ASN1_OID:
210  child = DecodeAsn1DerOid(d_ptr, el_max_size, depth+1, errcode);
211  break;
212  case ASN1_IA5STRING:
213  child = DecodeAsn1DerIA5String(d_ptr, el_max_size, depth+1,
214  errcode);
215  break;
216  case ASN1_OCTETSTRING:
217  child = DecodeAsn1DerOctetString(d_ptr, el_max_size, depth+1,
218  errcode);
219  break;
220  case ASN1_UTF8STRING:
221  child = DecodeAsn1DerUTF8String(d_ptr, el_max_size, depth+1,
222  errcode);
223  break;
224  case ASN1_PRINTSTRING:
225  child = DecodeAsn1DerPrintableString(d_ptr, el_max_size, depth+1,
226  errcode);
227  break;
228  case ASN1_SEQUENCE:
229  child = DecodeAsn1DerSequence(d_ptr, el_max_size, depth+1, errcode);
230  break;
231  case ASN1_SET:
232  child = DecodeAsn1DerSet(d_ptr, el_max_size, depth+1, errcode);
233  break;
234  case ASN1_T61STRING:
235  child = DecodeAsn1DerT61String(d_ptr, el_max_size, depth+1,
236  errcode);
237  break;
238  case ASN1_UTCTIME:
239  child = DecodeAsn1DerUTCTime(d_ptr, el_max_size, depth+1, errcode);
240  break;
242  child = DecodeAsn1DerGeneralizedTime(d_ptr, el_max_size, depth+1, errcode);
243  break;
244  default:
245  /* unknown ASN.1 type */
246  child = NULL;
247  child = Asn1GenericNew();
248  if (child == NULL)
249  break;
250 
251  child->type = el.tag;
252 
253  /* total sequence length */
254  const unsigned char * save_d_ptr = d_ptr;
255  d_ptr++;
256  el_max_size--;
257  c = d_ptr[0];
258 
259  /* short form 8.1.3.4 */
260  if ((c & (1<<7))>>7 == 0) {
261  child->length = c;
262  d_ptr++;
263  /* long form 8.1.3.5 */
264  } else {
265  numbytes = c & 0x7f;
266  if (2 + numbytes > el_max_size) {
267  SCFree(child);
268  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
269  return NULL;
270  }
271  child->length = 0;
272  d_ptr++;
273  for (i=0; i<numbytes; i++) {
274  child->length = child->length<<8 | d_ptr[0];
275  d_ptr++;
276  }
277  }
278 
279  /* fix the length for unknown objects, else sequence parsing
280  will fail */
281  child->length += (d_ptr - save_d_ptr);
282 
283  if (child->length > max_size - (d_ptr - buffer)) {
284  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
285  SCFree(child);
286  return NULL;
287  }
288 
289  break;
290  };
291 
292  if (child == NULL) {
293  if (*errcode == 0)
294  *errcode = ERR_DER_INVALID_OBJECT;
295  return NULL;
296  }
297 
298  /* child length should never be zero */
299  if (child->length == 0) {
300  *errcode = ERR_DER_INVALID_OBJECT;
301  SCFree(child);
302  return NULL;
303  }
304 
305  child->header = el;
306  return child;
307 }
308 
309 static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer,
310  uint32_t size, uint8_t depth,
311  uint32_t *errcode)
312 {
313  const unsigned char *d_ptr = buffer;
314  uint8_t numbytes;
315  uint32_t value;
316  uint32_t i;
317  Asn1Generic *a;
318 
319  numbytes = d_ptr[1];
320 
321  if ((uint32_t)(numbytes + 2) > size) {
322  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
323  return NULL;
324  }
325 
326  d_ptr += 2;
327 
328  value = 0;
329 
330  /* Here we need to ensure that numbytes is less than 4
331  so integer affectation is possible. We set the value
332  to 0xffffffff which is by convention the unknown value.
333  In this case, the hexadecimal value must be used. */
334  if (numbytes > 4) {
335  value = 0xffffffff;
336  } else {
337  for (i=0; i<numbytes; i++) {
338  value = value<<8 | d_ptr[i];
339  }
340  }
341 
342  a = Asn1GenericNew();
343  if (a == NULL) {
344  *errcode = ERR_DER_GENERIC;
345  return NULL;
346  }
347 
348  a->type = ASN1_INTEGER;
349  a->length = (d_ptr - buffer) + numbytes;
350  a->value = value;
351 
352  a->str = SCMalloc(2*numbytes + 1);
353  if (a->str == NULL) {
354  *errcode = ERR_DER_GENERIC;
355  SCFree(a);
356  return NULL;
357  }
358 
359  for (i=0; i<numbytes; i++) {
360  snprintf(a->str + 2*i, 2*(numbytes-i)+1, "%02X", d_ptr[i]);
361  }
362  a->str[2*numbytes]= '\0';
363 
364  return a;
365 }
366 
367 static int DecodeAsn1BuildValue(const unsigned char **d_ptr, uint32_t *val,
368  uint8_t numbytes, uint32_t *errcode)
369 {
370  int i;
371  uint32_t value = 0;
372 
373  if (numbytes > 4) {
374  *errcode = ERR_DER_INVALID_SIZE;
375 
376  /* too big won't fit: set it to 0xffffffff by convention */
377  value = 0xffffffff;
378  *val = value;
379  return -1;
380  } else {
381  for (i=0; i<numbytes; i++) {
382  value = value<<8 | (*d_ptr)[0];
383  (*d_ptr)++;
384  }
385  }
386 
387  *val = value;
388  return 0;
389 }
390 
391 static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer,
392  uint32_t size, uint8_t depth,
393  uint32_t *errcode)
394 {
395  const unsigned char *d_ptr = buffer;
396  uint8_t numbytes;
397  uint32_t value;
398  Asn1Generic *a;
399 
400  numbytes = d_ptr[1];
401  if ((uint32_t)(numbytes + 2) > size) {
402  *errcode = ERR_DER_INVALID_SIZE;
403  return NULL;
404  }
405  d_ptr += 2;
406 
407  if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes, errcode) == -1) {
408  return NULL;
409  }
410 
411  a = Asn1GenericNew();
412  if (a == NULL) {
413  *errcode = ERR_DER_GENERIC;
414  return NULL;
415  }
416 
417  a->type = ASN1_BOOLEAN;
418  a->length = (d_ptr - buffer);
419  a->value = value;
420 
421  return a;
422 }
423 
424 static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer,
425  uint32_t size, uint8_t depth,
426  uint32_t *errcode)
427 {
428  const unsigned char *d_ptr = buffer;
429  uint8_t numbytes;
430  uint32_t value;
431  Asn1Generic *a;
432 
433  numbytes = d_ptr[1];
434  if ((uint32_t)(numbytes + 2) > size) {
435  *errcode = ERR_DER_INVALID_SIZE;
436  return NULL;
437  }
438  d_ptr += 2;
439 
440  if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes, errcode) == -1) {
441  return NULL;
442  }
443 
444  a = Asn1GenericNew();
445  if (a == NULL) {
446  *errcode = ERR_DER_GENERIC;
447  return NULL;
448  }
449 
450  a->type = ASN1_NULL;
451  a->length = (d_ptr - buffer);
452  a->value = 0;
453 
454  return a;
455 }
456 
457 static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer,
458  uint32_t max_size, uint8_t depth,
459  uint32_t *errcode)
460 {
461  const unsigned char *d_ptr = buffer;
462  uint32_t length;
463  uint8_t numbytes, c;
464  Asn1Generic *a;
465 
466  d_ptr++;
467 
468  /* size */
469  c = d_ptr[0];
470  /* short form 8.1.3.4 */
471  if ((c & (1<<7))>>7 == 0) {
472  length = c;
473  d_ptr++;
474  /* long form 8.1.3.5 */
475  } else {
476  numbytes = c & 0x7f;
477  if ((uint32_t)(numbytes + 2) > max_size) {
478  *errcode = ERR_DER_INVALID_SIZE;
479  return NULL;
480  }
481  d_ptr++;
482  if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
483  return NULL;
484  }
485  }
486 
487  if ((d_ptr-buffer) + length > max_size) {
488  *errcode = ERR_DER_INVALID_SIZE;
489  return NULL;
490  }
491 
492  a = Asn1GenericNew();
493  if (a == NULL) {
494  *errcode = ERR_DER_GENERIC;
495  return NULL;
496  }
497 
498  a->type = ASN1_BITSTRING;
499  a->strlen = length;
500 
501  a->str = SCMalloc(length);
502  if (a->str == NULL) {
503  *errcode = ERR_DER_GENERIC;
504  SCFree(a);
505  return NULL;
506  }
507  memcpy(a->str, (const char*)d_ptr, length);
508 
509  d_ptr += length;
510 
511  a->length = (d_ptr - buffer);
512  return a;
513 }
514 
515 static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer,
516  uint32_t max_size, uint8_t depth,
517  uint32_t *errcode)
518 {
519  const unsigned char *d_ptr = buffer;
520  uint32_t oid_length, oid_value;
521  uint8_t numbytes, c;
522  Asn1Generic *a;
523  uint32_t i;
524 
525  d_ptr++;
526 
527  /* size */
528  c = d_ptr[0];
529  /* short form 8.1.3.4 */
530  if ((c & (1<<7))>>7 == 0) {
531  oid_length = c;
532  d_ptr++;
533  /* long form 8.1.3.5 */
534  } else {
535  numbytes = c & 0x7f;
536  if ((uint32_t)(numbytes + 2) > max_size) {
537  *errcode = ERR_DER_INVALID_SIZE;
538  return NULL;
539  }
540  d_ptr++;
541  if (DecodeAsn1BuildValue(&d_ptr, &oid_length, numbytes, errcode) == -1) {
542  return NULL;
543  }
544  }
545 
546  if (oid_length == 0 || (d_ptr-buffer) + oid_length > max_size) {
547  *errcode = ERR_DER_INVALID_SIZE;
548  return NULL;
549  }
550 
551  a = Asn1GenericNew();
552  if (a == NULL) {
553  *errcode = ERR_DER_GENERIC;
554  return NULL;
555  }
556 
557  a->type = ASN1_OID;
558 
560  if (a->str == NULL) {
561  *errcode = ERR_DER_GENERIC;
562  SCFree(a);
563  return NULL;
564  }
565 
566  /* first element = X*40 + Y (See 8.19.4) */
567  snprintf(a->str, MAX_OID_LENGTH, "%d.%d", (d_ptr[0]/40), (d_ptr[0]%40));
568  d_ptr++;
569 
570  if (oid_length + (d_ptr-buffer) > max_size) {
571  *errcode = ERR_DER_INVALID_SIZE;
572  SCFree(a->str);
573  SCFree(a);
574  return NULL;
575  }
576 
577  /* sub-identifiers are multi-valued, coded and 7 bits, first bit of
578  the 8bits is used to indicate, if a new value is starting */
579  for (i=1; i<oid_length; ) {
580  int s = strlen(a->str);
581  c = d_ptr[0];
582  oid_value = 0;
583  while ( i<oid_length && (c & (1<<7)) == 1<<7 ) {
584  oid_value = oid_value<<7 | (c & ~(1<<7));
585  d_ptr++;
586  c = d_ptr[0];
587  i++;
588  }
589  oid_value = oid_value<<7 | c;
590  d_ptr++;
591  i++;
592  snprintf(a->str + s, MAX_OID_LENGTH - s, ".%d", oid_value);
593  }
594 
595  a->length = (d_ptr - buffer);
596  return a;
597 }
598 
599 static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer,
600  uint32_t max_size, uint8_t depth,
601  uint32_t *errcode)
602 {
603  const unsigned char *d_ptr = buffer;
604  uint32_t length, numbytes;
605  Asn1Generic *a;
606  unsigned char c;
607 
608  d_ptr++;
609  max_size--;
610 
611  /* total sequence length */
612  c = d_ptr[0];
613  /* short form 8.1.3.4 */
614  if ((c & (1<<7))>>7 == 0) {
615  length = c;
616  d_ptr++;
617  max_size--;
618  /* long form 8.1.3.5 */
619  } else {
620  numbytes = c & 0x7f;
621  if (max_size < 1 + numbytes) {
622  *errcode = ERR_DER_INVALID_SIZE;
623  return NULL;
624  }
625  max_size -= 1 + numbytes;
626  d_ptr++;
627  if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
628  return NULL;
629  }
630  }
631 
632  if (length == UINT32_MAX || (d_ptr-buffer) + length > max_size) {
633  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
634  return NULL;
635  }
636 
637  a = Asn1GenericNew();
638  if (a == NULL) {
639  *errcode = ERR_DER_GENERIC;
640  return NULL;
641  }
642 
643  a->type = ASN1_IA5STRING;
644  a->strlen = length;
645 
646  a->str = SCMalloc(length+1);
647  if (a->str == NULL) {
648  *errcode = ERR_DER_GENERIC;
649  SCFree(a);
650  return NULL;
651  }
652  memcpy(a->str, (const char*)d_ptr, length);
653  a->str[length] = 0;
654 
655  d_ptr += length;
656 
657  a->length = (d_ptr - buffer);
658  return a;
659 }
660 
661 static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer,
662  uint32_t max_size, uint8_t depth,
663  uint32_t *errcode)
664 {
665  const unsigned char *d_ptr = buffer;
666  uint32_t length, numbytes;
667  Asn1Generic *a;
668  unsigned char c;
669 
670  d_ptr++;
671  max_size--;
672 
673  /* total sequence length */
674  c = d_ptr[0];
675  /* short form 8.1.3.4 */
676  if ((c & (1<<7))>>7 == 0) {
677  length = c;
678  d_ptr++;
679  max_size--;
680  /* long form 8.1.3.5 */
681  } else {
682  numbytes = c & 0x7f;
683  if (max_size < 1 + numbytes) {
684  *errcode = ERR_DER_INVALID_SIZE;
685  return NULL;
686  }
687  max_size -= 1 + numbytes;
688  d_ptr++;
689  if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
690  return NULL;
691  }
692  }
693 
694  if (length == UINT32_MAX || (d_ptr-buffer) + length > max_size) {
695  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
696  return NULL;
697  }
698  a = Asn1GenericNew();
699  if (a == NULL) {
700  *errcode = ERR_DER_GENERIC;
701  return NULL;
702  }
703 
704  a->type = ASN1_OCTETSTRING;
705  a->strlen = length;
706 
707  /* add one to the octet string for the 0. This will then allow us to
708  use the string in printf */
709  a->str = SCMalloc(length + 1);
710  if (a->str == NULL) {
711  *errcode = ERR_DER_GENERIC;
712  SCFree(a);
713  return NULL;
714  }
715  memcpy(a->str, (const char*)d_ptr, length);
716  a->str[length] = 0;
717 
718  d_ptr += length;
719 
720  a->length = (d_ptr - buffer);
721  return a;
722 }
723 
724 static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer,
725  uint32_t max_size, uint8_t depth,
726  uint32_t *errcode)
727 {
728  Asn1Generic *a = DecodeAsn1DerOctetString(buffer, max_size, depth, errcode);
729  if (a != NULL)
730  a->type = ASN1_UTF8STRING;
731 
732  return a;
733 }
734 
735 static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer,
736  uint32_t max_size,
737  uint8_t depth,
738  uint32_t *errcode)
739 {
740  const unsigned char *d_ptr = buffer;
741  uint32_t length, numbytes;
742  Asn1Generic *a;
743  unsigned char c;
744 
745  d_ptr++;
746 
747  /* total sequence length */
748  c = d_ptr[0];
749  /* short form 8.1.3.4 */
750  if ((c & (1<<7))>>7 == 0) {
751  length = c;
752  d_ptr++;
753  /* long form 8.1.3.5 */
754  } else {
755  numbytes = c & 0x7f;
756  d_ptr++;
757  if (2 + numbytes > max_size) {
758  *errcode = ERR_DER_INVALID_SIZE;
759  return NULL;
760  }
761  if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
762  return NULL;
763  }
764  }
765 
766  if (length == UINT32_MAX || (d_ptr-buffer) + length > max_size) {
767  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
768  return NULL;
769  }
770 
771  a = Asn1GenericNew();
772  if (a == NULL) {
773  *errcode = ERR_DER_GENERIC;
774  return NULL;
775  }
776 
777  a->type = ASN1_PRINTSTRING;
778  a->strlen = length;
779 
780  a->str = SCMalloc(length+1);
781  if (a->str == NULL) {
782  *errcode = ERR_DER_GENERIC;
783  SCFree(a);
784  return NULL;
785  }
786  memcpy(a->str, (const char*)d_ptr, length);
787  a->str[length] = 0;
788 
789  d_ptr += length;
790 
791  a->length = (d_ptr - buffer);
792  return a;
793 }
794 
795 static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer,
796  uint32_t max_size, uint8_t depth,
797  uint32_t *errcode)
798 {
799  const unsigned char *d_ptr = buffer;
800  uint32_t d_length, parsed_bytes, numbytes, el_max_size;
801  uint8_t c;
802  uint32_t seq_index;
803  Asn1Generic *node;
804 
805  d_ptr++;
806 
807  node = Asn1GenericNew();
808  if (node == NULL) {
809  *errcode = ERR_DER_GENERIC;
810  return NULL;
811  }
812 
813  node->type = ASN1_SEQUENCE;
814 
815  /* total sequence length */
816  c = d_ptr[0];
817  /* short form 8.1.3.4 */
818  if ((c & (1<<7))>>7 == 0) {
819  d_length = c;
820  d_ptr++;
821  /* long form 8.1.3.5 */
822  } else {
823  numbytes = c & 0x7f;
824  d_ptr++;
825  if ( 2 + numbytes > max_size ) {
826  *errcode = ERR_DER_INVALID_SIZE;
827  SCFree(node);
828  return NULL;
829  }
830  if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
831  SCFree(node);
832  return NULL;
833  }
834  }
835  node->length = d_length + (d_ptr - buffer);
836  if (node->length > max_size || node->length < d_length /* wrap */) {
837  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
838  SCFree(node);
839  return NULL;
840  }
841 
842  parsed_bytes = 0;
843  seq_index = 0;
844 
845  /* decode child elements */
846  while (parsed_bytes < d_length) {
847  el_max_size = max_size - (d_ptr-buffer);
848 
849  Asn1Generic *child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth,
850  seq_index, errcode);
851  if (child == NULL) {
852  if (*errcode != 0) {
853  DerFree(node);
854  return NULL;
855  }
856  break;
857  }
858 
859  int ret = Asn1SequenceAppend(node, child);
860  if (ret == -1) {
861  DerFree(child);
862  break;
863  }
864 
865  parsed_bytes += child->length;
866  d_ptr += child->length;
867  seq_index++;
868  }
869 
870  return (Asn1Generic *)node;
871 }
872 
873 static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer,
874  uint32_t max_size, uint8_t depth,
875  uint32_t *errcode)
876 {
877  const unsigned char *d_ptr = buffer;
878  uint32_t d_length, numbytes, el_max_size;
879  uint8_t c;
880  uint32_t seq_index;
881  Asn1Generic *node;
882  Asn1Generic *child;
883 
884  d_ptr++;
885 
886  node = Asn1GenericNew();
887  if (node == NULL) {
888  *errcode = ERR_DER_GENERIC;
889  return NULL;
890  }
891  node->type = ASN1_SET;
892  node->data = NULL;
893 
894  /* total sequence length */
895  c = d_ptr[0];
896  /* short form 8.1.3.4 */
897  if ((c & (1<<7))>>7 == 0) {
898  d_length = c;
899  d_ptr++;
900  /* long form 8.1.3.5 */
901  } else {
902  numbytes = c & 0x7f;
903  if (2 + numbytes > max_size) {
904  *errcode = ERR_DER_INVALID_SIZE;
905  SCFree(node);
906  return NULL;
907  }
908  d_ptr++;
909  if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
910  SCFree(node);
911  return NULL;
912  }
913  }
914 
915  node->length = d_length + (d_ptr - buffer);
916 
917  if (node->length > max_size || node->length < d_length /* wrap */) {
918  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
919  SCFree(node);
920  return NULL;
921  }
922 
923  seq_index = 0;
924 
925  el_max_size = max_size - (d_ptr-buffer);
926 
927  child = DecodeAsn1DerGeneric(d_ptr, el_max_size, depth, seq_index, errcode);
928  if (child == NULL) {
929  DerFree(node);
930  return NULL;
931  }
932 
933  node->data = child;
934 
935  return (Asn1Generic *)node;
936 }
937 
938 static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer,
939  uint32_t max_size, uint8_t depth,
940  uint32_t *errcode)
941 {
942  Asn1Generic *a;
943 
944  a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
945  if (a != NULL)
946  a->type = ASN1_T61STRING;
947 
948  return a;
949 }
950 
951 static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer,
952  uint32_t max_size, uint8_t depth,
953  uint32_t *errcode)
954 {
955  Asn1Generic *a;
956 
957  a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
958  if (a != NULL)
959  a->type = ASN1_UTCTIME;
960 
961  return a;
962 }
963 
964 static Asn1Generic * DecodeAsn1DerGeneralizedTime(const unsigned char *buffer,
965  uint32_t max_size,
966  uint8_t depth,
967  uint32_t *errcode)
968 {
969  Asn1Generic *a;
970 
971  a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
972  if (a != NULL)
974 
975  return a;
976 }
977 
978 /**
979  * \param errcode pointer to error code variable. May not be NULL.
980  */
981 Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size,
982  uint32_t *errcode)
983 {
984  const unsigned char *d_ptr = buffer;
985  uint32_t d_length, numbytes;
986  Asn1Generic *cert;
987  uint8_t c;
988 
989  DEBUG_VALIDATE_BUG_ON(errcode == NULL);
990  *errcode = 0;
991 
992  if (size < 2) {
993  *errcode = ERR_DER_INVALID_SIZE;
994  return NULL;
995  }
996 
997  /* check that buffer is an ASN.1 structure (basic checks) */
998  if (d_ptr[0] != 0x30 && d_ptr[1] != 0x82) { /* Sequence */
999  *errcode = ERR_DER_UNKNOWN_ELEMENT;
1000  return NULL;
1001  }
1002 
1003  c = d_ptr[1];
1004  if ((c & (1<<7))>>7 != 1) {
1005  *errcode = ERR_DER_INVALID_SIZE;
1006  return NULL;
1007  }
1008 
1009  numbytes = c & 0x7f;
1010  d_ptr += 2;
1011  if (size < numbytes + 2) {
1012  *errcode = ERR_DER_INVALID_SIZE;
1013  return NULL;
1014  }
1015  if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
1016  return NULL;
1017  }
1018 
1019  if (d_length+(d_ptr-buffer) != size) {
1020  *errcode = ERR_DER_INVALID_SIZE;
1021  return NULL;
1022  }
1023 
1024  cert = DecodeAsn1DerGeneric(buffer, size, 0 /* depth */, 0, errcode);
1025 
1026  return cert;
1027 }
1028 
1029 #ifdef AFLFUZZ_DER
1030 int DerParseDataFromFile(char *filename)
1031 {
1032  uint8_t buffer[65536];
1033  uint32_t errcode = 0;
1034 
1035 #ifdef AFLFUZZ_PERSISTANT_MODE
1036  while (__AFL_LOOP(1000)) {
1037  /* reset state */
1038  memset(buffer, 0, sizeof(buffer));
1039 #endif /* AFLFUZZ_PERSISTANT_MODE */
1040 
1041  FILE *fp = fopen(filename, "r");
1042  BUG_ON(fp == NULL);
1043 
1044  size_t result = fread(&buffer, 1, sizeof(buffer), fp);
1045  Asn1Generic *a = DecodeDer(buffer, result, &errcode);
1046  DerFree(a);
1047  fclose(fp);
1048 
1049 #ifdef AFLFUZZ_PERSISTANT_MODE
1050  }
1051 #endif /* AFLFUZZ_PERSISTANT_MODE */
1052 
1053  return 0;
1054 }
1055 #endif /* AFLFUZZ_DER */
1056 
1058 {
1059  Asn1Generic *it, *n;
1060 
1061  if (a == NULL)
1062  return;
1063 
1064  it = a;
1065  while (it) {
1066  n = it->next;
1067  if (it->data) {
1068  DerFree(it->data);
1069  }
1070  if (it->str)
1071  SCFree(it->str);
1072  memset(it, 0xff, sizeof(Asn1Generic));
1073  SCFree(it);
1074  it = n;
1075  }
1076 }
#define BUG_ON(x)
uint64_t value
#define ASN1_OID
void DerFree(Asn1Generic *a)
#define unlikely(expr)
Definition: util-optimize.h:35
#define ASN1_CLASS_CONTEXTSPEC
#define ASN1_UTF8STRING
struct Asn1Generic_ * next
#define ERR_DER_RECURSION_LIMIT
Asn1ElementType header
#define ASN1_PRINTSTRING
#define ASN1_SEQUENCE
#define ERR_DER_INVALID_SIZE
#define ASN1_BOOLEAN
#define ASN1_NULL
typedef __attribute__
DNP3 application header.
#define MAX_OID_LENGTH
#define ASN1_BITSTRING
uint32_t seq
uint32_t length
#define ASN1_OCTETSTRING
struct Asn1Generic_ * data
#define ERR_DER_GENERIC
#define SCMalloc(a)
Definition: util-mem.h:166
#define ERR_DER_ELEMENT_SIZE_TOO_BIG
#define ASN1_IA5STRING
#define SCFree(a)
Definition: util-mem.h:228
#define ASN1_GENERALIZEDTIME
#define ASN1_SET
#define ERR_DER_INVALID_OBJECT
#define ASN1_INTEGER
#define ERR_DER_UNKNOWN_ELEMENT
#define ASN1_UTCTIME
uint16_t length
uint32_t strlen
Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size, uint32_t *errcode)
#define ERR_DER_INVALID_TAG
#define DEBUG_VALIDATE_BUG_ON(exp)
#define ASN1_T61STRING