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 /* openssl has set a limit of 30, so stay close to that. */
134 #define DER_MAX_RECURSION_DEPTH 32
135 
136 static Asn1Generic * DecodeAsn1DerGeneric(const unsigned char *buffer,
137  uint32_t max_size, uint8_t depth,
138  int seq_index, uint32_t *errcode)
139 {
140  const unsigned char *d_ptr = buffer;
141  uint32_t numbytes, el_max_size;
142  Asn1ElementType el;
143  uint8_t c;
144  uint32_t i;
145  Asn1Generic *child;
146  uint8_t el_type;
147 
148  /* refuse excessive recursion */
149  if (unlikely(depth >= DER_MAX_RECURSION_DEPTH)) {
150  *errcode = ERR_DER_RECURSION_LIMIT;
151  return NULL;
152  }
153  if (max_size < 2) {
154  *errcode = ERR_DER_INVALID_SIZE;
155  return NULL;
156  }
157 
158  el.cls = (d_ptr[0] & 0xc0) >> 6;
159  el.pc = (d_ptr[0] & 0x20) >> 5;
160  el.tag = (d_ptr[0] & 0x1f);
161 
162  el_type = el.tag;
163 
164  if (el.tag == 0x1f) {
165  *errcode = ERR_DER_INVALID_TAG;
166  return NULL;
167  }
168 
169  switch (el.cls) {
171  /* get element type from definition, see:
172  http://www.ietf.org/rfc/rfc3280.txt */
173  if (depth == 2 && el.tag == 0) {
174  /* TBSCertificate */
175  el_type = ASN1_SEQUENCE;
176  break;
177  }
178  if (depth == 2 && el.tag == 1) {
179  /* issuerUniqueID */
180  el_type = ASN1_BITSTRING;
181  break;
182  }
183  if (depth == 2 && el.tag == 2) {
184  /* subjectUniqueID */
185  el_type = ASN1_BITSTRING;
186  break;
187  }
188  if (depth == 2 && el.tag == 3) {
189  /* extensions */
190  el_type = ASN1_SEQUENCE;
191  break;
192  }
193  /* unknown context specific value - do not decode */
194  break;
195  };
196 
197  el_max_size = max_size - (d_ptr-buffer);
198  switch (el_type) {
199  case ASN1_INTEGER:
200  child = DecodeAsn1DerInteger(d_ptr, el_max_size, depth+1, errcode);
201  break;
202  case ASN1_BOOLEAN:
203  child = DecodeAsn1DerBoolean(d_ptr, el_max_size, depth+1, errcode);
204  break;
205  case ASN1_NULL:
206  child = DecodeAsn1DerNull(d_ptr, el_max_size, depth+1, errcode);
207  break;
208  case ASN1_BITSTRING:
209  child = DecodeAsn1DerBitstring(d_ptr, el_max_size, depth+1,
210  errcode);
211  break;
212  case ASN1_OID:
213  child = DecodeAsn1DerOid(d_ptr, el_max_size, depth+1, errcode);
214  break;
215  case ASN1_IA5STRING:
216  child = DecodeAsn1DerIA5String(d_ptr, el_max_size, depth+1,
217  errcode);
218  break;
219  case ASN1_OCTETSTRING:
220  child = DecodeAsn1DerOctetString(d_ptr, el_max_size, depth+1,
221  errcode);
222  break;
223  case ASN1_UTF8STRING:
224  child = DecodeAsn1DerUTF8String(d_ptr, el_max_size, depth+1,
225  errcode);
226  break;
227  case ASN1_PRINTSTRING:
228  child = DecodeAsn1DerPrintableString(d_ptr, el_max_size, depth+1,
229  errcode);
230  break;
231  case ASN1_SEQUENCE:
232  child = DecodeAsn1DerSequence(d_ptr, el_max_size, depth+1, errcode);
233  break;
234  case ASN1_SET:
235  child = DecodeAsn1DerSet(d_ptr, el_max_size, depth+1, errcode);
236  break;
237  case ASN1_T61STRING:
238  child = DecodeAsn1DerT61String(d_ptr, el_max_size, depth+1,
239  errcode);
240  break;
241  case ASN1_UTCTIME:
242  child = DecodeAsn1DerUTCTime(d_ptr, el_max_size, depth+1, errcode);
243  break;
245  child = DecodeAsn1DerGeneralizedTime(d_ptr, el_max_size, depth+1, errcode);
246  break;
247  default:
248  /* unknown ASN.1 type */
249  child = NULL;
250  child = Asn1GenericNew();
251  if (child == NULL)
252  break;
253 
254  child->type = el.tag;
255 
256  /* total sequence length */
257  const unsigned char * save_d_ptr = d_ptr;
258  d_ptr++;
259  el_max_size--;
260  c = d_ptr[0];
261 
262  /* short form 8.1.3.4 */
263  if ((c & (1<<7))>>7 == 0) {
264  child->length = c;
265  d_ptr++;
266  /* long form 8.1.3.5 */
267  } else {
268  numbytes = c & 0x7f;
269  if (2 + numbytes > el_max_size) {
270  SCFree(child);
271  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
272  return NULL;
273  }
274  child->length = 0;
275  d_ptr++;
276  for (i=0; i<numbytes; i++) {
277  child->length = child->length<<8 | d_ptr[0];
278  d_ptr++;
279  }
280  }
281 
282  /* fix the length for unknown objects, else sequence parsing
283  will fail */
284  child->length += (d_ptr - save_d_ptr);
285 
286  if (child->length > max_size - (d_ptr - buffer)) {
287  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
288  SCFree(child);
289  return NULL;
290  }
291 
292  break;
293  };
294 
295  if (child == NULL) {
296  if (*errcode == 0)
297  *errcode = ERR_DER_INVALID_OBJECT;
298  return NULL;
299  }
300 
301  /* child length should never be zero */
302  if (child->length == 0) {
303  *errcode = ERR_DER_INVALID_OBJECT;
304  SCFree(child);
305  return NULL;
306  }
307 
308  child->header = el;
309  return child;
310 }
311 
312 static Asn1Generic * DecodeAsn1DerInteger(const unsigned char *buffer,
313  uint32_t size, uint8_t depth,
314  uint32_t *errcode)
315 {
316  const unsigned char *d_ptr = buffer;
317  uint8_t numbytes;
318  uint32_t value;
319  uint32_t i;
320  Asn1Generic *a;
321 
322  numbytes = d_ptr[1];
323 
324  if ((uint32_t)(numbytes + 2) > size) {
325  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
326  return NULL;
327  }
328 
329  d_ptr += 2;
330 
331  value = 0;
332 
333  /* Here we need to ensure that numbytes is less than 4
334  so integer affectation is possible. We set the value
335  to 0xffffffff which is by convention the unknown value.
336  In this case, the hexadecimal value must be used. */
337  if (numbytes > 4) {
338  value = 0xffffffff;
339  } else {
340  for (i=0; i<numbytes; i++) {
341  value = value<<8 | d_ptr[i];
342  }
343  }
344 
345  a = Asn1GenericNew();
346  if (a == NULL) {
347  *errcode = ERR_DER_GENERIC;
348  return NULL;
349  }
350 
351  a->type = ASN1_INTEGER;
352  a->length = (d_ptr - buffer) + numbytes;
353  a->value = value;
354 
355  a->str = SCMalloc(2*numbytes + 1);
356  if (a->str == NULL) {
357  *errcode = ERR_DER_GENERIC;
358  SCFree(a);
359  return NULL;
360  }
361 
362  for (i=0; i<numbytes; i++) {
363  snprintf(a->str + 2*i, 2*(numbytes-i)+1, "%02X", d_ptr[i]);
364  }
365  a->str[2*numbytes]= '\0';
366 
367  return a;
368 }
369 
370 static int DecodeAsn1BuildValue(const unsigned char **d_ptr, uint32_t *val,
371  uint8_t numbytes, uint32_t *errcode)
372 {
373  int i;
374  uint32_t value = 0;
375 
376  if (numbytes > 4) {
377  *errcode = ERR_DER_INVALID_SIZE;
378 
379  /* too big won't fit: set it to 0xffffffff by convention */
380  value = 0xffffffff;
381  *val = value;
382  return -1;
383  } else {
384  for (i=0; i<numbytes; i++) {
385  value = value<<8 | (*d_ptr)[0];
386  (*d_ptr)++;
387  }
388  }
389 
390  *val = value;
391  return 0;
392 }
393 
394 static Asn1Generic * DecodeAsn1DerBoolean(const unsigned char *buffer,
395  uint32_t size, uint8_t depth,
396  uint32_t *errcode)
397 {
398  const unsigned char *d_ptr = buffer;
399  uint8_t numbytes;
400  uint32_t value;
401  Asn1Generic *a;
402 
403  numbytes = d_ptr[1];
404  if ((uint32_t)(numbytes + 2) > size) {
405  *errcode = ERR_DER_INVALID_SIZE;
406  return NULL;
407  }
408  d_ptr += 2;
409 
410  if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes, errcode) == -1) {
411  return NULL;
412  }
413 
414  a = Asn1GenericNew();
415  if (a == NULL) {
416  *errcode = ERR_DER_GENERIC;
417  return NULL;
418  }
419 
420  a->type = ASN1_BOOLEAN;
421  a->length = (d_ptr - buffer);
422  a->value = value;
423 
424  return a;
425 }
426 
427 static Asn1Generic * DecodeAsn1DerNull(const unsigned char *buffer,
428  uint32_t size, uint8_t depth,
429  uint32_t *errcode)
430 {
431  const unsigned char *d_ptr = buffer;
432  uint8_t numbytes;
433  uint32_t value;
434  Asn1Generic *a;
435 
436  numbytes = d_ptr[1];
437  if ((uint32_t)(numbytes + 2) > size) {
438  *errcode = ERR_DER_INVALID_SIZE;
439  return NULL;
440  }
441  d_ptr += 2;
442 
443  if (DecodeAsn1BuildValue(&d_ptr, &value, numbytes, errcode) == -1) {
444  return NULL;
445  }
446 
447  a = Asn1GenericNew();
448  if (a == NULL) {
449  *errcode = ERR_DER_GENERIC;
450  return NULL;
451  }
452 
453  a->type = ASN1_NULL;
454  a->length = (d_ptr - buffer);
455  a->value = 0;
456 
457  return a;
458 }
459 
460 static Asn1Generic * DecodeAsn1DerBitstring(const unsigned char *buffer,
461  uint32_t max_size, uint8_t depth,
462  uint32_t *errcode)
463 {
464  const unsigned char *d_ptr = buffer;
465  uint32_t length;
466  uint8_t numbytes, c;
467  Asn1Generic *a;
468 
469  d_ptr++;
470 
471  /* size */
472  c = d_ptr[0];
473  /* short form 8.1.3.4 */
474  if ((c & (1<<7))>>7 == 0) {
475  length = c;
476  d_ptr++;
477  /* long form 8.1.3.5 */
478  } else {
479  numbytes = c & 0x7f;
480  if ((uint32_t)(numbytes + 2) > max_size) {
481  *errcode = ERR_DER_INVALID_SIZE;
482  return NULL;
483  }
484  d_ptr++;
485  if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
486  return NULL;
487  }
488  }
489 
490  if ((d_ptr-buffer) + length > max_size) {
491  *errcode = ERR_DER_INVALID_SIZE;
492  return NULL;
493  }
494 
495  a = Asn1GenericNew();
496  if (a == NULL) {
497  *errcode = ERR_DER_GENERIC;
498  return NULL;
499  }
500 
501  a->type = ASN1_BITSTRING;
502  a->strlen = length;
503 
504  a->str = SCMalloc(length);
505  if (a->str == NULL) {
506  *errcode = ERR_DER_GENERIC;
507  SCFree(a);
508  return NULL;
509  }
510  memcpy(a->str, (const char*)d_ptr, length);
511 
512  d_ptr += length;
513 
514  a->length = (d_ptr - buffer);
515  return a;
516 }
517 
518 static Asn1Generic * DecodeAsn1DerOid(const unsigned char *buffer,
519  uint32_t max_size, uint8_t depth,
520  uint32_t *errcode)
521 {
522  const unsigned char *d_ptr = buffer;
523  uint32_t oid_length, oid_value;
524  uint8_t numbytes, c;
525  Asn1Generic *a;
526  uint32_t i;
527 
528  d_ptr++;
529 
530  /* size */
531  c = d_ptr[0];
532  /* short form 8.1.3.4 */
533  if ((c & (1<<7))>>7 == 0) {
534  oid_length = c;
535  d_ptr++;
536  /* long form 8.1.3.5 */
537  } else {
538  numbytes = c & 0x7f;
539  if ((uint32_t)(numbytes + 2) > max_size) {
540  *errcode = ERR_DER_INVALID_SIZE;
541  return NULL;
542  }
543  d_ptr++;
544  if (DecodeAsn1BuildValue(&d_ptr, &oid_length, numbytes, errcode) == -1) {
545  return NULL;
546  }
547  }
548 
549  if (oid_length == 0 || (d_ptr-buffer) + oid_length > max_size) {
550  *errcode = ERR_DER_INVALID_SIZE;
551  return NULL;
552  }
553 
554  a = Asn1GenericNew();
555  if (a == NULL) {
556  *errcode = ERR_DER_GENERIC;
557  return NULL;
558  }
559 
560  a->type = ASN1_OID;
561 
563  if (a->str == NULL) {
564  *errcode = ERR_DER_GENERIC;
565  SCFree(a);
566  return NULL;
567  }
568 
569  /* first element = X*40 + Y (See 8.19.4) */
570  snprintf(a->str, MAX_OID_LENGTH, "%d.%d", (d_ptr[0]/40), (d_ptr[0]%40));
571  d_ptr++;
572 
573  if (oid_length + (d_ptr-buffer) > max_size) {
574  *errcode = ERR_DER_INVALID_SIZE;
575  SCFree(a->str);
576  SCFree(a);
577  return NULL;
578  }
579 
580  /* sub-identifiers are multi-valued, coded and 7 bits, first bit of
581  the 8bits is used to indicate, if a new value is starting */
582  for (i=1; i<oid_length; ) {
583  int s = strlen(a->str);
584  c = d_ptr[0];
585  oid_value = 0;
586  while ( i<oid_length && (c & (1<<7)) == 1<<7 ) {
587  oid_value = oid_value<<7 | (c & ~(1<<7));
588  d_ptr++;
589  c = d_ptr[0];
590  i++;
591  }
592  oid_value = oid_value<<7 | c;
593  d_ptr++;
594  i++;
595  snprintf(a->str + s, MAX_OID_LENGTH - s, ".%d", oid_value);
596  }
597 
598  a->length = (d_ptr - buffer);
599  return a;
600 }
601 
602 static Asn1Generic * DecodeAsn1DerIA5String(const unsigned char *buffer,
603  uint32_t max_size, uint8_t depth,
604  uint32_t *errcode)
605 {
606  const unsigned char *d_ptr = buffer;
607  uint32_t length, numbytes;
608  Asn1Generic *a;
609  unsigned char c;
610 
611  d_ptr++;
612  max_size--;
613 
614  /* total sequence length */
615  c = d_ptr[0];
616  /* short form 8.1.3.4 */
617  if ((c & (1<<7))>>7 == 0) {
618  length = c;
619  d_ptr++;
620  max_size--;
621  /* long form 8.1.3.5 */
622  } else {
623  numbytes = c & 0x7f;
624  if (max_size < 1 + numbytes) {
625  *errcode = ERR_DER_INVALID_SIZE;
626  return NULL;
627  }
628  max_size -= 1 + numbytes;
629  d_ptr++;
630  if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
631  return NULL;
632  }
633  }
634 
635  if (length == UINT32_MAX || (d_ptr-buffer) + length > max_size) {
636  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
637  return NULL;
638  }
639 
640  a = Asn1GenericNew();
641  if (a == NULL) {
642  *errcode = ERR_DER_GENERIC;
643  return NULL;
644  }
645 
646  a->type = ASN1_IA5STRING;
647  a->strlen = length;
648 
649  a->str = SCMalloc(length+1);
650  if (a->str == NULL) {
651  *errcode = ERR_DER_GENERIC;
652  SCFree(a);
653  return NULL;
654  }
655  memcpy(a->str, (const char*)d_ptr, length);
656  a->str[length] = 0;
657 
658  d_ptr += length;
659 
660  a->length = (d_ptr - buffer);
661  return a;
662 }
663 
664 static Asn1Generic * DecodeAsn1DerOctetString(const unsigned char *buffer,
665  uint32_t max_size, uint8_t depth,
666  uint32_t *errcode)
667 {
668  const unsigned char *d_ptr = buffer;
669  uint32_t length, numbytes;
670  Asn1Generic *a;
671  unsigned char c;
672 
673  d_ptr++;
674  max_size--;
675 
676  /* total sequence length */
677  c = d_ptr[0];
678  /* short form 8.1.3.4 */
679  if ((c & (1<<7))>>7 == 0) {
680  length = c;
681  d_ptr++;
682  max_size--;
683  /* long form 8.1.3.5 */
684  } else {
685  numbytes = c & 0x7f;
686  if (max_size < 1 + numbytes) {
687  *errcode = ERR_DER_INVALID_SIZE;
688  return NULL;
689  }
690  max_size -= 1 + numbytes;
691  d_ptr++;
692  if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
693  return NULL;
694  }
695  }
696 
697  if (length == UINT32_MAX || (d_ptr-buffer) + length > max_size) {
698  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
699  return NULL;
700  }
701  a = Asn1GenericNew();
702  if (a == NULL) {
703  *errcode = ERR_DER_GENERIC;
704  return NULL;
705  }
706 
707  a->type = ASN1_OCTETSTRING;
708  a->strlen = length;
709 
710  /* add one to the octet string for the 0. This will then allow us to
711  use the string in printf */
712  a->str = SCMalloc(length + 1);
713  if (a->str == NULL) {
714  *errcode = ERR_DER_GENERIC;
715  SCFree(a);
716  return NULL;
717  }
718  memcpy(a->str, (const char*)d_ptr, length);
719  a->str[length] = 0;
720 
721  d_ptr += length;
722 
723  a->length = (d_ptr - buffer);
724  return a;
725 }
726 
727 static Asn1Generic * DecodeAsn1DerUTF8String(const unsigned char *buffer,
728  uint32_t max_size, uint8_t depth,
729  uint32_t *errcode)
730 {
731  Asn1Generic *a = DecodeAsn1DerOctetString(buffer, max_size, depth, errcode);
732  if (a != NULL)
733  a->type = ASN1_UTF8STRING;
734 
735  return a;
736 }
737 
738 static Asn1Generic * DecodeAsn1DerPrintableString(const unsigned char *buffer,
739  uint32_t max_size,
740  uint8_t depth,
741  uint32_t *errcode)
742 {
743  const unsigned char *d_ptr = buffer;
744  uint32_t length, numbytes;
745  Asn1Generic *a;
746  unsigned char c;
747 
748  d_ptr++;
749 
750  /* total sequence length */
751  c = d_ptr[0];
752  /* short form 8.1.3.4 */
753  if ((c & (1<<7))>>7 == 0) {
754  length = c;
755  d_ptr++;
756  /* long form 8.1.3.5 */
757  } else {
758  numbytes = c & 0x7f;
759  d_ptr++;
760  if (2 + numbytes > max_size) {
761  *errcode = ERR_DER_INVALID_SIZE;
762  return NULL;
763  }
764  if (DecodeAsn1BuildValue(&d_ptr, &length, numbytes, errcode) == -1) {
765  return NULL;
766  }
767  }
768 
769  if (length == UINT32_MAX || (d_ptr-buffer) + length > max_size) {
770  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
771  return NULL;
772  }
773 
774  a = Asn1GenericNew();
775  if (a == NULL) {
776  *errcode = ERR_DER_GENERIC;
777  return NULL;
778  }
779 
780  a->type = ASN1_PRINTSTRING;
781  a->strlen = length;
782 
783  a->str = SCMalloc(length+1);
784  if (a->str == NULL) {
785  *errcode = ERR_DER_GENERIC;
786  SCFree(a);
787  return NULL;
788  }
789  memcpy(a->str, (const char*)d_ptr, length);
790  a->str[length] = 0;
791 
792  d_ptr += length;
793 
794  a->length = (d_ptr - buffer);
795  return a;
796 }
797 
798 static Asn1Generic * DecodeAsn1DerSequence(const unsigned char *buffer,
799  uint32_t max_size, uint8_t depth,
800  uint32_t *errcode)
801 {
802  const unsigned char *d_ptr = buffer;
803  uint32_t d_length, parsed_bytes, numbytes, el_max_size;
804  uint8_t c;
805  uint32_t seq_index;
806  Asn1Generic *node;
807 
808  d_ptr++;
809 
810  node = Asn1GenericNew();
811  if (node == NULL) {
812  *errcode = ERR_DER_GENERIC;
813  return NULL;
814  }
815 
816  node->type = ASN1_SEQUENCE;
817 
818  /* total sequence length */
819  c = d_ptr[0];
820  /* short form 8.1.3.4 */
821  if ((c & (1<<7))>>7 == 0) {
822  d_length = c;
823  d_ptr++;
824  /* long form 8.1.3.5 */
825  } else {
826  numbytes = c & 0x7f;
827  d_ptr++;
828  if ( 2 + numbytes > max_size ) {
829  *errcode = ERR_DER_INVALID_SIZE;
830  SCFree(node);
831  return NULL;
832  }
833  if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
834  SCFree(node);
835  return NULL;
836  }
837  }
838  node->length = d_length + (d_ptr - buffer);
839  if (node->length > max_size || node->length < d_length /* wrap */) {
840  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
841  SCFree(node);
842  return NULL;
843  }
844 
845  parsed_bytes = 0;
846  seq_index = 0;
847 
848  /* decode child elements */
849  while (parsed_bytes < d_length) {
850  el_max_size = max_size - (d_ptr-buffer);
851 
852  Asn1Generic *child = DecodeAsn1DerGeneric(d_ptr,
853  MIN(node->length, el_max_size), depth,
854  seq_index, errcode);
855  if (child == NULL) {
856  if (*errcode != 0) {
857  DerFree(node);
858  return NULL;
859  }
860  break;
861  }
862 
863  int ret = Asn1SequenceAppend(node, child);
864  if (ret == -1) {
865  DerFree(child);
866  break;
867  }
868 
869  parsed_bytes += child->length;
870  d_ptr += child->length;
871  seq_index++;
872  }
873 
874  return (Asn1Generic *)node;
875 }
876 
877 static Asn1Generic * DecodeAsn1DerSet(const unsigned char *buffer,
878  uint32_t max_size, uint8_t depth,
879  uint32_t *errcode)
880 {
881  const unsigned char *d_ptr = buffer;
882  uint32_t d_length, numbytes, el_max_size;
883  uint8_t c;
884  uint32_t seq_index;
885  Asn1Generic *node;
886  Asn1Generic *child;
887 
888  d_ptr++;
889 
890  node = Asn1GenericNew();
891  if (node == NULL) {
892  *errcode = ERR_DER_GENERIC;
893  return NULL;
894  }
895  node->type = ASN1_SET;
896  node->data = NULL;
897 
898  /* total sequence length */
899  c = d_ptr[0];
900  /* short form 8.1.3.4 */
901  if ((c & (1<<7))>>7 == 0) {
902  d_length = c;
903  d_ptr++;
904  /* long form 8.1.3.5 */
905  } else {
906  numbytes = c & 0x7f;
907  if (2 + numbytes > max_size) {
908  *errcode = ERR_DER_INVALID_SIZE;
909  SCFree(node);
910  return NULL;
911  }
912  d_ptr++;
913  if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
914  SCFree(node);
915  return NULL;
916  }
917  }
918 
919  node->length = d_length + (d_ptr - buffer);
920 
921  if (node->length > max_size || node->length < d_length /* wrap */) {
922  *errcode = ERR_DER_ELEMENT_SIZE_TOO_BIG;
923  SCFree(node);
924  return NULL;
925  }
926 
927  seq_index = 0;
928 
929  el_max_size = max_size - (d_ptr-buffer);
930 
931  child = DecodeAsn1DerGeneric(d_ptr, MIN(node->length, el_max_size),
932  depth, seq_index, errcode);
933  if (child == NULL) {
934  DerFree(node);
935  return NULL;
936  }
937 
938  node->data = child;
939 
940  return (Asn1Generic *)node;
941 }
942 
943 static Asn1Generic * DecodeAsn1DerT61String(const unsigned char *buffer,
944  uint32_t max_size, uint8_t depth,
945  uint32_t *errcode)
946 {
947  Asn1Generic *a;
948 
949  a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
950  if (a != NULL)
951  a->type = ASN1_T61STRING;
952 
953  return a;
954 }
955 
956 static Asn1Generic * DecodeAsn1DerUTCTime(const unsigned char *buffer,
957  uint32_t max_size, uint8_t depth,
958  uint32_t *errcode)
959 {
960  Asn1Generic *a;
961 
962  a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
963  if (a != NULL)
964  a->type = ASN1_UTCTIME;
965 
966  return a;
967 }
968 
969 static Asn1Generic * DecodeAsn1DerGeneralizedTime(const unsigned char *buffer,
970  uint32_t max_size,
971  uint8_t depth,
972  uint32_t *errcode)
973 {
974  Asn1Generic *a;
975 
976  a = DecodeAsn1DerIA5String(buffer, max_size, depth, errcode);
977  if (a != NULL)
979 
980  return a;
981 }
982 
983 /**
984  * \param errcode pointer to error code variable. May not be NULL.
985  */
986 Asn1Generic * DecodeDer(const unsigned char *buffer, uint32_t size,
987  uint32_t *errcode)
988 {
989  const unsigned char *d_ptr = buffer;
990  uint32_t d_length, numbytes;
991  Asn1Generic *cert;
992  uint8_t c;
993 
994  DEBUG_VALIDATE_BUG_ON(errcode == NULL);
995  *errcode = 0;
996 
997  if (size < 2) {
998  *errcode = ERR_DER_INVALID_SIZE;
999  return NULL;
1000  }
1001 
1002  /* check that buffer is an ASN.1 structure (basic checks) */
1003  if (d_ptr[0] != 0x30 && d_ptr[1] != 0x82) { /* Sequence */
1004  *errcode = ERR_DER_UNKNOWN_ELEMENT;
1005  return NULL;
1006  }
1007 
1008  c = d_ptr[1];
1009  if ((c & (1<<7))>>7 != 1) {
1010  *errcode = ERR_DER_INVALID_SIZE;
1011  return NULL;
1012  }
1013 
1014  numbytes = c & 0x7f;
1015  d_ptr += 2;
1016  if (size < numbytes + 2) {
1017  *errcode = ERR_DER_INVALID_SIZE;
1018  return NULL;
1019  }
1020  if (DecodeAsn1BuildValue(&d_ptr, &d_length, numbytes, errcode) == -1) {
1021  return NULL;
1022  }
1023 
1024  if (d_length+(d_ptr-buffer) != size) {
1025  *errcode = ERR_DER_INVALID_SIZE;
1026  return NULL;
1027  }
1028 
1029  cert = DecodeAsn1DerGeneric(buffer, size, 0 /* depth */, 0, errcode);
1030 
1031  return cert;
1032 }
1033 
1034 #ifdef AFLFUZZ_DER
1035 int DerParseDataFromFile(char *filename)
1036 {
1037  uint8_t buffer[65536];
1038  uint32_t errcode = 0;
1039 
1040 #ifdef AFLFUZZ_PERSISTANT_MODE
1041  while (__AFL_LOOP(1000)) {
1042  /* reset state */
1043  memset(buffer, 0, sizeof(buffer));
1044 #endif /* AFLFUZZ_PERSISTANT_MODE */
1045 
1046  FILE *fp = fopen(filename, "r");
1047  BUG_ON(fp == NULL);
1048 
1049  size_t result = fread(&buffer, 1, sizeof(buffer), fp);
1050  Asn1Generic *a = DecodeDer(buffer, result, &errcode);
1051  DerFree(a);
1052  fclose(fp);
1053 
1054 #ifdef AFLFUZZ_PERSISTANT_MODE
1055  }
1056 #endif /* AFLFUZZ_PERSISTANT_MODE */
1057 
1058  return 0;
1059 }
1060 #endif /* AFLFUZZ_DER */
1061 
1063 {
1064  Asn1Generic *it, *n;
1065 
1066  if (a == NULL)
1067  return;
1068 
1069  it = a;
1070  while (it) {
1071  n = it->next;
1072  if (it->data) {
1073  DerFree(it->data);
1074  }
1075  if (it->str)
1076  SCFree(it->str);
1077  memset(it, 0xff, sizeof(Asn1Generic));
1078  SCFree(it);
1079  it = n;
1080  }
1081 }
#define BUG_ON(x)
uint64_t value
#define ASN1_OID
#define DER_MAX_RECURSION_DEPTH
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
#define MIN(x, y)
Asn1ElementType header
#define ASN1_PRINTSTRING
#define ASN1_SEQUENCE
#define ERR_DER_INVALID_SIZE
#define ASN1_BOOLEAN
enum @34 __attribute__
DNP3 application header.
#define ASN1_NULL
#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:222
#define ERR_DER_ELEMENT_SIZE_TOO_BIG
#define ASN1_IA5STRING
#define SCFree(a)
Definition: util-mem.h:322
#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