1 /* Copyright (c) 2014, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <openssl/buf.h>
16 #include <openssl/mem.h>
17 #include <openssl/bytestring.h>
18 
19 #include <assert.h>
20 #include <string.h>
21 
22 #include "internal.h"
23 #include "../internal.h"
24 
25 
CBS_init(CBS * cbs,const uint8_t * data,size_t len)26 void CBS_init(CBS *cbs, const uint8_t *data, size_t len) {
27   cbs->data = data;
28   cbs->len = len;
29 }
30 
cbs_get(CBS * cbs,const uint8_t ** p,size_t n)31 static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) {
32   if (cbs->len < n) {
33     return 0;
34   }
35 
36   *p = cbs->data;
37   cbs->data += n;
38   cbs->len -= n;
39   return 1;
40 }
41 
CBS_skip(CBS * cbs,size_t len)42 int CBS_skip(CBS *cbs, size_t len) {
43   const uint8_t *dummy;
44   return cbs_get(cbs, &dummy, len);
45 }
46 
CBS_data(const CBS * cbs)47 const uint8_t *CBS_data(const CBS *cbs) {
48   return cbs->data;
49 }
50 
CBS_len(const CBS * cbs)51 size_t CBS_len(const CBS *cbs) {
52   return cbs->len;
53 }
54 
CBS_stow(const CBS * cbs,uint8_t ** out_ptr,size_t * out_len)55 int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) {
56   OPENSSL_free(*out_ptr);
57   *out_ptr = NULL;
58   *out_len = 0;
59 
60   if (cbs->len == 0) {
61     return 1;
62   }
63   *out_ptr = BUF_memdup(cbs->data, cbs->len);
64   if (*out_ptr == NULL) {
65     return 0;
66   }
67   *out_len = cbs->len;
68   return 1;
69 }
70 
CBS_strdup(const CBS * cbs,char ** out_ptr)71 int CBS_strdup(const CBS *cbs, char **out_ptr) {
72   if (*out_ptr != NULL) {
73     OPENSSL_free(*out_ptr);
74   }
75   *out_ptr = BUF_strndup((const char*)cbs->data, cbs->len);
76   return (*out_ptr != NULL);
77 }
78 
CBS_contains_zero_byte(const CBS * cbs)79 int CBS_contains_zero_byte(const CBS *cbs) {
80   return OPENSSL_memchr(cbs->data, 0, cbs->len) != NULL;
81 }
82 
CBS_mem_equal(const CBS * cbs,const uint8_t * data,size_t len)83 int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) {
84   if (len != cbs->len) {
85     return 0;
86   }
87   return CRYPTO_memcmp(cbs->data, data, len) == 0;
88 }
89 
cbs_get_u(CBS * cbs,uint32_t * out,size_t len)90 static int cbs_get_u(CBS *cbs, uint32_t *out, size_t len) {
91   uint32_t result = 0;
92   const uint8_t *data;
93 
94   if (!cbs_get(cbs, &data, len)) {
95     return 0;
96   }
97   for (size_t i = 0; i < len; i++) {
98     result <<= 8;
99     result |= data[i];
100   }
101   *out = result;
102   return 1;
103 }
104 
CBS_get_u8(CBS * cbs,uint8_t * out)105 int CBS_get_u8(CBS *cbs, uint8_t *out) {
106   const uint8_t *v;
107   if (!cbs_get(cbs, &v, 1)) {
108     return 0;
109   }
110   *out = *v;
111   return 1;
112 }
113 
CBS_get_u16(CBS * cbs,uint16_t * out)114 int CBS_get_u16(CBS *cbs, uint16_t *out) {
115   uint32_t v;
116   if (!cbs_get_u(cbs, &v, 2)) {
117     return 0;
118   }
119   *out = v;
120   return 1;
121 }
122 
CBS_get_u24(CBS * cbs,uint32_t * out)123 int CBS_get_u24(CBS *cbs, uint32_t *out) {
124   return cbs_get_u(cbs, out, 3);
125 }
126 
CBS_get_u32(CBS * cbs,uint32_t * out)127 int CBS_get_u32(CBS *cbs, uint32_t *out) {
128   return cbs_get_u(cbs, out, 4);
129 }
130 
CBS_get_last_u8(CBS * cbs,uint8_t * out)131 int CBS_get_last_u8(CBS *cbs, uint8_t *out) {
132   if (cbs->len == 0) {
133     return 0;
134   }
135   *out = cbs->data[cbs->len - 1];
136   cbs->len--;
137   return 1;
138 }
139 
CBS_get_bytes(CBS * cbs,CBS * out,size_t len)140 int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
141   const uint8_t *v;
142   if (!cbs_get(cbs, &v, len)) {
143     return 0;
144   }
145   CBS_init(out, v, len);
146   return 1;
147 }
148 
CBS_copy_bytes(CBS * cbs,uint8_t * out,size_t len)149 int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) {
150   const uint8_t *v;
151   if (!cbs_get(cbs, &v, len)) {
152     return 0;
153   }
154   OPENSSL_memcpy(out, v, len);
155   return 1;
156 }
157 
cbs_get_length_prefixed(CBS * cbs,CBS * out,size_t len_len)158 static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
159   uint32_t len;
160   if (!cbs_get_u(cbs, &len, len_len)) {
161     return 0;
162   }
163   return CBS_get_bytes(cbs, out, len);
164 }
165 
CBS_get_u8_length_prefixed(CBS * cbs,CBS * out)166 int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) {
167   return cbs_get_length_prefixed(cbs, out, 1);
168 }
169 
CBS_get_u16_length_prefixed(CBS * cbs,CBS * out)170 int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) {
171   return cbs_get_length_prefixed(cbs, out, 2);
172 }
173 
CBS_get_u24_length_prefixed(CBS * cbs,CBS * out)174 int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) {
175   return cbs_get_length_prefixed(cbs, out, 3);
176 }
177 
cbs_get_any_asn1_element(CBS * cbs,CBS * out,unsigned * out_tag,size_t * out_header_len,int ber_ok)178 static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
179                                     size_t *out_header_len, int ber_ok) {
180   uint8_t tag, length_byte;
181   CBS header = *cbs;
182   CBS throwaway;
183 
184   if (out == NULL) {
185     out = &throwaway;
186   }
187 
188   if (!CBS_get_u8(&header, &tag) ||
189       !CBS_get_u8(&header, &length_byte)) {
190     return 0;
191   }
192 
193   /* ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag
194    * number no greater than 30.
195    *
196    * If the number portion is 31 (0x1f, the largest value that fits in the
197    * allotted bits), then the tag is more than one byte long and the
198    * continuation bytes contain the tag number. This parser only supports tag
199    * numbers less than 31 (and thus single-byte tags). */
200   if ((tag & 0x1f) == 0x1f) {
201     return 0;
202   }
203 
204   if (out_tag != NULL) {
205     *out_tag = tag;
206   }
207 
208   size_t len;
209   /* The format for the length encoding is specified in ITU-T X.690 section
210    * 8.1.3. */
211   if ((length_byte & 0x80) == 0) {
212     /* Short form length. */
213     len = ((size_t) length_byte) + 2;
214     if (out_header_len != NULL) {
215       *out_header_len = 2;
216     }
217   } else {
218     /* The high bit indicate that this is the long form, while the next 7 bits
219      * encode the number of subsequent octets used to encode the length (ITU-T
220      * X.690 clause 8.1.3.5.b). */
221     const size_t num_bytes = length_byte & 0x7f;
222     uint32_t len32;
223 
224     if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
225       /* indefinite length */
226       if (out_header_len != NULL) {
227         *out_header_len = 2;
228       }
229       return CBS_get_bytes(cbs, out, 2);
230     }
231 
232     /* ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be
233      * used as the first byte of the length. If this parser encounters that
234      * value, num_bytes will be parsed as 127, which will fail the check below.
235      */
236     if (num_bytes == 0 || num_bytes > 4) {
237       return 0;
238     }
239     if (!cbs_get_u(&header, &len32, num_bytes)) {
240       return 0;
241     }
242     /* ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
243      * with the minimum number of octets. */
244     if (len32 < 128) {
245       /* Length should have used short-form encoding. */
246       return 0;
247     }
248     if ((len32 >> ((num_bytes-1)*8)) == 0) {
249       /* Length should have been at least one byte shorter. */
250       return 0;
251     }
252     len = len32;
253     if (len + 2 + num_bytes < len) {
254       /* Overflow. */
255       return 0;
256     }
257     len += 2 + num_bytes;
258     if (out_header_len != NULL) {
259       *out_header_len = 2 + num_bytes;
260     }
261   }
262 
263   return CBS_get_bytes(cbs, out, len);
264 }
265 
CBS_get_any_asn1(CBS * cbs,CBS * out,unsigned * out_tag)266 int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) {
267   size_t header_len;
268   if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) {
269     return 0;
270   }
271 
272   if (!CBS_skip(out, header_len)) {
273     assert(0);
274     return 0;
275   }
276 
277   return 1;
278 }
279 
CBS_get_any_asn1_element(CBS * cbs,CBS * out,unsigned * out_tag,size_t * out_header_len)280 int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
281                                     size_t *out_header_len) {
282   return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len,
283                                   0 /* DER only */);
284 }
285 
CBS_get_any_ber_asn1_element(CBS * cbs,CBS * out,unsigned * out_tag,size_t * out_header_len)286 int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
287                                  size_t *out_header_len) {
288   return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len,
289                                   1 /* BER allowed */);
290 }
291 
cbs_get_asn1(CBS * cbs,CBS * out,unsigned tag_value,int skip_header)292 static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value,
293                         int skip_header) {
294   size_t header_len;
295   unsigned tag;
296   CBS throwaway;
297 
298   if (out == NULL) {
299     out = &throwaway;
300   }
301 
302   if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
303       tag != tag_value) {
304     return 0;
305   }
306 
307   if (skip_header && !CBS_skip(out, header_len)) {
308     assert(0);
309     return 0;
310   }
311 
312   return 1;
313 }
314 
CBS_get_asn1(CBS * cbs,CBS * out,unsigned tag_value)315 int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) {
316   return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
317 }
318 
CBS_get_asn1_element(CBS * cbs,CBS * out,unsigned tag_value)319 int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) {
320   return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
321 }
322 
CBS_peek_asn1_tag(const CBS * cbs,unsigned tag_value)323 int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) {
324   if (CBS_len(cbs) < 1) {
325     return 0;
326   }
327   return CBS_data(cbs)[0] == tag_value;
328 }
329 
CBS_get_asn1_uint64(CBS * cbs,uint64_t * out)330 int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
331   CBS bytes;
332   const uint8_t *data;
333   size_t i, len;
334 
335   if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) {
336     return 0;
337   }
338 
339   *out = 0;
340   data = CBS_data(&bytes);
341   len = CBS_len(&bytes);
342 
343   if (len == 0) {
344     /* An INTEGER is encoded with at least one octet. */
345     return 0;
346   }
347 
348   if ((data[0] & 0x80) != 0) {
349     /* Negative number. */
350     return 0;
351   }
352 
353   if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0) {
354     /* Extra leading zeros. */
355     return 0;
356   }
357 
358   for (i = 0; i < len; i++) {
359     if ((*out >> 56) != 0) {
360       /* Too large to represent as a uint64_t. */
361       return 0;
362     }
363     *out <<= 8;
364     *out |= data[i];
365   }
366 
367   return 1;
368 }
369 
CBS_get_optional_asn1(CBS * cbs,CBS * out,int * out_present,unsigned tag)370 int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
371   int present = 0;
372 
373   if (CBS_peek_asn1_tag(cbs, tag)) {
374     if (!CBS_get_asn1(cbs, out, tag)) {
375       return 0;
376     }
377     present = 1;
378   }
379 
380   if (out_present != NULL) {
381     *out_present = present;
382   }
383 
384   return 1;
385 }
386 
CBS_get_optional_asn1_octet_string(CBS * cbs,CBS * out,int * out_present,unsigned tag)387 int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
388                                        unsigned tag) {
389   CBS child;
390   int present;
391   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
392     return 0;
393   }
394   if (present) {
395     if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
396         CBS_len(&child) != 0) {
397       return 0;
398     }
399   } else {
400     CBS_init(out, NULL, 0);
401   }
402   if (out_present) {
403     *out_present = present;
404   }
405   return 1;
406 }
407 
CBS_get_optional_asn1_uint64(CBS * cbs,uint64_t * out,unsigned tag,uint64_t default_value)408 int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
409                                  uint64_t default_value) {
410   CBS child;
411   int present;
412   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
413     return 0;
414   }
415   if (present) {
416     if (!CBS_get_asn1_uint64(&child, out) ||
417         CBS_len(&child) != 0) {
418       return 0;
419     }
420   } else {
421     *out = default_value;
422   }
423   return 1;
424 }
425 
CBS_get_optional_asn1_bool(CBS * cbs,int * out,unsigned tag,int default_value)426 int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
427                                int default_value) {
428   CBS child, child2;
429   int present;
430   if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) {
431     return 0;
432   }
433   if (present) {
434     uint8_t boolean;
435 
436     if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
437         CBS_len(&child2) != 1 ||
438         CBS_len(&child) != 0) {
439       return 0;
440     }
441 
442     boolean = CBS_data(&child2)[0];
443     if (boolean == 0) {
444       *out = 0;
445     } else if (boolean == 0xff) {
446       *out = 1;
447     } else {
448       return 0;
449     }
450   } else {
451     *out = default_value;
452   }
453   return 1;
454 }
455 
CBS_is_valid_asn1_bitstring(const CBS * cbs)456 int CBS_is_valid_asn1_bitstring(const CBS *cbs) {
457   CBS in = *cbs;
458   uint8_t num_unused_bits;
459   if (!CBS_get_u8(&in, &num_unused_bits) ||
460       num_unused_bits > 7) {
461     return 0;
462   }
463 
464   if (num_unused_bits == 0) {
465     return 1;
466   }
467 
468   /* All num_unused_bits bits must exist and be zeros. */
469   uint8_t last;
470   if (!CBS_get_last_u8(&in, &last) ||
471       (last & ((1 << num_unused_bits) - 1)) != 0) {
472     return 0;
473   }
474 
475   return 1;
476 }
477 
CBS_asn1_bitstring_has_bit(const CBS * cbs,unsigned bit)478 int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) {
479   if (!CBS_is_valid_asn1_bitstring(cbs)) {
480     return 0;
481   }
482 
483   const unsigned byte_num = (bit >> 3) + 1;
484   const unsigned bit_num = 7 - (bit & 7);
485 
486   /* Unused bits are zero, and this function does not distinguish between
487    * missing and unset bits. Thus it is sufficient to do a byte-level length
488    * check. */
489   return byte_num < CBS_len(cbs) &&
490          (CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0;
491 }
492