summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libssl/bs_ber.c390
-rw-r--r--src/lib/libssl/bs_cbb.c611
-rw-r--r--src/lib/libssl/bs_cbs.c663
-rw-r--r--src/lib/libssl/bytestring.h340
-rw-r--r--src/lib/libssl/src/ssl/bs_ber.c390
-rw-r--r--src/lib/libssl/src/ssl/bs_cbb.c611
-rw-r--r--src/lib/libssl/src/ssl/bs_cbs.c663
-rw-r--r--src/lib/libssl/src/ssl/bytestring.h340
8 files changed, 2192 insertions, 1816 deletions
diff --git a/src/lib/libssl/bs_ber.c b/src/lib/libssl/bs_ber.c
index b94b63e37e..cfc9475f9a 100644
--- a/src/lib/libssl/bs_ber.c
+++ b/src/lib/libssl/bs_ber.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bs_ber.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */ 1/* $OpenBSD: bs_ber.c,v 1.2 2015/02/06 22:22:33 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -20,201 +20,233 @@
20 20
21#include "bytestring.h" 21#include "bytestring.h"
22 22
23/* kMaxDepth is a just a sanity limit. The code should be such that the length 23/*
24 * kMaxDepth is a just a sanity limit. The code should be such that the length
24 * of the input being processes always decreases. None the less, a very large 25 * of the input being processes always decreases. None the less, a very large
25 * input could otherwise cause the stack to overflow. */ 26 * input could otherwise cause the stack to overflow.
27 */
26static const unsigned kMaxDepth = 2048; 28static const unsigned kMaxDepth = 2048;
27 29
28/* cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found| 30/*
31 * cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found|
29 * depending on whether an indefinite length element was found. The value of 32 * depending on whether an indefinite length element was found. The value of
30 * |in| is not changed. It returns one on success (i.e. |*ber_found| was set) 33 * |in| is not changed. It returns one on success (i.e. |*ber_found| was set)
31 * and zero on error. */ 34 * and zero on error.
32static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) { 35 */
33 CBS in; 36static int
34 37cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth)
35 if (depth > kMaxDepth) { 38{
36 return 0; 39 CBS in;
37 } 40
38 41 if (depth > kMaxDepth)
39 CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); 42 return 0;
40 *ber_found = 0; 43
41 44 CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in));
42 while (CBS_len(&in) > 0) { 45 *ber_found = 0;
43 CBS contents; 46
44 unsigned tag; 47 while (CBS_len(&in) > 0) {
45 size_t header_len; 48 CBS contents;
46 49 unsigned tag;
47 if (!CBS_get_any_asn1_element(&in, &contents, &tag, &header_len)) { 50 size_t header_len;
48 return 0; 51
49 } 52 if (!CBS_get_any_asn1_element(&in, &contents, &tag,
50 if (CBS_len(&contents) == header_len && 53 &header_len))
51 header_len > 0 && 54 return 0;
52 CBS_data(&contents)[header_len-1] == 0x80) { 55
53 *ber_found = 1; 56 if (CBS_len(&contents) == header_len && header_len > 0 &&
54 return 1; 57 CBS_data(&contents)[header_len-1] == 0x80) {
55 } 58 *ber_found = 1;
56 if (tag & CBS_ASN1_CONSTRUCTED) { 59 return 1;
57 if (!CBS_skip(&contents, header_len) || 60 }
58 !cbs_find_ber(&contents, ber_found, depth + 1)) { 61 if (tag & CBS_ASN1_CONSTRUCTED) {
59 return 0; 62 if (!CBS_skip(&contents, header_len) ||
60 } 63 !cbs_find_ber(&contents, ber_found, depth + 1))
61 } 64 return 0;
62 } 65 }
63 66 }
64 return 1; 67
68 return 1;
65} 69}
66 70
67/* is_primitive_type returns true if |tag| likely a primitive type. Normally 71/*
72 * is_primitive_type returns true if |tag| likely a primitive type. Normally
68 * one can just test the "constructed" bit in the tag but, in BER, even 73 * one can just test the "constructed" bit in the tag but, in BER, even
69 * primitive tags can have the constructed bit if they have indefinite 74 * primitive tags can have the constructed bit if they have indefinite
70 * length. */ 75 * length.
71static char is_primitive_type(unsigned tag) { 76 */
72 return (tag & 0xc0) == 0 && 77static char
73 (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) && 78is_primitive_type(unsigned tag)
74 (tag & 0x1f) != (CBS_ASN1_SET & 0x1f); 79{
80 return (tag & 0xc0) == 0 &&
81 (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) &&
82 (tag & 0x1f) != (CBS_ASN1_SET & 0x1f);
75} 83}
76 84
77/* is_eoc returns true if |header_len| and |contents|, as returned by 85/*
78 * |CBS_get_any_asn1_element|, indicate an "end of contents" (EOC) value. */ 86 * is_eoc returns true if |header_len| and |contents|, as returned by
79static char is_eoc(size_t header_len, CBS *contents) { 87 * |CBS_get_any_asn1_element|, indicate an "end of contents" (EOC) value.
80 return header_len == 2 && CBS_len(contents) == 2 && 88 */
81 memcmp(CBS_data(contents), "\x00\x00", 2) == 0; 89static char
90is_eoc(size_t header_len, CBS *contents)
91{
92 return header_len == 2 && CBS_len(contents) == 2 &&
93 memcmp(CBS_data(contents), "\x00\x00", 2) == 0;
82} 94}
83 95
84/* cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If 96/*
97 * cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If
85 * |squash_header| is set then the top-level of elements from |in| will not 98 * |squash_header| is set then the top-level of elements from |in| will not
86 * have their headers written. This is used when concatenating the fragments of 99 * have their headers written. This is used when concatenating the fragments of
87 * an indefinite length, primitive value. If |looking_for_eoc| is set then any 100 * an indefinite length, primitive value. If |looking_for_eoc| is set then any
88 * EOC elements found will cause the function to return after consuming it. 101 * EOC elements found will cause the function to return after consuming it.
89 * It returns one on success and zero on error. */ 102 * It returns one on success and zero on error.
90static int cbs_convert_ber(CBS *in, CBB *out, char squash_header, 103 */
91 char looking_for_eoc, unsigned depth) { 104static int
92 if (depth > kMaxDepth) { 105cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc,
93 return 0; 106 unsigned depth)
94 } 107{
95 108 if (depth > kMaxDepth)
96 while (CBS_len(in) > 0) { 109 return 0;
97 CBS contents; 110
98 unsigned tag; 111 while (CBS_len(in) > 0) {
99 size_t header_len; 112 CBS contents;
100 CBB *out_contents, out_contents_storage; 113 unsigned tag;
101 114 size_t header_len;
102 if (!CBS_get_any_asn1_element(in, &contents, &tag, &header_len)) { 115 CBB *out_contents, out_contents_storage;
103 return 0; 116
104 } 117 if (!CBS_get_any_asn1_element(in, &contents, &tag, &header_len))
105 out_contents = out; 118 return 0;
106 119
107 if (CBS_len(&contents) == header_len) { 120 out_contents = out;
108 if (is_eoc(header_len, &contents)) { 121
109 return looking_for_eoc; 122 if (CBS_len(&contents) == header_len) {
110 } 123 if (is_eoc(header_len, &contents))
111 124 return looking_for_eoc;
112 if (header_len > 0 && CBS_data(&contents)[header_len - 1] == 0x80) { 125
113 /* This is an indefinite length element. If it's a SEQUENCE or SET then 126 if (header_len > 0 &&
114 * we just need to write the out the contents as normal, but with a 127 CBS_data(&contents)[header_len - 1] == 0x80) {
115 * concrete length prefix. 128 /*
116 * 129 * This is an indefinite length element. If
117 * If it's a something else then the contents will be a series of BER 130 * it's a SEQUENCE or SET then we just need to
118 * elements of the same type which need to be concatenated. */ 131 * write the out the contents as normal, but
119 const char context_specific = (tag & 0xc0) == 0x80; 132 * with a concrete length prefix.
120 char squash_child_headers = is_primitive_type(tag); 133 *
121 134 * If it's a something else then the contents
122 /* This is a hack, but it sufficies to handle NSS's output. If we find 135 * will be a series of BER elements of the same
123 * an indefinite length, context-specific tag with a definite, primtive 136 * type which need to be concatenated.
124 * tag inside it, then we assume that the context-specific tag is 137 */
125 * implicit and the tags within are fragments of a primitive type that 138 const char context_specific = (tag & 0xc0)
126 * need to be concatenated. */ 139 == 0x80;
127 if (context_specific && (tag & CBS_ASN1_CONSTRUCTED)) { 140 char squash_child_headers =
128 CBS in_copy, inner_contents; 141 is_primitive_type(tag);
129 unsigned inner_tag; 142
130 size_t inner_header_len; 143 /*
131 144 * This is a hack, but it sufficies to handle
132 CBS_init(&in_copy, CBS_data(in), CBS_len(in)); 145 * NSS's output. If we find an indefinite
133 if (!CBS_get_any_asn1_element(&in_copy, &inner_contents, &inner_tag, 146 * length, context-specific tag with a definite,
134 &inner_header_len)) { 147 * primtive tag inside it, then we assume that
135 return 0; 148 * the context-specific tag is implicit and the
136 } 149 * tags within are fragments of a primitive type
137 if (CBS_len(&inner_contents) > inner_header_len && 150 * that need to be concatenated.
138 is_primitive_type(inner_tag)) { 151 */
139 squash_child_headers = 1; 152 if (context_specific &&
140 } 153 (tag & CBS_ASN1_CONSTRUCTED)) {
141 } 154 CBS in_copy, inner_contents;
142 155 unsigned inner_tag;
143 if (!squash_header) { 156 size_t inner_header_len;
144 unsigned out_tag = tag; 157
145 if (squash_child_headers) { 158 CBS_init(&in_copy, CBS_data(in),
146 out_tag &= ~CBS_ASN1_CONSTRUCTED; 159 CBS_len(in));
147 } 160 if (!CBS_get_any_asn1_element(&in_copy,
148 if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) { 161 &inner_contents, &inner_tag,
149 return 0; 162 &inner_header_len))
150 } 163 return 0;
151 out_contents = &out_contents_storage; 164
152 } 165 if (CBS_len(&inner_contents) >
153 166 inner_header_len &&
154 if (!cbs_convert_ber(in, out_contents, 167 is_primitive_type(inner_tag))
155 squash_child_headers, 168 squash_child_headers = 1;
156 1 /* looking for eoc */, depth + 1)) { 169 }
157 return 0; 170
158 } 171 if (!squash_header) {
159 if (out_contents != out && !CBB_flush(out)) { 172 unsigned out_tag = tag;
160 return 0; 173
161 } 174 if (squash_child_headers)
162 continue; 175 out_tag &=
163 } 176 ~CBS_ASN1_CONSTRUCTED;
164 } 177
165 178 if (!CBB_add_asn1(out,
166 if (!squash_header) { 179 &out_contents_storage, out_tag))
167 if (!CBB_add_asn1(out, &out_contents_storage, tag)) { 180 return 0;
168 return 0; 181
169 } 182 out_contents = &out_contents_storage;
170 out_contents = &out_contents_storage; 183 }
171 } 184
172 185 if (!cbs_convert_ber(in, out_contents,
173 if (!CBS_skip(&contents, header_len)) { 186 squash_child_headers,
174 return 0; 187 1 /* looking for eoc */, depth + 1))
175 } 188 return 0;
176 189
177 if (tag & CBS_ASN1_CONSTRUCTED) { 190 if (out_contents != out && !CBB_flush(out))
178 if (!cbs_convert_ber(&contents, out_contents, 0 /* don't squash header */, 191 return 0;
179 0 /* not looking for eoc */, depth + 1)) { 192
180 return 0; 193 continue;
181 } 194 }
182 } else { 195 }
183 if (!CBB_add_bytes(out_contents, CBS_data(&contents), 196
184 CBS_len(&contents))) { 197 if (!squash_header) {
185 return 0; 198 if (!CBB_add_asn1(out, &out_contents_storage, tag))
186 } 199 return 0;
187 } 200
188 201 out_contents = &out_contents_storage;
189 if (out_contents != out && !CBB_flush(out)) { 202 }
190 return 0; 203
191 } 204 if (!CBS_skip(&contents, header_len))
192 } 205 return 0;
193 206
194 return looking_for_eoc == 0; 207 if (tag & CBS_ASN1_CONSTRUCTED) {
208 if (!cbs_convert_ber(&contents, out_contents,
209 0 /* don't squash header */,
210 0 /* not looking for eoc */, depth + 1))
211 return 0;
212 } else {
213 if (!CBB_add_bytes(out_contents, CBS_data(&contents),
214 CBS_len(&contents)))
215 return 0;
216 }
217
218 if (out_contents != out && !CBB_flush(out))
219 return 0;
220 }
221
222 return looking_for_eoc == 0;
195} 223}
196 224
197int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) { 225int
198 CBB cbb; 226CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len)
199 227{
200 /* First, do a quick walk to find any indefinite-length elements. Most of the 228 CBB cbb;
201 * time we hope that there aren't any and thus we can quickly return. */ 229
202 char conversion_needed; 230 /*
203 if (!cbs_find_ber(in, &conversion_needed, 0)) { 231 * First, do a quick walk to find any indefinite-length elements. Most
204 return 0; 232 * of the time we hope that there aren't any and thus we can quickly
205 } 233 * return.
206 234 */
207 if (!conversion_needed) { 235 char conversion_needed;
208 *out = NULL; 236 if (!cbs_find_ber(in, &conversion_needed, 0))
209 *out_len = 0; 237 return 0;
210 return 1; 238
211 } 239 if (!conversion_needed) {
212 240 *out = NULL;
213 CBB_init(&cbb, CBS_len(in)); 241 *out_len = 0;
214 if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) { 242 return 1;
215 CBB_cleanup(&cbb); 243 }
216 return 0; 244
217 } 245 CBB_init(&cbb, CBS_len(in));
218 246 if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) {
219 return CBB_finish(&cbb, out, out_len); 247 CBB_cleanup(&cbb);
248 return 0;
249 }
250
251 return CBB_finish(&cbb, out, out_len);
220} 252}
diff --git a/src/lib/libssl/bs_cbb.c b/src/lib/libssl/bs_cbb.c
index 11688bcb7b..94ca54f43b 100644
--- a/src/lib/libssl/bs_cbb.c
+++ b/src/lib/libssl/bs_cbb.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bs_cbb.c,v 1.2 2015/02/06 10:06:30 doug Exp $ */ 1/* $OpenBSD: bs_cbb.c,v 1.3 2015/02/06 22:22:33 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -22,356 +22,365 @@
22 22
23#include "bytestring.h" 23#include "bytestring.h"
24 24
25static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) { 25static int
26 struct cbb_buffer_st *base; 26cbb_init(CBB *cbb, uint8_t *buf, size_t cap)
27{
28 struct cbb_buffer_st *base;
29
30 base = malloc(sizeof(struct cbb_buffer_st));
31 if (base == NULL) {
32 free(buf);
33 return 0;
34 }
35
36 base->buf = buf;
37 base->len = 0;
38 base->cap = cap;
39 base->can_resize = 1;
40
41 memset(cbb, 0, sizeof(CBB));
42 cbb->base = base;
43 cbb->is_top_level = 1;
44 return 1;
45}
27 46
28 base = malloc(sizeof(struct cbb_buffer_st)); 47int
29 if (base == NULL) { 48CBB_init(CBB *cbb, size_t initial_capacity)
30 free(buf); 49{
31 return 0; 50 uint8_t *buf;
32 }
33 51
34 base->buf = buf; 52 buf = malloc(initial_capacity);
35 base->len = 0; 53 if (initial_capacity > 0 && buf == NULL)
36 base->cap = cap; 54 return 0;
37 base->can_resize = 1;
38 55
39 memset(cbb, 0, sizeof(CBB)); 56 return cbb_init(cbb, buf, initial_capacity);
40 cbb->base = base;
41 cbb->is_top_level = 1;
42 return 1;
43} 57}
44 58
45int CBB_init(CBB *cbb, size_t initial_capacity) { 59int
46 uint8_t *buf; 60CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len)
47 61{
48 buf = malloc(initial_capacity); 62 if (!cbb_init(cbb, buf, len))
49 if (initial_capacity > 0 && buf == NULL) { 63 return 0;
50 return 0;
51 }
52 64
53 return cbb_init(cbb, buf, initial_capacity); 65 cbb->base->can_resize = 0;
66 return 1;
54} 67}
55 68
56int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) { 69void
57 if (!cbb_init(cbb, buf, len)) { 70CBB_cleanup(CBB *cbb)
58 return 0; 71{
59 } 72 if (cbb->base) {
73 if (cbb->base->buf && cbb->base->can_resize)
74 free(cbb->base->buf);
60 75
61 cbb->base->can_resize = 0; 76 free(cbb->base);
62 return 1; 77 }
78 cbb->base = NULL;
63} 79}
64 80
65void CBB_cleanup(CBB *cbb) { 81static int
66 if (cbb->base) { 82cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len)
67 if (cbb->base->buf && cbb->base->can_resize) { 83{
68 free(cbb->base->buf); 84 size_t newlen;
69 } 85
70 free(cbb->base); 86 if (base == NULL)
71 } 87 return 0;
72 cbb->base = NULL; 88
73} 89 newlen = base->len + len;
90 if (newlen < base->len)
91 /* Overflow */
92 return 0;
93
94 if (newlen > base->cap) {
95 size_t newcap = base->cap * 2;
96 uint8_t *newbuf;
97
98 if (!base->can_resize)
99 return 0;
100
101 if (newcap < base->cap || newcap < newlen)
102 newcap = newlen;
103
104 newbuf = realloc(base->buf, newcap);
105 if (newbuf == NULL)
106 return 0;
107
108 base->buf = newbuf;
109 base->cap = newcap;
110 }
111
112 if (out)
113 *out = base->buf + base->len;
74 114
75static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, 115 base->len = newlen;
76 size_t len) { 116 return 1;
77 size_t newlen;
78
79 if (base == NULL) {
80 return 0;
81 }
82
83 newlen = base->len + len;
84 if (newlen < base->len) {
85 /* Overflow */
86 return 0;
87 }
88
89 if (newlen > base->cap) {
90 size_t newcap = base->cap * 2;
91 uint8_t *newbuf;
92
93 if (!base->can_resize) {
94 return 0;
95 }
96
97 if (newcap < base->cap || newcap < newlen) {
98 newcap = newlen;
99 }
100 newbuf = realloc(base->buf, newcap);
101 if (newbuf == NULL) {
102 return 0;
103 }
104
105 base->buf = newbuf;
106 base->cap = newcap;
107 }
108
109 if (out) {
110 *out = base->buf + base->len;
111 }
112 base->len = newlen;
113 return 1;
114} 117}
115 118
116static int cbb_buffer_add_u(struct cbb_buffer_st *base, uint32_t v, 119static int
117 size_t len_len) { 120cbb_buffer_add_u(struct cbb_buffer_st *base, uint32_t v, size_t len_len)
118 uint8_t *buf; 121{
119 size_t i; 122 uint8_t *buf;
120 123 size_t i;
121 if (len_len == 0) { 124
122 return 1; 125 if (len_len == 0)
123 } 126 return 1;
124 if (!cbb_buffer_add(base, &buf, len_len)) { 127
125 return 0; 128 if (!cbb_buffer_add(base, &buf, len_len))
126 } 129 return 0;
127 130
128 for (i = len_len - 1; i < len_len; i--) { 131 for (i = len_len - 1; i < len_len; i--) {
129 buf[i] = v; 132 buf[i] = v;
130 v >>= 8; 133 v >>= 8;
131 } 134 }
132 return 1; 135 return 1;
133} 136}
134 137
135int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) { 138int
136 if (!cbb->is_top_level) { 139CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len)
137 return 0; 140{
138 } 141 if (!cbb->is_top_level)
139 142 return 0;
140 if (!CBB_flush(cbb)) { 143
141 return 0; 144 if (!CBB_flush(cbb))
142 } 145 return 0;
143 146
144 if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) { 147 if (cbb->base->can_resize && (out_data == NULL || out_len == NULL))
145 /* |out_data| and |out_len| can only be NULL if the CBB is fixed. */ 148 /* |out_data| and |out_len| can only be NULL if the CBB is fixed. */
146 return 0; 149 return 0;
147 } 150
148 151 if (out_data != NULL)
149 if (out_data != NULL) { 152 *out_data = cbb->base->buf;
150 *out_data = cbb->base->buf; 153
151 } 154 if (out_len != NULL)
152 if (out_len != NULL) { 155 *out_len = cbb->base->len;
153 *out_len = cbb->base->len; 156
154 } 157 cbb->base->buf = NULL;
155 cbb->base->buf = NULL; 158 CBB_cleanup(cbb);
156 CBB_cleanup(cbb); 159 return 1;
157 return 1;
158} 160}
159 161
160/* CBB_flush recurses and then writes out any pending length prefix. The 162/*
161 * current length of the underlying base is taken to be the length of the 163 * CBB_flush recurses and then writes out any pending length prefix. The current
162 * length-prefixed data. */ 164 * length of the underlying base is taken to be the length of the
163int CBB_flush(CBB *cbb) { 165 * length-prefixed data.
164 size_t child_start, i, len; 166 */
165 167int
166 if (cbb->base == NULL) { 168CBB_flush(CBB *cbb)
167 return 0; 169{
168 } 170 size_t child_start, i, len;
169 171
170 if (cbb->child == NULL || cbb->pending_len_len == 0) { 172 if (cbb->base == NULL)
171 return 1; 173 return 0;
172 } 174
173 175 if (cbb->child == NULL || cbb->pending_len_len == 0)
174 child_start = cbb->offset + cbb->pending_len_len; 176 return 1;
175 177
176 if (!CBB_flush(cbb->child) || 178 child_start = cbb->offset + cbb->pending_len_len;
177 child_start < cbb->offset || 179
178 cbb->base->len < child_start) { 180 if (!CBB_flush(cbb->child) || child_start < cbb->offset ||
179 return 0; 181 cbb->base->len < child_start)
180 } 182 return 0;
181 183
182 len = cbb->base->len - child_start; 184 len = cbb->base->len - child_start;
183 185
184 if (cbb->pending_is_asn1) { 186 if (cbb->pending_is_asn1) {
185 /* For ASN.1 we assume that we'll only need a single byte for the length. 187 /* For ASN.1 we assume that we'll only need a single byte for the length.
186 * If that turned out to be incorrect, we have to move the contents along 188 * If that turned out to be incorrect, we have to move the contents along
187 * in order to make space. */ 189 * in order to make space. */
188 size_t len_len; 190 size_t len_len;
189 uint8_t initial_length_byte; 191 uint8_t initial_length_byte;
190 192
191 assert (cbb->pending_len_len == 1); 193 assert (cbb->pending_len_len == 1);
192 194
193 if (len > 0xfffffffe) { 195 if (len > 0xfffffffe) {
194 /* Too large. */ 196 /* Too large. */
195 return 0; 197 return 0;
196 } else if (len > 0xffffff) { 198 } else if (len > 0xffffff) {
197 len_len = 5; 199 len_len = 5;
198 initial_length_byte = 0x80 | 4; 200 initial_length_byte = 0x80 | 4;
199 } else if (len > 0xffff) { 201 } else if (len > 0xffff) {
200 len_len = 4; 202 len_len = 4;
201 initial_length_byte = 0x80 | 3; 203 initial_length_byte = 0x80 | 3;
202 } else if (len > 0xff) { 204 } else if (len > 0xff) {
203 len_len = 3; 205 len_len = 3;
204 initial_length_byte = 0x80 | 2; 206 initial_length_byte = 0x80 | 2;
205 } else if (len > 0x7f) { 207 } else if (len > 0x7f) {
206 len_len = 2; 208 len_len = 2;
207 initial_length_byte = 0x80 | 1; 209 initial_length_byte = 0x80 | 1;
208 } else { 210 } else {
209 len_len = 1; 211 len_len = 1;
210 initial_length_byte = len; 212 initial_length_byte = len;
211 len = 0; 213 len = 0;
212 } 214 }
213 215
214 if (len_len != 1) { 216 if (len_len != 1) {
215 /* We need to move the contents along in order to make space. */ 217 /* We need to move the contents along in order to make space. */
216 size_t extra_bytes = len_len - 1; 218 size_t extra_bytes = len_len - 1;
217 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) { 219 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes))
218 return 0; 220 return 0;
219 } 221
220 memmove(cbb->base->buf + child_start + extra_bytes, 222 memmove(cbb->base->buf + child_start + extra_bytes,
221 cbb->base->buf + child_start, len); 223 cbb->base->buf + child_start, len);
222 } 224 }
223 cbb->base->buf[cbb->offset++] = initial_length_byte; 225 cbb->base->buf[cbb->offset++] = initial_length_byte;
224 cbb->pending_len_len = len_len - 1; 226 cbb->pending_len_len = len_len - 1;
225 } 227 }
226 228
227 for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) { 229 for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) {
228 cbb->base->buf[cbb->offset + i] = len; 230 cbb->base->buf[cbb->offset + i] = len;
229 len >>= 8; 231 len >>= 8;
230 } 232 }
231 if (len != 0) { 233 if (len != 0)
232 return 0; 234 return 0;
233 } 235
234 236 cbb->child->base = NULL;
235 cbb->child->base = NULL; 237 cbb->child = NULL;
236 cbb->child = NULL; 238 cbb->pending_len_len = 0;
237 cbb->pending_len_len = 0; 239 cbb->pending_is_asn1 = 0;
238 cbb->pending_is_asn1 = 0; 240 cbb->offset = 0;
239 cbb->offset = 0; 241
240 242 return 1;
241 return 1;
242} 243}
243 244
244 245
245static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, 246static int
246 size_t len_len) { 247cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len)
247 uint8_t *prefix_bytes; 248{
249 uint8_t *prefix_bytes;
248 250
249 if (!CBB_flush(cbb)) { 251 if (!CBB_flush(cbb))
250 return 0; 252 return 0;
251 }
252 253
253 cbb->offset = cbb->base->len; 254 cbb->offset = cbb->base->len;
254 if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) { 255 if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len))
255 return 0; 256 return 0;
256 }
257 257
258 memset(prefix_bytes, 0, len_len); 258 memset(prefix_bytes, 0, len_len);
259 memset(out_contents, 0, sizeof(CBB)); 259 memset(out_contents, 0, sizeof(CBB));
260 out_contents->base = cbb->base; 260 out_contents->base = cbb->base;
261 cbb->child = out_contents; 261 cbb->child = out_contents;
262 cbb->pending_len_len = len_len; 262 cbb->pending_len_len = len_len;
263 cbb->pending_is_asn1 = 0; 263 cbb->pending_is_asn1 = 0;
264 264
265 return 1; 265 return 1;
266} 266}
267 267
268int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) { 268int
269 return cbb_add_length_prefixed(cbb, out_contents, 1); 269CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents)
270{
271 return cbb_add_length_prefixed(cbb, out_contents, 1);
270} 272}
271 273
272int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) { 274int
273 return cbb_add_length_prefixed(cbb, out_contents, 2); 275CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents)
276{
277 return cbb_add_length_prefixed(cbb, out_contents, 2);
274} 278}
275 279
276int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) { 280int
277 return cbb_add_length_prefixed(cbb, out_contents, 3); 281CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents)
282{
283 return cbb_add_length_prefixed(cbb, out_contents, 3);
278} 284}
279 285
280int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) { 286int
281 if (!CBB_flush(cbb) || 287CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag)
282 !CBB_add_u8(cbb, tag)) { 288{
283 return 0; 289 if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag))
284 } 290 return 0;
285 291
286 cbb->offset = cbb->base->len; 292 cbb->offset = cbb->base->len;
287 if (!CBB_add_u8(cbb, 0)) { 293 if (!CBB_add_u8(cbb, 0))
288 return 0; 294 return 0;
289 }
290 295
291 memset(out_contents, 0, sizeof(CBB)); 296 memset(out_contents, 0, sizeof(CBB));
292 out_contents->base = cbb->base; 297 out_contents->base = cbb->base;
293 cbb->child = out_contents; 298 cbb->child = out_contents;
294 cbb->pending_len_len = 1; 299 cbb->pending_len_len = 1;
295 cbb->pending_is_asn1 = 1; 300 cbb->pending_is_asn1 = 1;
296 301
297 return 1; 302 return 1;
298} 303}
299 304
300int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) { 305int
301 uint8_t *dest; 306CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len)
307{
308 uint8_t *dest;
302 309
303 if (!CBB_flush(cbb) || 310 if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &dest, len))
304 !cbb_buffer_add(cbb->base, &dest, len)) { 311 return 0;
305 return 0; 312
306 } 313 memcpy(dest, data, len);
307 memcpy(dest, data, len); 314 return 1;
308 return 1;
309} 315}
310 316
311int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { 317int
312 if (!CBB_flush(cbb) || 318CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len)
313 !cbb_buffer_add(cbb->base, out_data, len)) { 319{
314 return 0; 320 if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len))
315 } 321 return 0;
316 return 1; 322
323 return 1;
317} 324}
318 325
319int CBB_add_u8(CBB *cbb, uint8_t value) { 326int
320 if (!CBB_flush(cbb)) { 327CBB_add_u8(CBB *cbb, uint8_t value)
321 return 0; 328{
322 } 329 if (!CBB_flush(cbb))
330 return 0;
323 331
324 return cbb_buffer_add_u(cbb->base, value, 1); 332 return cbb_buffer_add_u(cbb->base, value, 1);
325} 333}
326 334
327int CBB_add_u16(CBB *cbb, uint16_t value) { 335int
328 if (!CBB_flush(cbb)) { 336CBB_add_u16(CBB *cbb, uint16_t value)
329 return 0; 337{
330 } 338 if (!CBB_flush(cbb))
339 return 0;
331 340
332 return cbb_buffer_add_u(cbb->base, value, 2); 341 return cbb_buffer_add_u(cbb->base, value, 2);
333} 342}
334 343
335int CBB_add_u24(CBB *cbb, uint32_t value) { 344int
336 if (!CBB_flush(cbb)) { 345CBB_add_u24(CBB *cbb, uint32_t value)
337 return 0; 346{
338 } 347 if (!CBB_flush(cbb))
348 return 0;
339 349
340 return cbb_buffer_add_u(cbb->base, value, 3); 350 return cbb_buffer_add_u(cbb->base, value, 3);
341} 351}
342 352
343int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { 353int
344 CBB child; 354CBB_add_asn1_uint64(CBB *cbb, uint64_t value)
345 size_t i; 355{
346 int started = 0; 356 CBB child;
347 357 size_t i;
348 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { 358 int started = 0;
349 return 0; 359
350 } 360 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER))
351 361 return 0;
352 for (i = 0; i < 8; i++) { 362
353 uint8_t byte = (value >> 8*(7-i)) & 0xff; 363 for (i = 0; i < 8; i++) {
354 if (!started) { 364 uint8_t byte = (value >> 8*(7-i)) & 0xff;
355 if (byte == 0) { 365 if (!started) {
356 /* Don't encode leading zeros. */ 366 if (byte == 0)
357 continue; 367 /* Don't encode leading zeros. */
358 } 368 continue;
359 /* If the high bit is set, add a padding byte to make it 369
360 * unsigned. */ 370 /* If the high bit is set, add a padding byte to make it
361 if ((byte & 0x80) && !CBB_add_u8(&child, 0)) { 371 * unsigned. */
362 return 0; 372 if ((byte & 0x80) && !CBB_add_u8(&child, 0))
363 } 373 return 0;
364 started = 1; 374
365 } 375 started = 1;
366 if (!CBB_add_u8(&child, byte)) { 376 }
367 return 0; 377 if (!CBB_add_u8(&child, byte))
368 } 378 return 0;
369 } 379 }
370 380
371 /* 0 is encoded as a single 0, not the empty string. */ 381 /* 0 is encoded as a single 0, not the empty string. */
372 if (!started && !CBB_add_u8(&child, 0)) { 382 if (!started && !CBB_add_u8(&child, 0))
373 return 0; 383 return 0;
374 } 384
375 385 return CBB_flush(cbb);
376 return CBB_flush(cbb);
377} 386}
diff --git a/src/lib/libssl/bs_cbs.c b/src/lib/libssl/bs_cbs.c
index 7edfe65288..c3d3a8abf2 100644
--- a/src/lib/libssl/bs_cbs.c
+++ b/src/lib/libssl/bs_cbs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bs_cbs.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */ 1/* $OpenBSD: bs_cbs.c,v 1.2 2015/02/06 22:22:33 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -24,367 +24,416 @@
24 24
25#include "bytestring.h" 25#include "bytestring.h"
26 26
27void CBS_init(CBS *cbs, const uint8_t *data, size_t len) { 27void
28 cbs->data = data; 28CBS_init(CBS *cbs, const uint8_t *data, size_t len)
29 cbs->len = len; 29{
30 cbs->data = data;
31 cbs->len = len;
30} 32}
31 33
32static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) { 34static int
33 if (cbs->len < n) { 35cbs_get(CBS *cbs, const uint8_t **p, size_t n)
34 return 0; 36{
35 } 37 if (cbs->len < n)
38 return 0;
36 39
37 *p = cbs->data; 40 *p = cbs->data;
38 cbs->data += n; 41 cbs->data += n;
39 cbs->len -= n; 42 cbs->len -= n;
40 return 1; 43 return 1;
41} 44}
42 45
43int CBS_skip(CBS *cbs, size_t len) { 46int
44 const uint8_t *dummy; 47CBS_skip(CBS *cbs, size_t len)
45 return cbs_get(cbs, &dummy, len); 48{
49 const uint8_t *dummy;
50 return cbs_get(cbs, &dummy, len);
46} 51}
47 52
48const uint8_t *CBS_data(const CBS *cbs) { 53const uint8_t *
49 return cbs->data; 54CBS_data(const CBS *cbs)
55{
56 return cbs->data;
50} 57}
51 58
52size_t CBS_len(const CBS *cbs) { 59size_t
53 return cbs->len; 60CBS_len(const CBS *cbs)
61{
62 return cbs->len;
54} 63}
55 64
56int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) { 65int
57 if (*out_ptr != NULL) { 66CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len)
58 free(*out_ptr); 67{
59 *out_ptr = NULL; 68 if (*out_ptr != NULL) {
60 } 69 free(*out_ptr);
61 *out_len = 0; 70 *out_ptr = NULL;
62 71 }
63 if (cbs->len == 0) { 72 *out_len = 0;
64 return 1; 73
65 } 74 if (cbs->len == 0)
66 *out_ptr = BUF_memdup(cbs->data, cbs->len); 75 return 1;
67 if (*out_ptr == NULL) { 76
68 return 0; 77 *out_ptr = BUF_memdup(cbs->data, cbs->len);
69 } 78 if (*out_ptr == NULL)
70 *out_len = cbs->len; 79 return 0;
71 return 1; 80
81 *out_len = cbs->len;
82 return 1;
72} 83}
73 84
74int CBS_strdup(const CBS *cbs, char **out_ptr) { 85int
75 if (*out_ptr != NULL) { 86CBS_strdup(const CBS *cbs, char **out_ptr)
76 free(*out_ptr); 87{
77 } 88 if (*out_ptr != NULL)
78 *out_ptr = strndup((const char*)cbs->data, cbs->len); 89 free(*out_ptr);
79 return (*out_ptr != NULL); 90
91 *out_ptr = strndup((const char*)cbs->data, cbs->len);
92 return (*out_ptr != NULL);
80} 93}
81 94
82int CBS_contains_zero_byte(const CBS *cbs) { 95int
83 return memchr(cbs->data, 0, cbs->len) != NULL; 96CBS_contains_zero_byte(const CBS *cbs)
97{
98 return memchr(cbs->data, 0, cbs->len) != NULL;
84} 99}
85 100
86int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) { 101int
87 if (len != cbs->len) 102CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len)
88 return 0; 103{
89 return CRYPTO_memcmp(cbs->data, data, len) == 0; 104 if (len != cbs->len)
105 return 0;
106
107 return CRYPTO_memcmp(cbs->data, data, len) == 0;
90} 108}
91 109
92static int cbs_get_u(CBS *cbs, uint32_t *out, size_t len) { 110static int
93 uint32_t result = 0; 111cbs_get_u(CBS *cbs, uint32_t *out, size_t len)
94 size_t i; 112{
95 const uint8_t *data; 113 uint32_t result = 0;
96 114 size_t i;
97 if (!cbs_get(cbs, &data, len)) { 115 const uint8_t *data;
98 return 0; 116
99 } 117 if (!cbs_get(cbs, &data, len))
100 for (i = 0; i < len; i++) { 118 return 0;
101 result <<= 8; 119
102 result |= data[i]; 120 for (i = 0; i < len; i++) {
103 } 121 result <<= 8;
104 *out = result; 122 result |= data[i];
105 return 1; 123 }
124 *out = result;
125 return 1;
106} 126}
107 127
108int CBS_get_u8(CBS *cbs, uint8_t *out) { 128int
109 const uint8_t *v; 129CBS_get_u8(CBS *cbs, uint8_t *out)
110 if (!cbs_get(cbs, &v, 1)) { 130{
111 return 0; 131 const uint8_t *v;
112 } 132
113 *out = *v; 133 if (!cbs_get(cbs, &v, 1))
114 return 1; 134 return 0;
135
136 *out = *v;
137 return 1;
115} 138}
116 139
117int CBS_get_u16(CBS *cbs, uint16_t *out) { 140int
118 uint32_t v; 141CBS_get_u16(CBS *cbs, uint16_t *out)
119 if (!cbs_get_u(cbs, &v, 2)) { 142{
120 return 0; 143 uint32_t v;
121 } 144
122 *out = v; 145 if (!cbs_get_u(cbs, &v, 2))
123 return 1; 146 return 0;
147
148 *out = v;
149 return 1;
124} 150}
125 151
126int CBS_get_u24(CBS *cbs, uint32_t *out) { 152int
127 return cbs_get_u(cbs, out, 3); 153CBS_get_u24(CBS *cbs, uint32_t *out)
154{
155 return cbs_get_u(cbs, out, 3);
128} 156}
129 157
130int CBS_get_u32(CBS *cbs, uint32_t *out) { 158int
131 return cbs_get_u(cbs, out, 4); 159CBS_get_u32(CBS *cbs, uint32_t *out)
160{
161 return cbs_get_u(cbs, out, 4);
132} 162}
133 163
134int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) { 164int
135 const uint8_t *v; 165CBS_get_bytes(CBS *cbs, CBS *out, size_t len)
136 if (!cbs_get(cbs, &v, len)) { 166{
137 return 0; 167 const uint8_t *v;
138 } 168
139 CBS_init(out, v, len); 169 if (!cbs_get(cbs, &v, len))
140 return 1; 170 return 0;
171
172 CBS_init(out, v, len);
173 return 1;
141} 174}
142 175
143static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) { 176static int
144 uint32_t len; 177cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len)
145 if (!cbs_get_u(cbs, &len, len_len)) { 178{
146 return 0; 179 uint32_t len;
147 } 180
148 return CBS_get_bytes(cbs, out, len); 181 if (!cbs_get_u(cbs, &len, len_len))
182 return 0;
183
184 return CBS_get_bytes(cbs, out, len);
149} 185}
150 186
151int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) { 187int
152 return cbs_get_length_prefixed(cbs, out, 1); 188CBS_get_u8_length_prefixed(CBS *cbs, CBS *out)
189{
190 return cbs_get_length_prefixed(cbs, out, 1);
153} 191}
154 192
155int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) { 193int
156 return cbs_get_length_prefixed(cbs, out, 2); 194CBS_get_u16_length_prefixed(CBS *cbs, CBS *out)
195{
196 return cbs_get_length_prefixed(cbs, out, 2);
157} 197}
158 198
159int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) { 199int
160 return cbs_get_length_prefixed(cbs, out, 3); 200CBS_get_u24_length_prefixed(CBS *cbs, CBS *out)
201{
202 return cbs_get_length_prefixed(cbs, out, 3);
161} 203}
162 204
163int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, 205int
164 size_t *out_header_len) { 206CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
165 uint8_t tag, length_byte; 207 size_t *out_header_len)
166 CBS header = *cbs; 208{
167 CBS throwaway; 209 uint8_t tag, length_byte;
168 210 CBS header = *cbs;
169 if (out == NULL) { 211 CBS throwaway;
170 out = &throwaway; 212
171 } 213 if (out == NULL)
172 214 out = &throwaway;
173 if (!CBS_get_u8(&header, &tag) || 215
174 !CBS_get_u8(&header, &length_byte)) { 216 if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte))
175 return 0; 217 return 0;
176 } 218
177 219 if ((tag & 0x1f) == 0x1f)
178 if ((tag & 0x1f) == 0x1f) { 220 /* Long form tags are not supported. */
179 /* Long form tags are not supported. */ 221 return 0;
180 return 0; 222
181 } 223 if (out_tag != NULL)
182 224 *out_tag = tag;
183 if (out_tag != NULL) { 225
184 *out_tag = tag; 226 size_t len;
185 } 227 if ((length_byte & 0x80) == 0) {
186 228 /* Short form length. */
187 size_t len; 229 len = ((size_t) length_byte) + 2;
188 if ((length_byte & 0x80) == 0) { 230 if (out_header_len != NULL)
189 /* Short form length. */ 231 *out_header_len = 2;
190 len = ((size_t) length_byte) + 2; 232
191 if (out_header_len != NULL) { 233 } else {
192 *out_header_len = 2; 234 /* Long form length. */
193 } 235 const size_t num_bytes = length_byte & 0x7f;
194 } else { 236 uint32_t len32;
195 /* Long form length. */ 237
196 const size_t num_bytes = length_byte & 0x7f; 238 if ((tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
197 uint32_t len32; 239 /* indefinite length */
198 240 *out_header_len = 2;
199 if ((tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) { 241 return CBS_get_bytes(cbs, out, 2);
200 /* indefinite length */ 242 }
201 *out_header_len = 2; 243
202 return CBS_get_bytes(cbs, out, 2); 244 if (num_bytes == 0 || num_bytes > 4)
203 } 245 return 0;
204 246
205 if (num_bytes == 0 || num_bytes > 4) { 247 if (!cbs_get_u(&header, &len32, num_bytes))
206 return 0; 248 return 0;
207 } 249
208 if (!cbs_get_u(&header, &len32, num_bytes)) { 250 if (len32 < 128)
209 return 0; 251 /* Length should have used short-form encoding. */
210 } 252 return 0;
211 if (len32 < 128) { 253
212 /* Length should have used short-form encoding. */ 254 if ((len32 >> ((num_bytes-1)*8)) == 0)
213 return 0; 255 /* Length should have been at least one byte shorter. */
214 } 256 return 0;
215 if ((len32 >> ((num_bytes-1)*8)) == 0) { 257
216 /* Length should have been at least one byte shorter. */ 258 len = len32;
217 return 0; 259 if (len + 2 + num_bytes < len)
218 } 260 /* Overflow. */
219 len = len32; 261 return 0;
220 if (len + 2 + num_bytes < len) { 262
221 /* Overflow. */ 263 len += 2 + num_bytes;
222 return 0; 264 if (out_header_len != NULL)
223 } 265 *out_header_len = 2 + num_bytes;
224 len += 2 + num_bytes; 266 }
225 if (out_header_len != NULL) { 267
226 *out_header_len = 2 + num_bytes; 268 return CBS_get_bytes(cbs, out, len);
227 }
228 }
229
230 return CBS_get_bytes(cbs, out, len);
231} 269}
232 270
233static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, 271static int
234 int skip_header) { 272cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, int skip_header)
235 size_t header_len; 273{
236 unsigned tag; 274 size_t header_len;
237 CBS throwaway; 275 unsigned tag;
238 276 CBS throwaway;
239 if (out == NULL) { 277
240 out = &throwaway; 278 if (out == NULL)
241 } 279 out = &throwaway;
242 280
243 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) || 281 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
244 tag != tag_value || 282 tag != tag_value || (header_len > 0 &&
245 (header_len > 0 && 283 /*
246 /* This ensures that the tag is either zero length or 284 * This ensures that the tag is either zero length or
247 * indefinite-length. */ 285 * indefinite-length.
248 CBS_len(out) == header_len && 286 */
249 CBS_data(out)[header_len - 1] == 0x80)) { 287 CBS_len(out) == header_len &&
250 return 0; 288 CBS_data(out)[header_len - 1] == 0x80))
251 } 289 return 0;
252 290
253 if (skip_header && !CBS_skip(out, header_len)) { 291 if (skip_header && !CBS_skip(out, header_len)) {
254 assert(0); 292 assert(0);
255 return 0; 293 return 0;
256 } 294 }
257 295
258 return 1; 296 return 1;
259} 297}
260 298
261int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) { 299int
262 return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */); 300CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value)
301{
302 return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
263} 303}
264 304
265int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) { 305int
266 return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */); 306CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value)
307{
308 return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
267} 309}
268 310
269int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) { 311int
270 if (CBS_len(cbs) < 1) { 312CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value)
271 return 0; 313{
272 } 314 if (CBS_len(cbs) < 1)
273 return CBS_data(cbs)[0] == tag_value; 315 return 0;
316
317 return CBS_data(cbs)[0] == tag_value;
274} 318}
275 319
276int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) { 320int
277 CBS bytes; 321CBS_get_asn1_uint64(CBS *cbs, uint64_t *out)
278 const uint8_t *data; 322{
279 size_t i, len; 323 CBS bytes;
280 324 const uint8_t *data;
281 if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) { 325 size_t i, len;
282 return 0; 326
283 } 327 if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER))
284 328 return 0;
285 *out = 0; 329
286 data = CBS_data(&bytes); 330 *out = 0;
287 len = CBS_len(&bytes); 331 data = CBS_data(&bytes);
288 332 len = CBS_len(&bytes);
289 if (len == 0) { 333
290 /* An INTEGER is encoded with at least one octet. */ 334 if (len == 0)
291 return 0; 335 /* An INTEGER is encoded with at least one octet. */
292 } 336 return 0;
293 337
294 if ((data[0] & 0x80) != 0) { 338 if ((data[0] & 0x80) != 0)
295 /* negative number */ 339 /* negative number */
296 return 0; 340 return 0;
297 } 341
298 342 for (i = 0; i < len; i++) {
299 for (i = 0; i < len; i++) { 343 if ((*out >> 56) != 0)
300 if ((*out >> 56) != 0) { 344 /* Too large to represent as a uint64_t. */
301 /* Too large to represent as a uint64_t. */ 345 return 0;
302 return 0; 346
303 } 347 *out <<= 8;
304 *out <<= 8; 348 *out |= data[i];
305 *out |= data[i]; 349 }
306 } 350
307 351 return 1;
308 return 1;
309} 352}
310 353
311int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) { 354int
312 if (CBS_peek_asn1_tag(cbs, tag)) { 355CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag)
313 if (!CBS_get_asn1(cbs, out, tag)) { 356{
314 return 0; 357 if (CBS_peek_asn1_tag(cbs, tag)) {
315 } 358 if (!CBS_get_asn1(cbs, out, tag))
316 *out_present = 1; 359 return 0;
317 } else { 360
318 *out_present = 0; 361 *out_present = 1;
319 } 362 } else {
320 return 1; 363 *out_present = 0;
364 }
365 return 1;
321} 366}
322 367
323int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, 368int
324 unsigned tag) { 369CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
325 CBS child; 370 unsigned tag)
326 int present; 371{
327 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { 372 CBS child;
328 return 0; 373 int present;
329 } 374
330 if (present) { 375 if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
331 if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) || 376 return 0;
332 CBS_len(&child) != 0) { 377
333 return 0; 378 if (present) {
334 } 379 if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
335 } else { 380 CBS_len(&child) != 0)
336 CBS_init(out, NULL, 0); 381 return 0;
337 } 382 } else {
338 if (out_present) { 383 CBS_init(out, NULL, 0);
339 *out_present = present; 384 }
340 } 385 if (out_present)
341 return 1; 386 *out_present = present;
387
388 return 1;
342} 389}
343 390
344int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag, 391int
345 uint64_t default_value) { 392CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
346 CBS child; 393 uint64_t default_value)
347 int present; 394{
348 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { 395 CBS child;
349 return 0; 396 int present;
350 } 397
351 if (present) { 398 if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
352 if (!CBS_get_asn1_uint64(&child, out) || 399 return 0;
353 CBS_len(&child) != 0) { 400
354 return 0; 401 if (present) {
355 } 402 if (!CBS_get_asn1_uint64(&child, out) ||
356 } else { 403 CBS_len(&child) != 0)
357 *out = default_value; 404 return 0;
358 } 405 } else {
359 return 1; 406 *out = default_value;
407 }
408 return 1;
360} 409}
361 410
362int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, 411int
363 int default_value) { 412CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, int default_value)
364 CBS child, child2; 413{
365 int present; 414 CBS child, child2;
366 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { 415 int present;
367 return 0; 416
368 } 417 if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
369 if (present) { 418 return 0;
370 uint8_t boolean; 419
371 420 if (present) {
372 if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) || 421 uint8_t boolean;
373 CBS_len(&child2) != 1 || 422
374 CBS_len(&child) != 0) { 423 if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
375 return 0; 424 CBS_len(&child2) != 1 || CBS_len(&child) != 0)
376 } 425 return 0;
377 426
378 boolean = CBS_data(&child2)[0]; 427 boolean = CBS_data(&child2)[0];
379 if (boolean == 0) { 428 if (boolean == 0)
380 *out = 0; 429 *out = 0;
381 } else if (boolean == 0xff) { 430 else if (boolean == 0xff)
382 *out = 1; 431 *out = 1;
383 } else { 432 else
384 return 0; 433 return 0;
385 } 434
386 } else { 435 } else {
387 *out = default_value; 436 *out = default_value;
388 } 437 }
389 return 1; 438 return 1;
390} 439}
diff --git a/src/lib/libssl/bytestring.h b/src/lib/libssl/bytestring.h
index 3c4e8eaaf3..09414af056 100644
--- a/src/lib/libssl/bytestring.h
+++ b/src/lib/libssl/bytestring.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: bytestring.h,v 1.1 2015/02/06 09:36:16 doug Exp $ */ 1/* $OpenBSD: bytestring.h,v 1.2 2015/02/06 22:22:33 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -26,96 +26,127 @@ extern "C" {
26 26
27#include <openssl/opensslconf.h> 27#include <openssl/opensslconf.h>
28 28
29/* Bytestrings are used for parsing and building TLS and ASN.1 messages. 29/*
30 * Bytestrings are used for parsing and building TLS and ASN.1 messages.
30 * 31 *
31 * A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and 32 * A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and
32 * provides utility functions for safely parsing length-prefixed structures 33 * provides utility functions for safely parsing length-prefixed structures
33 * like TLS and ASN.1 from it. 34 * like TLS and ASN.1 from it.
34 * 35 *
35 * A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and 36 * A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and
36 * provides utility functions for building length-prefixed messages. */ 37 * provides utility functions for building length-prefixed messages.
37 38 */
38 39
39/* CRYPTO ByteString */ 40/* CRYPTO ByteString */
40
41typedef struct cbs_st { 41typedef struct cbs_st {
42 const uint8_t *data; 42 const uint8_t *data;
43 size_t len; 43 size_t len;
44} CBS; 44} CBS;
45 45
46/* CBS_init sets |cbs| to point to |data|. It does not take ownership of 46/*
47 * |data|. */ 47 * CBS_init sets |cbs| to point to |data|. It does not take ownership of
48 * |data|.
49 */
48void CBS_init(CBS *cbs, const uint8_t *data, size_t len); 50void CBS_init(CBS *cbs, const uint8_t *data, size_t len);
49 51
50/* CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero 52/*
51 * otherwise. */ 53 * CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero
54 * otherwise.
55 */
52int CBS_skip(CBS *cbs, size_t len); 56int CBS_skip(CBS *cbs, size_t len);
53 57
54/* CBS_data returns a pointer to the contains of |cbs|. */ 58/*
59 * CBS_data returns a pointer to the contains of |cbs|.
60 */
55const uint8_t *CBS_data(const CBS *cbs); 61const uint8_t *CBS_data(const CBS *cbs);
56 62
57/* CBS_len returns the number of bytes remaining in |cbs|. */ 63/*
64 * CBS_len returns the number of bytes remaining in |cbs|.
65 */
58size_t CBS_len(const CBS *cbs); 66size_t CBS_len(const CBS *cbs);
59 67
60/* CBS_stow copies the current contents of |cbs| into |*out_ptr| and 68/*
69 * CBS_stow copies the current contents of |cbs| into |*out_ptr| and
61 * |*out_len|. If |*out_ptr| is not NULL, the contents are freed with 70 * |*out_len|. If |*out_ptr| is not NULL, the contents are freed with
62 * OPENSSL_free. It returns one on success and zero on allocation failure. On 71 * OPENSSL_free. It returns one on success and zero on allocation failure. On
63 * success, |*out_ptr| should be freed with OPENSSL_free. If |cbs| is empty, 72 * success, |*out_ptr| should be freed with OPENSSL_free. If |cbs| is empty,
64 * |*out_ptr| will be NULL. */ 73 * |*out_ptr| will be NULL.
74 */
65int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len); 75int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len);
66 76
67/* CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a 77/*
78 * CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a
68 * NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed 79 * NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed
69 * with OPENSSL_free. It returns one on success and zero on allocation 80 * with OPENSSL_free. It returns one on success and zero on allocation
70 * failure. On success, |*out_ptr| should be freed with OPENSSL_free. 81 * failure. On success, |*out_ptr| should be freed with OPENSSL_free.
71 * 82 *
72 * NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call 83 * NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call
73 * |CBS_contains_zero_byte(cbs)| to check for NUL bytes. */ 84 * |CBS_contains_zero_byte(cbs)| to check for NUL bytes.
85 */
74int CBS_strdup(const CBS *cbs, char **out_ptr); 86int CBS_strdup(const CBS *cbs, char **out_ptr);
75 87
76/* CBS_contains_zero_byte returns one if the current contents of |cbs| contains 88/*
77 * a NUL byte and zero otherwise. */ 89 * CBS_contains_zero_byte returns one if the current contents of |cbs| contains
90 * a NUL byte and zero otherwise.
91 */
78int CBS_contains_zero_byte(const CBS *cbs); 92int CBS_contains_zero_byte(const CBS *cbs);
79 93
80/* CBS_mem_equal compares the current contents of |cbs| with the |len| bytes 94/*
95 * CBS_mem_equal compares the current contents of |cbs| with the |len| bytes
81 * starting at |data|. If they're equal, it returns one, otherwise zero. If the 96 * starting at |data|. If they're equal, it returns one, otherwise zero. If the
82 * lengths match, it uses a constant-time comparison. */ 97 * lengths match, it uses a constant-time comparison.
83int CBS_mem_equal(const CBS *cbs, const uint8_t *data, 98 */
84 size_t len); 99int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len);
85 100
86/* CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It 101/*
87 * returns one on success and zero on error. */ 102 * CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It
103 * returns one on success and zero on error.
104 */
88int CBS_get_u8(CBS *cbs, uint8_t *out); 105int CBS_get_u8(CBS *cbs, uint8_t *out);
89 106
90/* CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and 107/*
91 * advances |cbs|. It returns one on success and zero on error. */ 108 * CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and
109 * advances |cbs|. It returns one on success and zero on error.
110 */
92int CBS_get_u16(CBS *cbs, uint16_t *out); 111int CBS_get_u16(CBS *cbs, uint16_t *out);
93 112
94/* CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and 113/*
95 * advances |cbs|. It returns one on success and zero on error. */ 114 * CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and
115 * advances |cbs|. It returns one on success and zero on error.
116 */
96int CBS_get_u24(CBS *cbs, uint32_t *out); 117int CBS_get_u24(CBS *cbs, uint32_t *out);
97 118
98/* CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs| 119/*
99 * and advances |cbs|. It returns one on success and zero on error. */ 120 * CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|
121 * and advances |cbs|. It returns one on success and zero on error.
122 */
100int CBS_get_u32(CBS *cbs, uint32_t *out); 123int CBS_get_u32(CBS *cbs, uint32_t *out);
101 124
102/* CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances 125/*
103 * |cbs|. It returns one on success and zero on error. */ 126 * CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances
127 * |cbs|. It returns one on success and zero on error.
128 */
104int CBS_get_bytes(CBS *cbs, CBS *out, size_t len); 129int CBS_get_bytes(CBS *cbs, CBS *out, size_t len);
105 130
106/* CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit, 131/*
132 * CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit,
107 * length-prefixed value from |cbs| and advances |cbs| over it. It returns one 133 * length-prefixed value from |cbs| and advances |cbs| over it. It returns one
108 * on success and zero on error. */ 134 * on success and zero on error.
135 */
109int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out); 136int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out);
110 137
111/* CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit, 138/*
139 * CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit,
112 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It 140 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
113 * returns one on success and zero on error. */ 141 * returns one on success and zero on error.
142 */
114int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out); 143int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out);
115 144
116/* CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit, 145/*
146 * CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit,
117 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It 147 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
118 * returns one on success and zero on error. */ 148 * returns one on success and zero on error.
149 */
119int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); 150int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
120 151
121 152
@@ -133,80 +164,95 @@ int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
133#define CBS_ASN1_CONSTRUCTED 0x20 164#define CBS_ASN1_CONSTRUCTED 0x20
134#define CBS_ASN1_CONTEXT_SPECIFIC 0x80 165#define CBS_ASN1_CONTEXT_SPECIFIC 0x80
135 166
136/* CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not 167/*
168 * CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not
137 * including tag and length bytes) and advances |cbs| over it. The ASN.1 169 * including tag and length bytes) and advances |cbs| over it. The ASN.1
138 * element must match |tag_value|. It returns one on success and zero 170 * element must match |tag_value|. It returns one on success and zero
139 * on error. 171 * on error.
140 * 172 *
141 * Tag numbers greater than 31 are not supported. */ 173 * Tag numbers greater than 31 are not supported.
174 */
142int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value); 175int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value);
143 176
144/* CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the 177/*
145 * ASN.1 header bytes too. */ 178 * CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the
179 * ASN.1 header bytes too.
180 */
146int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value); 181int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value);
147 182
148/* CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one 183/*
184 * CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one
149 * if the next ASN.1 element on |cbs| would have tag |tag_value|. If 185 * if the next ASN.1 element on |cbs| would have tag |tag_value|. If
150 * |cbs| is empty or the tag does not match, it returns zero. Note: if 186 * |cbs| is empty or the tag does not match, it returns zero. Note: if
151 * it returns one, CBS_get_asn1 may still fail if the rest of the 187 * it returns one, CBS_get_asn1 may still fail if the rest of the
152 * element is malformed. */ 188 * element is malformed.
189 */
153int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value); 190int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value);
154 191
155/* CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from 192/*
193 * CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
156 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to 194 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
157 * the tag number and |*out_header_len| to the length of the ASN.1 header. If 195 * the tag number and |*out_header_len| to the length of the ASN.1 header. If
158 * the element has indefinite length then |*out| will only contain the 196 * the element has indefinite length then |*out| will only contain the
159 * header. Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore 197 * header. Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore
160 * the value. 198 * the value.
161 * 199 *
162 * Tag numbers greater than 31 are not supported. */ 200 * Tag numbers greater than 31 are not supported.
163int CBS_get_any_asn1_element(CBS *cbs, CBS *out, 201 */
164 unsigned *out_tag, 202int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
165 size_t *out_header_len); 203 size_t *out_header_len);
166 204
167/* CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1| 205/*
206 * CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1|
168 * and sets |*out| to its value. It returns one on success and zero on error, 207 * and sets |*out| to its value. It returns one on success and zero on error,
169 * where error includes the integer being negative, or too large to represent 208 * where error includes the integer being negative, or too large to represent
170 * in 64 bits. */ 209 * in 64 bits.
210 */
171int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out); 211int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out);
172 212
173/* CBS_get_optional_asn1 gets an optional explicitly-tagged element 213/*
214 * CBS_get_optional_asn1 gets an optional explicitly-tagged element
174 * from |cbs| tagged with |tag| and sets |*out| to its contents. If 215 * from |cbs| tagged with |tag| and sets |*out| to its contents. If
175 * present, it sets |*out_present| to one, otherwise zero. It returns 216 * present, it sets |*out_present| to one, otherwise zero. It returns
176 * one on success, whether or not the element was present, and zero on 217 * one on success, whether or not the element was present, and zero on
177 * decode failure. */ 218 * decode failure.
178int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, 219 */
179 unsigned tag); 220int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag);
180 221
181/* CBS_get_optional_asn1_octet_string gets an optional 222/*
223 * CBS_get_optional_asn1_octet_string gets an optional
182 * explicitly-tagged OCTET STRING from |cbs|. If present, it sets 224 * explicitly-tagged OCTET STRING from |cbs|. If present, it sets
183 * |*out| to the string and |*out_present| to one. Otherwise, it sets 225 * |*out| to the string and |*out_present| to one. Otherwise, it sets
184 * |*out| to empty and |*out_present| to zero. |out_present| may be 226 * |*out| to empty and |*out_present| to zero. |out_present| may be
185 * NULL. It returns one on success, whether or not the element was 227 * NULL. It returns one on success, whether or not the element was
186 * present, and zero on decode failure. */ 228 * present, and zero on decode failure.
187int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, 229 */
188 int *out_present, 230int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
189 unsigned tag); 231 unsigned tag);
190 232
191/* CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged 233/*
234 * CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged
192 * INTEGER from |cbs|. If present, it sets |*out| to the 235 * INTEGER from |cbs|. If present, it sets |*out| to the
193 * value. Otherwise, it sets |*out| to |default_value|. It returns one 236 * value. Otherwise, it sets |*out| to |default_value|. It returns one
194 * on success, whether or not the element was present, and zero on 237 * on success, whether or not the element was present, and zero on
195 * decode failure. */ 238 * decode failure.
196int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, 239 */
197 unsigned tag, 240int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
198 uint64_t default_value); 241 uint64_t default_value);
199 242
200/* CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from 243/*
244 * CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from
201 * |cbs|. If present, it sets |*out| to either zero or one, based on the 245 * |cbs|. If present, it sets |*out| to either zero or one, based on the
202 * boolean. Otherwise, it sets |*out| to |default_value|. It returns one on 246 * boolean. Otherwise, it sets |*out| to |default_value|. It returns one on
203 * success, whether or not the element was present, and zero on decode 247 * success, whether or not the element was present, and zero on decode
204 * failure. */ 248 * failure.
249 */
205int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, 250int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
206 int default_value); 251 int default_value);
207 252
208 253
209/* CRYPTO ByteBuilder. 254/*
255 * CRYPTO ByteBuilder.
210 * 256 *
211 * |CBB| objects allow one to build length-prefixed serialisations. A |CBB| 257 * |CBB| objects allow one to build length-prefixed serialisations. A |CBB|
212 * object is associated with a buffer and new buffers are created with 258 * object is associated with a buffer and new buffers are created with
@@ -218,111 +264,162 @@ int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
218 * not be used again. 264 * not be used again.
219 * 265 *
220 * If one needs to force a length prefix to be written out because a |CBB| is 266 * If one needs to force a length prefix to be written out because a |CBB| is
221 * going out of scope, use |CBB_flush|. */ 267 * going out of scope, use |CBB_flush|.
268 */
222 269
223struct cbb_buffer_st { 270struct cbb_buffer_st {
224 uint8_t *buf; 271 uint8_t *buf;
225 size_t len; /* The number of valid bytes. */ 272
226 size_t cap; /* The size of buf. */ 273 /* The number of valid bytes. */
227 char can_resize; /* One iff |buf| is owned by this object. If not then |buf| 274 size_t len;
228 cannot be resized. */ 275
276 /* The size of buf. */
277 size_t cap;
278
279 /*
280 * One iff |buf| is owned by this object. If not then |buf| cannot be
281 * resized.
282 */
283 char can_resize;
229}; 284};
230 285
231typedef struct cbb_st { 286typedef struct cbb_st {
232 struct cbb_buffer_st *base; 287 struct cbb_buffer_st *base;
233 /* offset is the offset from the start of |base->buf| to the position of any 288
234 * pending length-prefix. */ 289 /*
235 size_t offset; 290 * offset is the offset from the start of |base->buf| to the position of any
236 /* child points to a child CBB if a length-prefix is pending. */ 291 * pending length-prefix.
237 struct cbb_st *child; 292 */
238 /* pending_len_len contains the number of bytes in a pending length-prefix, 293 size_t offset;
239 * or zero if no length-prefix is pending. */ 294
240 uint8_t pending_len_len; 295 /* child points to a child CBB if a length-prefix is pending. */
241 char pending_is_asn1; 296 struct cbb_st *child;
242 /* is_top_level is true iff this is a top-level |CBB| (as opposed to a child 297
243 * |CBB|). Top-level objects are valid arguments for |CBB_finish|. */ 298 /*
244 char is_top_level; 299 * pending_len_len contains the number of bytes in a pending length-prefix,
300 * or zero if no length-prefix is pending.
301 */
302 uint8_t pending_len_len;
303
304 char pending_is_asn1;
305
306 /*
307 * is_top_level is true iff this is a top-level |CBB| (as opposed to a child
308 * |CBB|). Top-level objects are valid arguments for |CBB_finish|.
309 */
310 char is_top_level;
245} CBB; 311} CBB;
246 312
247/* CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as 313/*
314 * CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as
248 * needed, the |initial_capacity| is just a hint. It returns one on success or 315 * needed, the |initial_capacity| is just a hint. It returns one on success or
249 * zero on error. */ 316 * zero on error.
317 */
250int CBB_init(CBB *cbb, size_t initial_capacity); 318int CBB_init(CBB *cbb, size_t initial_capacity);
251 319
252/* CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since 320/*
321 * CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since
253 * |buf| cannot grow, trying to write more than |len| bytes will cause CBB 322 * |buf| cannot grow, trying to write more than |len| bytes will cause CBB
254 * functions to fail. It returns one on success or zero on error. */ 323 * functions to fail. It returns one on success or zero on error.
324 */
255int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len); 325int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len);
256 326
257/* CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects 327/*
328 * CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects
258 * writing to the same buffer. This should be used in an error case where a 329 * writing to the same buffer. This should be used in an error case where a
259 * serialisation is abandoned. */ 330 * serialisation is abandoned.
331 */
260void CBB_cleanup(CBB *cbb); 332void CBB_cleanup(CBB *cbb);
261 333
262/* CBB_finish completes any pending length prefix and sets |*out_data| to a 334/*
335 * CBB_finish completes any pending length prefix and sets |*out_data| to a
263 * malloced buffer and |*out_len| to the length of that buffer. The caller 336 * malloced buffer and |*out_len| to the length of that buffer. The caller
264 * takes ownership of the buffer and, unless the buffer was fixed with 337 * takes ownership of the buffer and, unless the buffer was fixed with
265 * |CBB_init_fixed|, must call |OPENSSL_free| when done. 338 * |CBB_init_fixed|, must call |OPENSSL_free| when done.
266 * 339 *
267 * It can only be called on a "top level" |CBB|, i.e. one initialised with 340 * It can only be called on a "top level" |CBB|, i.e. one initialised with
268 * |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on 341 * |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on
269 * error. */ 342 * error.
343 */
270int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len); 344int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
271 345
272/* CBB_flush causes any pending length prefixes to be written out and any child 346/*
347 * CBB_flush causes any pending length prefixes to be written out and any child
273 * |CBB| objects of |cbb| to be invalidated. It returns one on success or zero 348 * |CBB| objects of |cbb| to be invalidated. It returns one on success or zero
274 * on error. */ 349 * on error.
350 */
275int CBB_flush(CBB *cbb); 351int CBB_flush(CBB *cbb);
276 352
277/* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The 353/*
354 * CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The
278 * data written to |*out_contents| will be prefixed in |cbb| with an 8-bit 355 * data written to |*out_contents| will be prefixed in |cbb| with an 8-bit
279 * length. It returns one on success or zero on error. */ 356 * length. It returns one on success or zero on error.
357 */
280int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents); 358int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents);
281 359
282/* CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|. 360/*
361 * CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|.
283 * The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit, 362 * The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit,
284 * big-endian length. It returns one on success or zero on error. */ 363 * big-endian length. It returns one on success or zero on error.
364 */
285int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents); 365int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents);
286 366
287/* CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|. 367/*
368 * CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|.
288 * The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit, 369 * The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit,
289 * big-endian length. It returns one on success or zero on error. */ 370 * big-endian length. It returns one on success or zero on error.
371 */
290int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents); 372int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
291 373
292/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an 374/*
375 * CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
293 * ASN.1 object can be written. The |tag| argument will be used as the tag for 376 * ASN.1 object can be written. The |tag| argument will be used as the tag for
294 * the object. It returns one on success or zero on error. */ 377 * the object. It returns one on success or zero on error.
378 */
295int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag); 379int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
296 380
297/* CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on 381/*
298 * success and zero otherwise. */ 382 * CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on
383 * success and zero otherwise.
384 */
299int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len); 385int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
300 386
301/* CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to 387/*
388 * CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to
302 * the beginning of that space. The caller must then write |len| bytes of 389 * the beginning of that space. The caller must then write |len| bytes of
303 * actual contents to |*out_data|. It returns one on success and zero 390 * actual contents to |*out_data|. It returns one on success and zero
304 * otherwise. */ 391 * otherwise.
392 */
305int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len); 393int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len);
306 394
307/* CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on 395/*
308 * success and zero otherwise. */ 396 * CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on
397 * success and zero otherwise.
398 */
309int CBB_add_u8(CBB *cbb, uint8_t value); 399int CBB_add_u8(CBB *cbb, uint8_t value);
310 400
311/* CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It 401/*
312 * returns one on success and zero otherwise. */ 402 * CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It
403 * returns one on success and zero otherwise.
404 */
313int CBB_add_u16(CBB *cbb, uint16_t value); 405int CBB_add_u16(CBB *cbb, uint16_t value);
314 406
315/* CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It 407/*
316 * returns one on success and zero otherwise. */ 408 * CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It
409 * returns one on success and zero otherwise.
410 */
317int CBB_add_u24(CBB *cbb, uint32_t value); 411int CBB_add_u24(CBB *cbb, uint32_t value);
318 412
319/* CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| 413/*
414 * CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1|
320 * and writes |value| in its contents. It returns one on success and zero on 415 * and writes |value| in its contents. It returns one on success and zero on
321 * error. */ 416 * error.
417 */
322int CBB_add_asn1_uint64(CBB *cbb, uint64_t value); 418int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
323 419
324#ifdef LIBRESSL_INTERNAL 420#ifdef LIBRESSL_INTERNAL
325/* CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds 421/*
422 * CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds
326 * indefinite-length elements then it attempts to convert the BER data to DER 423 * indefinite-length elements then it attempts to convert the BER data to DER
327 * and sets |*out| and |*out_length| to describe a malloced buffer containing 424 * and sets |*out| and |*out_length| to describe a malloced buffer containing
328 * the DER data. Additionally, |*in| will be advanced over the ASN.1 data. 425 * the DER data. Additionally, |*in| will be advanced over the ASN.1 data.
@@ -335,7 +432,8 @@ int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
335 * structure itself. However, this sufficies to handle the PKCS#7 and #12 output 432 * structure itself. However, this sufficies to handle the PKCS#7 and #12 output
336 * from NSS. 433 * from NSS.
337 * 434 *
338 * It returns one on success and zero otherwise. */ 435 * It returns one on success and zero otherwise.
436 */
339int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len); 437int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len);
340#endif /* LIBRESSL_INTERNAL */ 438#endif /* LIBRESSL_INTERNAL */
341 439
diff --git a/src/lib/libssl/src/ssl/bs_ber.c b/src/lib/libssl/src/ssl/bs_ber.c
index b94b63e37e..cfc9475f9a 100644
--- a/src/lib/libssl/src/ssl/bs_ber.c
+++ b/src/lib/libssl/src/ssl/bs_ber.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bs_ber.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */ 1/* $OpenBSD: bs_ber.c,v 1.2 2015/02/06 22:22:33 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -20,201 +20,233 @@
20 20
21#include "bytestring.h" 21#include "bytestring.h"
22 22
23/* kMaxDepth is a just a sanity limit. The code should be such that the length 23/*
24 * kMaxDepth is a just a sanity limit. The code should be such that the length
24 * of the input being processes always decreases. None the less, a very large 25 * of the input being processes always decreases. None the less, a very large
25 * input could otherwise cause the stack to overflow. */ 26 * input could otherwise cause the stack to overflow.
27 */
26static const unsigned kMaxDepth = 2048; 28static const unsigned kMaxDepth = 2048;
27 29
28/* cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found| 30/*
31 * cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found|
29 * depending on whether an indefinite length element was found. The value of 32 * depending on whether an indefinite length element was found. The value of
30 * |in| is not changed. It returns one on success (i.e. |*ber_found| was set) 33 * |in| is not changed. It returns one on success (i.e. |*ber_found| was set)
31 * and zero on error. */ 34 * and zero on error.
32static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) { 35 */
33 CBS in; 36static int
34 37cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth)
35 if (depth > kMaxDepth) { 38{
36 return 0; 39 CBS in;
37 } 40
38 41 if (depth > kMaxDepth)
39 CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); 42 return 0;
40 *ber_found = 0; 43
41 44 CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in));
42 while (CBS_len(&in) > 0) { 45 *ber_found = 0;
43 CBS contents; 46
44 unsigned tag; 47 while (CBS_len(&in) > 0) {
45 size_t header_len; 48 CBS contents;
46 49 unsigned tag;
47 if (!CBS_get_any_asn1_element(&in, &contents, &tag, &header_len)) { 50 size_t header_len;
48 return 0; 51
49 } 52 if (!CBS_get_any_asn1_element(&in, &contents, &tag,
50 if (CBS_len(&contents) == header_len && 53 &header_len))
51 header_len > 0 && 54 return 0;
52 CBS_data(&contents)[header_len-1] == 0x80) { 55
53 *ber_found = 1; 56 if (CBS_len(&contents) == header_len && header_len > 0 &&
54 return 1; 57 CBS_data(&contents)[header_len-1] == 0x80) {
55 } 58 *ber_found = 1;
56 if (tag & CBS_ASN1_CONSTRUCTED) { 59 return 1;
57 if (!CBS_skip(&contents, header_len) || 60 }
58 !cbs_find_ber(&contents, ber_found, depth + 1)) { 61 if (tag & CBS_ASN1_CONSTRUCTED) {
59 return 0; 62 if (!CBS_skip(&contents, header_len) ||
60 } 63 !cbs_find_ber(&contents, ber_found, depth + 1))
61 } 64 return 0;
62 } 65 }
63 66 }
64 return 1; 67
68 return 1;
65} 69}
66 70
67/* is_primitive_type returns true if |tag| likely a primitive type. Normally 71/*
72 * is_primitive_type returns true if |tag| likely a primitive type. Normally
68 * one can just test the "constructed" bit in the tag but, in BER, even 73 * one can just test the "constructed" bit in the tag but, in BER, even
69 * primitive tags can have the constructed bit if they have indefinite 74 * primitive tags can have the constructed bit if they have indefinite
70 * length. */ 75 * length.
71static char is_primitive_type(unsigned tag) { 76 */
72 return (tag & 0xc0) == 0 && 77static char
73 (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) && 78is_primitive_type(unsigned tag)
74 (tag & 0x1f) != (CBS_ASN1_SET & 0x1f); 79{
80 return (tag & 0xc0) == 0 &&
81 (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) &&
82 (tag & 0x1f) != (CBS_ASN1_SET & 0x1f);
75} 83}
76 84
77/* is_eoc returns true if |header_len| and |contents|, as returned by 85/*
78 * |CBS_get_any_asn1_element|, indicate an "end of contents" (EOC) value. */ 86 * is_eoc returns true if |header_len| and |contents|, as returned by
79static char is_eoc(size_t header_len, CBS *contents) { 87 * |CBS_get_any_asn1_element|, indicate an "end of contents" (EOC) value.
80 return header_len == 2 && CBS_len(contents) == 2 && 88 */
81 memcmp(CBS_data(contents), "\x00\x00", 2) == 0; 89static char
90is_eoc(size_t header_len, CBS *contents)
91{
92 return header_len == 2 && CBS_len(contents) == 2 &&
93 memcmp(CBS_data(contents), "\x00\x00", 2) == 0;
82} 94}
83 95
84/* cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If 96/*
97 * cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If
85 * |squash_header| is set then the top-level of elements from |in| will not 98 * |squash_header| is set then the top-level of elements from |in| will not
86 * have their headers written. This is used when concatenating the fragments of 99 * have their headers written. This is used when concatenating the fragments of
87 * an indefinite length, primitive value. If |looking_for_eoc| is set then any 100 * an indefinite length, primitive value. If |looking_for_eoc| is set then any
88 * EOC elements found will cause the function to return after consuming it. 101 * EOC elements found will cause the function to return after consuming it.
89 * It returns one on success and zero on error. */ 102 * It returns one on success and zero on error.
90static int cbs_convert_ber(CBS *in, CBB *out, char squash_header, 103 */
91 char looking_for_eoc, unsigned depth) { 104static int
92 if (depth > kMaxDepth) { 105cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc,
93 return 0; 106 unsigned depth)
94 } 107{
95 108 if (depth > kMaxDepth)
96 while (CBS_len(in) > 0) { 109 return 0;
97 CBS contents; 110
98 unsigned tag; 111 while (CBS_len(in) > 0) {
99 size_t header_len; 112 CBS contents;
100 CBB *out_contents, out_contents_storage; 113 unsigned tag;
101 114 size_t header_len;
102 if (!CBS_get_any_asn1_element(in, &contents, &tag, &header_len)) { 115 CBB *out_contents, out_contents_storage;
103 return 0; 116
104 } 117 if (!CBS_get_any_asn1_element(in, &contents, &tag, &header_len))
105 out_contents = out; 118 return 0;
106 119
107 if (CBS_len(&contents) == header_len) { 120 out_contents = out;
108 if (is_eoc(header_len, &contents)) { 121
109 return looking_for_eoc; 122 if (CBS_len(&contents) == header_len) {
110 } 123 if (is_eoc(header_len, &contents))
111 124 return looking_for_eoc;
112 if (header_len > 0 && CBS_data(&contents)[header_len - 1] == 0x80) { 125
113 /* This is an indefinite length element. If it's a SEQUENCE or SET then 126 if (header_len > 0 &&
114 * we just need to write the out the contents as normal, but with a 127 CBS_data(&contents)[header_len - 1] == 0x80) {
115 * concrete length prefix. 128 /*
116 * 129 * This is an indefinite length element. If
117 * If it's a something else then the contents will be a series of BER 130 * it's a SEQUENCE or SET then we just need to
118 * elements of the same type which need to be concatenated. */ 131 * write the out the contents as normal, but
119 const char context_specific = (tag & 0xc0) == 0x80; 132 * with a concrete length prefix.
120 char squash_child_headers = is_primitive_type(tag); 133 *
121 134 * If it's a something else then the contents
122 /* This is a hack, but it sufficies to handle NSS's output. If we find 135 * will be a series of BER elements of the same
123 * an indefinite length, context-specific tag with a definite, primtive 136 * type which need to be concatenated.
124 * tag inside it, then we assume that the context-specific tag is 137 */
125 * implicit and the tags within are fragments of a primitive type that 138 const char context_specific = (tag & 0xc0)
126 * need to be concatenated. */ 139 == 0x80;
127 if (context_specific && (tag & CBS_ASN1_CONSTRUCTED)) { 140 char squash_child_headers =
128 CBS in_copy, inner_contents; 141 is_primitive_type(tag);
129 unsigned inner_tag; 142
130 size_t inner_header_len; 143 /*
131 144 * This is a hack, but it sufficies to handle
132 CBS_init(&in_copy, CBS_data(in), CBS_len(in)); 145 * NSS's output. If we find an indefinite
133 if (!CBS_get_any_asn1_element(&in_copy, &inner_contents, &inner_tag, 146 * length, context-specific tag with a definite,
134 &inner_header_len)) { 147 * primtive tag inside it, then we assume that
135 return 0; 148 * the context-specific tag is implicit and the
136 } 149 * tags within are fragments of a primitive type
137 if (CBS_len(&inner_contents) > inner_header_len && 150 * that need to be concatenated.
138 is_primitive_type(inner_tag)) { 151 */
139 squash_child_headers = 1; 152 if (context_specific &&
140 } 153 (tag & CBS_ASN1_CONSTRUCTED)) {
141 } 154 CBS in_copy, inner_contents;
142 155 unsigned inner_tag;
143 if (!squash_header) { 156 size_t inner_header_len;
144 unsigned out_tag = tag; 157
145 if (squash_child_headers) { 158 CBS_init(&in_copy, CBS_data(in),
146 out_tag &= ~CBS_ASN1_CONSTRUCTED; 159 CBS_len(in));
147 } 160 if (!CBS_get_any_asn1_element(&in_copy,
148 if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) { 161 &inner_contents, &inner_tag,
149 return 0; 162 &inner_header_len))
150 } 163 return 0;
151 out_contents = &out_contents_storage; 164
152 } 165 if (CBS_len(&inner_contents) >
153 166 inner_header_len &&
154 if (!cbs_convert_ber(in, out_contents, 167 is_primitive_type(inner_tag))
155 squash_child_headers, 168 squash_child_headers = 1;
156 1 /* looking for eoc */, depth + 1)) { 169 }
157 return 0; 170
158 } 171 if (!squash_header) {
159 if (out_contents != out && !CBB_flush(out)) { 172 unsigned out_tag = tag;
160 return 0; 173
161 } 174 if (squash_child_headers)
162 continue; 175 out_tag &=
163 } 176 ~CBS_ASN1_CONSTRUCTED;
164 } 177
165 178 if (!CBB_add_asn1(out,
166 if (!squash_header) { 179 &out_contents_storage, out_tag))
167 if (!CBB_add_asn1(out, &out_contents_storage, tag)) { 180 return 0;
168 return 0; 181
169 } 182 out_contents = &out_contents_storage;
170 out_contents = &out_contents_storage; 183 }
171 } 184
172 185 if (!cbs_convert_ber(in, out_contents,
173 if (!CBS_skip(&contents, header_len)) { 186 squash_child_headers,
174 return 0; 187 1 /* looking for eoc */, depth + 1))
175 } 188 return 0;
176 189
177 if (tag & CBS_ASN1_CONSTRUCTED) { 190 if (out_contents != out && !CBB_flush(out))
178 if (!cbs_convert_ber(&contents, out_contents, 0 /* don't squash header */, 191 return 0;
179 0 /* not looking for eoc */, depth + 1)) { 192
180 return 0; 193 continue;
181 } 194 }
182 } else { 195 }
183 if (!CBB_add_bytes(out_contents, CBS_data(&contents), 196
184 CBS_len(&contents))) { 197 if (!squash_header) {
185 return 0; 198 if (!CBB_add_asn1(out, &out_contents_storage, tag))
186 } 199 return 0;
187 } 200
188 201 out_contents = &out_contents_storage;
189 if (out_contents != out && !CBB_flush(out)) { 202 }
190 return 0; 203
191 } 204 if (!CBS_skip(&contents, header_len))
192 } 205 return 0;
193 206
194 return looking_for_eoc == 0; 207 if (tag & CBS_ASN1_CONSTRUCTED) {
208 if (!cbs_convert_ber(&contents, out_contents,
209 0 /* don't squash header */,
210 0 /* not looking for eoc */, depth + 1))
211 return 0;
212 } else {
213 if (!CBB_add_bytes(out_contents, CBS_data(&contents),
214 CBS_len(&contents)))
215 return 0;
216 }
217
218 if (out_contents != out && !CBB_flush(out))
219 return 0;
220 }
221
222 return looking_for_eoc == 0;
195} 223}
196 224
197int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) { 225int
198 CBB cbb; 226CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len)
199 227{
200 /* First, do a quick walk to find any indefinite-length elements. Most of the 228 CBB cbb;
201 * time we hope that there aren't any and thus we can quickly return. */ 229
202 char conversion_needed; 230 /*
203 if (!cbs_find_ber(in, &conversion_needed, 0)) { 231 * First, do a quick walk to find any indefinite-length elements. Most
204 return 0; 232 * of the time we hope that there aren't any and thus we can quickly
205 } 233 * return.
206 234 */
207 if (!conversion_needed) { 235 char conversion_needed;
208 *out = NULL; 236 if (!cbs_find_ber(in, &conversion_needed, 0))
209 *out_len = 0; 237 return 0;
210 return 1; 238
211 } 239 if (!conversion_needed) {
212 240 *out = NULL;
213 CBB_init(&cbb, CBS_len(in)); 241 *out_len = 0;
214 if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) { 242 return 1;
215 CBB_cleanup(&cbb); 243 }
216 return 0; 244
217 } 245 CBB_init(&cbb, CBS_len(in));
218 246 if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) {
219 return CBB_finish(&cbb, out, out_len); 247 CBB_cleanup(&cbb);
248 return 0;
249 }
250
251 return CBB_finish(&cbb, out, out_len);
220} 252}
diff --git a/src/lib/libssl/src/ssl/bs_cbb.c b/src/lib/libssl/src/ssl/bs_cbb.c
index 11688bcb7b..94ca54f43b 100644
--- a/src/lib/libssl/src/ssl/bs_cbb.c
+++ b/src/lib/libssl/src/ssl/bs_cbb.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bs_cbb.c,v 1.2 2015/02/06 10:06:30 doug Exp $ */ 1/* $OpenBSD: bs_cbb.c,v 1.3 2015/02/06 22:22:33 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -22,356 +22,365 @@
22 22
23#include "bytestring.h" 23#include "bytestring.h"
24 24
25static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) { 25static int
26 struct cbb_buffer_st *base; 26cbb_init(CBB *cbb, uint8_t *buf, size_t cap)
27{
28 struct cbb_buffer_st *base;
29
30 base = malloc(sizeof(struct cbb_buffer_st));
31 if (base == NULL) {
32 free(buf);
33 return 0;
34 }
35
36 base->buf = buf;
37 base->len = 0;
38 base->cap = cap;
39 base->can_resize = 1;
40
41 memset(cbb, 0, sizeof(CBB));
42 cbb->base = base;
43 cbb->is_top_level = 1;
44 return 1;
45}
27 46
28 base = malloc(sizeof(struct cbb_buffer_st)); 47int
29 if (base == NULL) { 48CBB_init(CBB *cbb, size_t initial_capacity)
30 free(buf); 49{
31 return 0; 50 uint8_t *buf;
32 }
33 51
34 base->buf = buf; 52 buf = malloc(initial_capacity);
35 base->len = 0; 53 if (initial_capacity > 0 && buf == NULL)
36 base->cap = cap; 54 return 0;
37 base->can_resize = 1;
38 55
39 memset(cbb, 0, sizeof(CBB)); 56 return cbb_init(cbb, buf, initial_capacity);
40 cbb->base = base;
41 cbb->is_top_level = 1;
42 return 1;
43} 57}
44 58
45int CBB_init(CBB *cbb, size_t initial_capacity) { 59int
46 uint8_t *buf; 60CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len)
47 61{
48 buf = malloc(initial_capacity); 62 if (!cbb_init(cbb, buf, len))
49 if (initial_capacity > 0 && buf == NULL) { 63 return 0;
50 return 0;
51 }
52 64
53 return cbb_init(cbb, buf, initial_capacity); 65 cbb->base->can_resize = 0;
66 return 1;
54} 67}
55 68
56int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) { 69void
57 if (!cbb_init(cbb, buf, len)) { 70CBB_cleanup(CBB *cbb)
58 return 0; 71{
59 } 72 if (cbb->base) {
73 if (cbb->base->buf && cbb->base->can_resize)
74 free(cbb->base->buf);
60 75
61 cbb->base->can_resize = 0; 76 free(cbb->base);
62 return 1; 77 }
78 cbb->base = NULL;
63} 79}
64 80
65void CBB_cleanup(CBB *cbb) { 81static int
66 if (cbb->base) { 82cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len)
67 if (cbb->base->buf && cbb->base->can_resize) { 83{
68 free(cbb->base->buf); 84 size_t newlen;
69 } 85
70 free(cbb->base); 86 if (base == NULL)
71 } 87 return 0;
72 cbb->base = NULL; 88
73} 89 newlen = base->len + len;
90 if (newlen < base->len)
91 /* Overflow */
92 return 0;
93
94 if (newlen > base->cap) {
95 size_t newcap = base->cap * 2;
96 uint8_t *newbuf;
97
98 if (!base->can_resize)
99 return 0;
100
101 if (newcap < base->cap || newcap < newlen)
102 newcap = newlen;
103
104 newbuf = realloc(base->buf, newcap);
105 if (newbuf == NULL)
106 return 0;
107
108 base->buf = newbuf;
109 base->cap = newcap;
110 }
111
112 if (out)
113 *out = base->buf + base->len;
74 114
75static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, 115 base->len = newlen;
76 size_t len) { 116 return 1;
77 size_t newlen;
78
79 if (base == NULL) {
80 return 0;
81 }
82
83 newlen = base->len + len;
84 if (newlen < base->len) {
85 /* Overflow */
86 return 0;
87 }
88
89 if (newlen > base->cap) {
90 size_t newcap = base->cap * 2;
91 uint8_t *newbuf;
92
93 if (!base->can_resize) {
94 return 0;
95 }
96
97 if (newcap < base->cap || newcap < newlen) {
98 newcap = newlen;
99 }
100 newbuf = realloc(base->buf, newcap);
101 if (newbuf == NULL) {
102 return 0;
103 }
104
105 base->buf = newbuf;
106 base->cap = newcap;
107 }
108
109 if (out) {
110 *out = base->buf + base->len;
111 }
112 base->len = newlen;
113 return 1;
114} 117}
115 118
116static int cbb_buffer_add_u(struct cbb_buffer_st *base, uint32_t v, 119static int
117 size_t len_len) { 120cbb_buffer_add_u(struct cbb_buffer_st *base, uint32_t v, size_t len_len)
118 uint8_t *buf; 121{
119 size_t i; 122 uint8_t *buf;
120 123 size_t i;
121 if (len_len == 0) { 124
122 return 1; 125 if (len_len == 0)
123 } 126 return 1;
124 if (!cbb_buffer_add(base, &buf, len_len)) { 127
125 return 0; 128 if (!cbb_buffer_add(base, &buf, len_len))
126 } 129 return 0;
127 130
128 for (i = len_len - 1; i < len_len; i--) { 131 for (i = len_len - 1; i < len_len; i--) {
129 buf[i] = v; 132 buf[i] = v;
130 v >>= 8; 133 v >>= 8;
131 } 134 }
132 return 1; 135 return 1;
133} 136}
134 137
135int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) { 138int
136 if (!cbb->is_top_level) { 139CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len)
137 return 0; 140{
138 } 141 if (!cbb->is_top_level)
139 142 return 0;
140 if (!CBB_flush(cbb)) { 143
141 return 0; 144 if (!CBB_flush(cbb))
142 } 145 return 0;
143 146
144 if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) { 147 if (cbb->base->can_resize && (out_data == NULL || out_len == NULL))
145 /* |out_data| and |out_len| can only be NULL if the CBB is fixed. */ 148 /* |out_data| and |out_len| can only be NULL if the CBB is fixed. */
146 return 0; 149 return 0;
147 } 150
148 151 if (out_data != NULL)
149 if (out_data != NULL) { 152 *out_data = cbb->base->buf;
150 *out_data = cbb->base->buf; 153
151 } 154 if (out_len != NULL)
152 if (out_len != NULL) { 155 *out_len = cbb->base->len;
153 *out_len = cbb->base->len; 156
154 } 157 cbb->base->buf = NULL;
155 cbb->base->buf = NULL; 158 CBB_cleanup(cbb);
156 CBB_cleanup(cbb); 159 return 1;
157 return 1;
158} 160}
159 161
160/* CBB_flush recurses and then writes out any pending length prefix. The 162/*
161 * current length of the underlying base is taken to be the length of the 163 * CBB_flush recurses and then writes out any pending length prefix. The current
162 * length-prefixed data. */ 164 * length of the underlying base is taken to be the length of the
163int CBB_flush(CBB *cbb) { 165 * length-prefixed data.
164 size_t child_start, i, len; 166 */
165 167int
166 if (cbb->base == NULL) { 168CBB_flush(CBB *cbb)
167 return 0; 169{
168 } 170 size_t child_start, i, len;
169 171
170 if (cbb->child == NULL || cbb->pending_len_len == 0) { 172 if (cbb->base == NULL)
171 return 1; 173 return 0;
172 } 174
173 175 if (cbb->child == NULL || cbb->pending_len_len == 0)
174 child_start = cbb->offset + cbb->pending_len_len; 176 return 1;
175 177
176 if (!CBB_flush(cbb->child) || 178 child_start = cbb->offset + cbb->pending_len_len;
177 child_start < cbb->offset || 179
178 cbb->base->len < child_start) { 180 if (!CBB_flush(cbb->child) || child_start < cbb->offset ||
179 return 0; 181 cbb->base->len < child_start)
180 } 182 return 0;
181 183
182 len = cbb->base->len - child_start; 184 len = cbb->base->len - child_start;
183 185
184 if (cbb->pending_is_asn1) { 186 if (cbb->pending_is_asn1) {
185 /* For ASN.1 we assume that we'll only need a single byte for the length. 187 /* For ASN.1 we assume that we'll only need a single byte for the length.
186 * If that turned out to be incorrect, we have to move the contents along 188 * If that turned out to be incorrect, we have to move the contents along
187 * in order to make space. */ 189 * in order to make space. */
188 size_t len_len; 190 size_t len_len;
189 uint8_t initial_length_byte; 191 uint8_t initial_length_byte;
190 192
191 assert (cbb->pending_len_len == 1); 193 assert (cbb->pending_len_len == 1);
192 194
193 if (len > 0xfffffffe) { 195 if (len > 0xfffffffe) {
194 /* Too large. */ 196 /* Too large. */
195 return 0; 197 return 0;
196 } else if (len > 0xffffff) { 198 } else if (len > 0xffffff) {
197 len_len = 5; 199 len_len = 5;
198 initial_length_byte = 0x80 | 4; 200 initial_length_byte = 0x80 | 4;
199 } else if (len > 0xffff) { 201 } else if (len > 0xffff) {
200 len_len = 4; 202 len_len = 4;
201 initial_length_byte = 0x80 | 3; 203 initial_length_byte = 0x80 | 3;
202 } else if (len > 0xff) { 204 } else if (len > 0xff) {
203 len_len = 3; 205 len_len = 3;
204 initial_length_byte = 0x80 | 2; 206 initial_length_byte = 0x80 | 2;
205 } else if (len > 0x7f) { 207 } else if (len > 0x7f) {
206 len_len = 2; 208 len_len = 2;
207 initial_length_byte = 0x80 | 1; 209 initial_length_byte = 0x80 | 1;
208 } else { 210 } else {
209 len_len = 1; 211 len_len = 1;
210 initial_length_byte = len; 212 initial_length_byte = len;
211 len = 0; 213 len = 0;
212 } 214 }
213 215
214 if (len_len != 1) { 216 if (len_len != 1) {
215 /* We need to move the contents along in order to make space. */ 217 /* We need to move the contents along in order to make space. */
216 size_t extra_bytes = len_len - 1; 218 size_t extra_bytes = len_len - 1;
217 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) { 219 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes))
218 return 0; 220 return 0;
219 } 221
220 memmove(cbb->base->buf + child_start + extra_bytes, 222 memmove(cbb->base->buf + child_start + extra_bytes,
221 cbb->base->buf + child_start, len); 223 cbb->base->buf + child_start, len);
222 } 224 }
223 cbb->base->buf[cbb->offset++] = initial_length_byte; 225 cbb->base->buf[cbb->offset++] = initial_length_byte;
224 cbb->pending_len_len = len_len - 1; 226 cbb->pending_len_len = len_len - 1;
225 } 227 }
226 228
227 for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) { 229 for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) {
228 cbb->base->buf[cbb->offset + i] = len; 230 cbb->base->buf[cbb->offset + i] = len;
229 len >>= 8; 231 len >>= 8;
230 } 232 }
231 if (len != 0) { 233 if (len != 0)
232 return 0; 234 return 0;
233 } 235
234 236 cbb->child->base = NULL;
235 cbb->child->base = NULL; 237 cbb->child = NULL;
236 cbb->child = NULL; 238 cbb->pending_len_len = 0;
237 cbb->pending_len_len = 0; 239 cbb->pending_is_asn1 = 0;
238 cbb->pending_is_asn1 = 0; 240 cbb->offset = 0;
239 cbb->offset = 0; 241
240 242 return 1;
241 return 1;
242} 243}
243 244
244 245
245static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, 246static int
246 size_t len_len) { 247cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len)
247 uint8_t *prefix_bytes; 248{
249 uint8_t *prefix_bytes;
248 250
249 if (!CBB_flush(cbb)) { 251 if (!CBB_flush(cbb))
250 return 0; 252 return 0;
251 }
252 253
253 cbb->offset = cbb->base->len; 254 cbb->offset = cbb->base->len;
254 if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) { 255 if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len))
255 return 0; 256 return 0;
256 }
257 257
258 memset(prefix_bytes, 0, len_len); 258 memset(prefix_bytes, 0, len_len);
259 memset(out_contents, 0, sizeof(CBB)); 259 memset(out_contents, 0, sizeof(CBB));
260 out_contents->base = cbb->base; 260 out_contents->base = cbb->base;
261 cbb->child = out_contents; 261 cbb->child = out_contents;
262 cbb->pending_len_len = len_len; 262 cbb->pending_len_len = len_len;
263 cbb->pending_is_asn1 = 0; 263 cbb->pending_is_asn1 = 0;
264 264
265 return 1; 265 return 1;
266} 266}
267 267
268int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) { 268int
269 return cbb_add_length_prefixed(cbb, out_contents, 1); 269CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents)
270{
271 return cbb_add_length_prefixed(cbb, out_contents, 1);
270} 272}
271 273
272int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) { 274int
273 return cbb_add_length_prefixed(cbb, out_contents, 2); 275CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents)
276{
277 return cbb_add_length_prefixed(cbb, out_contents, 2);
274} 278}
275 279
276int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) { 280int
277 return cbb_add_length_prefixed(cbb, out_contents, 3); 281CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents)
282{
283 return cbb_add_length_prefixed(cbb, out_contents, 3);
278} 284}
279 285
280int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) { 286int
281 if (!CBB_flush(cbb) || 287CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag)
282 !CBB_add_u8(cbb, tag)) { 288{
283 return 0; 289 if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag))
284 } 290 return 0;
285 291
286 cbb->offset = cbb->base->len; 292 cbb->offset = cbb->base->len;
287 if (!CBB_add_u8(cbb, 0)) { 293 if (!CBB_add_u8(cbb, 0))
288 return 0; 294 return 0;
289 }
290 295
291 memset(out_contents, 0, sizeof(CBB)); 296 memset(out_contents, 0, sizeof(CBB));
292 out_contents->base = cbb->base; 297 out_contents->base = cbb->base;
293 cbb->child = out_contents; 298 cbb->child = out_contents;
294 cbb->pending_len_len = 1; 299 cbb->pending_len_len = 1;
295 cbb->pending_is_asn1 = 1; 300 cbb->pending_is_asn1 = 1;
296 301
297 return 1; 302 return 1;
298} 303}
299 304
300int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) { 305int
301 uint8_t *dest; 306CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len)
307{
308 uint8_t *dest;
302 309
303 if (!CBB_flush(cbb) || 310 if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &dest, len))
304 !cbb_buffer_add(cbb->base, &dest, len)) { 311 return 0;
305 return 0; 312
306 } 313 memcpy(dest, data, len);
307 memcpy(dest, data, len); 314 return 1;
308 return 1;
309} 315}
310 316
311int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { 317int
312 if (!CBB_flush(cbb) || 318CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len)
313 !cbb_buffer_add(cbb->base, out_data, len)) { 319{
314 return 0; 320 if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len))
315 } 321 return 0;
316 return 1; 322
323 return 1;
317} 324}
318 325
319int CBB_add_u8(CBB *cbb, uint8_t value) { 326int
320 if (!CBB_flush(cbb)) { 327CBB_add_u8(CBB *cbb, uint8_t value)
321 return 0; 328{
322 } 329 if (!CBB_flush(cbb))
330 return 0;
323 331
324 return cbb_buffer_add_u(cbb->base, value, 1); 332 return cbb_buffer_add_u(cbb->base, value, 1);
325} 333}
326 334
327int CBB_add_u16(CBB *cbb, uint16_t value) { 335int
328 if (!CBB_flush(cbb)) { 336CBB_add_u16(CBB *cbb, uint16_t value)
329 return 0; 337{
330 } 338 if (!CBB_flush(cbb))
339 return 0;
331 340
332 return cbb_buffer_add_u(cbb->base, value, 2); 341 return cbb_buffer_add_u(cbb->base, value, 2);
333} 342}
334 343
335int CBB_add_u24(CBB *cbb, uint32_t value) { 344int
336 if (!CBB_flush(cbb)) { 345CBB_add_u24(CBB *cbb, uint32_t value)
337 return 0; 346{
338 } 347 if (!CBB_flush(cbb))
348 return 0;
339 349
340 return cbb_buffer_add_u(cbb->base, value, 3); 350 return cbb_buffer_add_u(cbb->base, value, 3);
341} 351}
342 352
343int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { 353int
344 CBB child; 354CBB_add_asn1_uint64(CBB *cbb, uint64_t value)
345 size_t i; 355{
346 int started = 0; 356 CBB child;
347 357 size_t i;
348 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { 358 int started = 0;
349 return 0; 359
350 } 360 if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER))
351 361 return 0;
352 for (i = 0; i < 8; i++) { 362
353 uint8_t byte = (value >> 8*(7-i)) & 0xff; 363 for (i = 0; i < 8; i++) {
354 if (!started) { 364 uint8_t byte = (value >> 8*(7-i)) & 0xff;
355 if (byte == 0) { 365 if (!started) {
356 /* Don't encode leading zeros. */ 366 if (byte == 0)
357 continue; 367 /* Don't encode leading zeros. */
358 } 368 continue;
359 /* If the high bit is set, add a padding byte to make it 369
360 * unsigned. */ 370 /* If the high bit is set, add a padding byte to make it
361 if ((byte & 0x80) && !CBB_add_u8(&child, 0)) { 371 * unsigned. */
362 return 0; 372 if ((byte & 0x80) && !CBB_add_u8(&child, 0))
363 } 373 return 0;
364 started = 1; 374
365 } 375 started = 1;
366 if (!CBB_add_u8(&child, byte)) { 376 }
367 return 0; 377 if (!CBB_add_u8(&child, byte))
368 } 378 return 0;
369 } 379 }
370 380
371 /* 0 is encoded as a single 0, not the empty string. */ 381 /* 0 is encoded as a single 0, not the empty string. */
372 if (!started && !CBB_add_u8(&child, 0)) { 382 if (!started && !CBB_add_u8(&child, 0))
373 return 0; 383 return 0;
374 } 384
375 385 return CBB_flush(cbb);
376 return CBB_flush(cbb);
377} 386}
diff --git a/src/lib/libssl/src/ssl/bs_cbs.c b/src/lib/libssl/src/ssl/bs_cbs.c
index 7edfe65288..c3d3a8abf2 100644
--- a/src/lib/libssl/src/ssl/bs_cbs.c
+++ b/src/lib/libssl/src/ssl/bs_cbs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bs_cbs.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */ 1/* $OpenBSD: bs_cbs.c,v 1.2 2015/02/06 22:22:33 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -24,367 +24,416 @@
24 24
25#include "bytestring.h" 25#include "bytestring.h"
26 26
27void CBS_init(CBS *cbs, const uint8_t *data, size_t len) { 27void
28 cbs->data = data; 28CBS_init(CBS *cbs, const uint8_t *data, size_t len)
29 cbs->len = len; 29{
30 cbs->data = data;
31 cbs->len = len;
30} 32}
31 33
32static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) { 34static int
33 if (cbs->len < n) { 35cbs_get(CBS *cbs, const uint8_t **p, size_t n)
34 return 0; 36{
35 } 37 if (cbs->len < n)
38 return 0;
36 39
37 *p = cbs->data; 40 *p = cbs->data;
38 cbs->data += n; 41 cbs->data += n;
39 cbs->len -= n; 42 cbs->len -= n;
40 return 1; 43 return 1;
41} 44}
42 45
43int CBS_skip(CBS *cbs, size_t len) { 46int
44 const uint8_t *dummy; 47CBS_skip(CBS *cbs, size_t len)
45 return cbs_get(cbs, &dummy, len); 48{
49 const uint8_t *dummy;
50 return cbs_get(cbs, &dummy, len);
46} 51}
47 52
48const uint8_t *CBS_data(const CBS *cbs) { 53const uint8_t *
49 return cbs->data; 54CBS_data(const CBS *cbs)
55{
56 return cbs->data;
50} 57}
51 58
52size_t CBS_len(const CBS *cbs) { 59size_t
53 return cbs->len; 60CBS_len(const CBS *cbs)
61{
62 return cbs->len;
54} 63}
55 64
56int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) { 65int
57 if (*out_ptr != NULL) { 66CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len)
58 free(*out_ptr); 67{
59 *out_ptr = NULL; 68 if (*out_ptr != NULL) {
60 } 69 free(*out_ptr);
61 *out_len = 0; 70 *out_ptr = NULL;
62 71 }
63 if (cbs->len == 0) { 72 *out_len = 0;
64 return 1; 73
65 } 74 if (cbs->len == 0)
66 *out_ptr = BUF_memdup(cbs->data, cbs->len); 75 return 1;
67 if (*out_ptr == NULL) { 76
68 return 0; 77 *out_ptr = BUF_memdup(cbs->data, cbs->len);
69 } 78 if (*out_ptr == NULL)
70 *out_len = cbs->len; 79 return 0;
71 return 1; 80
81 *out_len = cbs->len;
82 return 1;
72} 83}
73 84
74int CBS_strdup(const CBS *cbs, char **out_ptr) { 85int
75 if (*out_ptr != NULL) { 86CBS_strdup(const CBS *cbs, char **out_ptr)
76 free(*out_ptr); 87{
77 } 88 if (*out_ptr != NULL)
78 *out_ptr = strndup((const char*)cbs->data, cbs->len); 89 free(*out_ptr);
79 return (*out_ptr != NULL); 90
91 *out_ptr = strndup((const char*)cbs->data, cbs->len);
92 return (*out_ptr != NULL);
80} 93}
81 94
82int CBS_contains_zero_byte(const CBS *cbs) { 95int
83 return memchr(cbs->data, 0, cbs->len) != NULL; 96CBS_contains_zero_byte(const CBS *cbs)
97{
98 return memchr(cbs->data, 0, cbs->len) != NULL;
84} 99}
85 100
86int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) { 101int
87 if (len != cbs->len) 102CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len)
88 return 0; 103{
89 return CRYPTO_memcmp(cbs->data, data, len) == 0; 104 if (len != cbs->len)
105 return 0;
106
107 return CRYPTO_memcmp(cbs->data, data, len) == 0;
90} 108}
91 109
92static int cbs_get_u(CBS *cbs, uint32_t *out, size_t len) { 110static int
93 uint32_t result = 0; 111cbs_get_u(CBS *cbs, uint32_t *out, size_t len)
94 size_t i; 112{
95 const uint8_t *data; 113 uint32_t result = 0;
96 114 size_t i;
97 if (!cbs_get(cbs, &data, len)) { 115 const uint8_t *data;
98 return 0; 116
99 } 117 if (!cbs_get(cbs, &data, len))
100 for (i = 0; i < len; i++) { 118 return 0;
101 result <<= 8; 119
102 result |= data[i]; 120 for (i = 0; i < len; i++) {
103 } 121 result <<= 8;
104 *out = result; 122 result |= data[i];
105 return 1; 123 }
124 *out = result;
125 return 1;
106} 126}
107 127
108int CBS_get_u8(CBS *cbs, uint8_t *out) { 128int
109 const uint8_t *v; 129CBS_get_u8(CBS *cbs, uint8_t *out)
110 if (!cbs_get(cbs, &v, 1)) { 130{
111 return 0; 131 const uint8_t *v;
112 } 132
113 *out = *v; 133 if (!cbs_get(cbs, &v, 1))
114 return 1; 134 return 0;
135
136 *out = *v;
137 return 1;
115} 138}
116 139
117int CBS_get_u16(CBS *cbs, uint16_t *out) { 140int
118 uint32_t v; 141CBS_get_u16(CBS *cbs, uint16_t *out)
119 if (!cbs_get_u(cbs, &v, 2)) { 142{
120 return 0; 143 uint32_t v;
121 } 144
122 *out = v; 145 if (!cbs_get_u(cbs, &v, 2))
123 return 1; 146 return 0;
147
148 *out = v;
149 return 1;
124} 150}
125 151
126int CBS_get_u24(CBS *cbs, uint32_t *out) { 152int
127 return cbs_get_u(cbs, out, 3); 153CBS_get_u24(CBS *cbs, uint32_t *out)
154{
155 return cbs_get_u(cbs, out, 3);
128} 156}
129 157
130int CBS_get_u32(CBS *cbs, uint32_t *out) { 158int
131 return cbs_get_u(cbs, out, 4); 159CBS_get_u32(CBS *cbs, uint32_t *out)
160{
161 return cbs_get_u(cbs, out, 4);
132} 162}
133 163
134int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) { 164int
135 const uint8_t *v; 165CBS_get_bytes(CBS *cbs, CBS *out, size_t len)
136 if (!cbs_get(cbs, &v, len)) { 166{
137 return 0; 167 const uint8_t *v;
138 } 168
139 CBS_init(out, v, len); 169 if (!cbs_get(cbs, &v, len))
140 return 1; 170 return 0;
171
172 CBS_init(out, v, len);
173 return 1;
141} 174}
142 175
143static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) { 176static int
144 uint32_t len; 177cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len)
145 if (!cbs_get_u(cbs, &len, len_len)) { 178{
146 return 0; 179 uint32_t len;
147 } 180
148 return CBS_get_bytes(cbs, out, len); 181 if (!cbs_get_u(cbs, &len, len_len))
182 return 0;
183
184 return CBS_get_bytes(cbs, out, len);
149} 185}
150 186
151int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) { 187int
152 return cbs_get_length_prefixed(cbs, out, 1); 188CBS_get_u8_length_prefixed(CBS *cbs, CBS *out)
189{
190 return cbs_get_length_prefixed(cbs, out, 1);
153} 191}
154 192
155int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) { 193int
156 return cbs_get_length_prefixed(cbs, out, 2); 194CBS_get_u16_length_prefixed(CBS *cbs, CBS *out)
195{
196 return cbs_get_length_prefixed(cbs, out, 2);
157} 197}
158 198
159int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) { 199int
160 return cbs_get_length_prefixed(cbs, out, 3); 200CBS_get_u24_length_prefixed(CBS *cbs, CBS *out)
201{
202 return cbs_get_length_prefixed(cbs, out, 3);
161} 203}
162 204
163int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, 205int
164 size_t *out_header_len) { 206CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
165 uint8_t tag, length_byte; 207 size_t *out_header_len)
166 CBS header = *cbs; 208{
167 CBS throwaway; 209 uint8_t tag, length_byte;
168 210 CBS header = *cbs;
169 if (out == NULL) { 211 CBS throwaway;
170 out = &throwaway; 212
171 } 213 if (out == NULL)
172 214 out = &throwaway;
173 if (!CBS_get_u8(&header, &tag) || 215
174 !CBS_get_u8(&header, &length_byte)) { 216 if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte))
175 return 0; 217 return 0;
176 } 218
177 219 if ((tag & 0x1f) == 0x1f)
178 if ((tag & 0x1f) == 0x1f) { 220 /* Long form tags are not supported. */
179 /* Long form tags are not supported. */ 221 return 0;
180 return 0; 222
181 } 223 if (out_tag != NULL)
182 224 *out_tag = tag;
183 if (out_tag != NULL) { 225
184 *out_tag = tag; 226 size_t len;
185 } 227 if ((length_byte & 0x80) == 0) {
186 228 /* Short form length. */
187 size_t len; 229 len = ((size_t) length_byte) + 2;
188 if ((length_byte & 0x80) == 0) { 230 if (out_header_len != NULL)
189 /* Short form length. */ 231 *out_header_len = 2;
190 len = ((size_t) length_byte) + 2; 232
191 if (out_header_len != NULL) { 233 } else {
192 *out_header_len = 2; 234 /* Long form length. */
193 } 235 const size_t num_bytes = length_byte & 0x7f;
194 } else { 236 uint32_t len32;
195 /* Long form length. */ 237
196 const size_t num_bytes = length_byte & 0x7f; 238 if ((tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) {
197 uint32_t len32; 239 /* indefinite length */
198 240 *out_header_len = 2;
199 if ((tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) { 241 return CBS_get_bytes(cbs, out, 2);
200 /* indefinite length */ 242 }
201 *out_header_len = 2; 243
202 return CBS_get_bytes(cbs, out, 2); 244 if (num_bytes == 0 || num_bytes > 4)
203 } 245 return 0;
204 246
205 if (num_bytes == 0 || num_bytes > 4) { 247 if (!cbs_get_u(&header, &len32, num_bytes))
206 return 0; 248 return 0;
207 } 249
208 if (!cbs_get_u(&header, &len32, num_bytes)) { 250 if (len32 < 128)
209 return 0; 251 /* Length should have used short-form encoding. */
210 } 252 return 0;
211 if (len32 < 128) { 253
212 /* Length should have used short-form encoding. */ 254 if ((len32 >> ((num_bytes-1)*8)) == 0)
213 return 0; 255 /* Length should have been at least one byte shorter. */
214 } 256 return 0;
215 if ((len32 >> ((num_bytes-1)*8)) == 0) { 257
216 /* Length should have been at least one byte shorter. */ 258 len = len32;
217 return 0; 259 if (len + 2 + num_bytes < len)
218 } 260 /* Overflow. */
219 len = len32; 261 return 0;
220 if (len + 2 + num_bytes < len) { 262
221 /* Overflow. */ 263 len += 2 + num_bytes;
222 return 0; 264 if (out_header_len != NULL)
223 } 265 *out_header_len = 2 + num_bytes;
224 len += 2 + num_bytes; 266 }
225 if (out_header_len != NULL) { 267
226 *out_header_len = 2 + num_bytes; 268 return CBS_get_bytes(cbs, out, len);
227 }
228 }
229
230 return CBS_get_bytes(cbs, out, len);
231} 269}
232 270
233static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, 271static int
234 int skip_header) { 272cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, int skip_header)
235 size_t header_len; 273{
236 unsigned tag; 274 size_t header_len;
237 CBS throwaway; 275 unsigned tag;
238 276 CBS throwaway;
239 if (out == NULL) { 277
240 out = &throwaway; 278 if (out == NULL)
241 } 279 out = &throwaway;
242 280
243 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) || 281 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
244 tag != tag_value || 282 tag != tag_value || (header_len > 0 &&
245 (header_len > 0 && 283 /*
246 /* This ensures that the tag is either zero length or 284 * This ensures that the tag is either zero length or
247 * indefinite-length. */ 285 * indefinite-length.
248 CBS_len(out) == header_len && 286 */
249 CBS_data(out)[header_len - 1] == 0x80)) { 287 CBS_len(out) == header_len &&
250 return 0; 288 CBS_data(out)[header_len - 1] == 0x80))
251 } 289 return 0;
252 290
253 if (skip_header && !CBS_skip(out, header_len)) { 291 if (skip_header && !CBS_skip(out, header_len)) {
254 assert(0); 292 assert(0);
255 return 0; 293 return 0;
256 } 294 }
257 295
258 return 1; 296 return 1;
259} 297}
260 298
261int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) { 299int
262 return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */); 300CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value)
301{
302 return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
263} 303}
264 304
265int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) { 305int
266 return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */); 306CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value)
307{
308 return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
267} 309}
268 310
269int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) { 311int
270 if (CBS_len(cbs) < 1) { 312CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value)
271 return 0; 313{
272 } 314 if (CBS_len(cbs) < 1)
273 return CBS_data(cbs)[0] == tag_value; 315 return 0;
316
317 return CBS_data(cbs)[0] == tag_value;
274} 318}
275 319
276int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) { 320int
277 CBS bytes; 321CBS_get_asn1_uint64(CBS *cbs, uint64_t *out)
278 const uint8_t *data; 322{
279 size_t i, len; 323 CBS bytes;
280 324 const uint8_t *data;
281 if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) { 325 size_t i, len;
282 return 0; 326
283 } 327 if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER))
284 328 return 0;
285 *out = 0; 329
286 data = CBS_data(&bytes); 330 *out = 0;
287 len = CBS_len(&bytes); 331 data = CBS_data(&bytes);
288 332 len = CBS_len(&bytes);
289 if (len == 0) { 333
290 /* An INTEGER is encoded with at least one octet. */ 334 if (len == 0)
291 return 0; 335 /* An INTEGER is encoded with at least one octet. */
292 } 336 return 0;
293 337
294 if ((data[0] & 0x80) != 0) { 338 if ((data[0] & 0x80) != 0)
295 /* negative number */ 339 /* negative number */
296 return 0; 340 return 0;
297 } 341
298 342 for (i = 0; i < len; i++) {
299 for (i = 0; i < len; i++) { 343 if ((*out >> 56) != 0)
300 if ((*out >> 56) != 0) { 344 /* Too large to represent as a uint64_t. */
301 /* Too large to represent as a uint64_t. */ 345 return 0;
302 return 0; 346
303 } 347 *out <<= 8;
304 *out <<= 8; 348 *out |= data[i];
305 *out |= data[i]; 349 }
306 } 350
307 351 return 1;
308 return 1;
309} 352}
310 353
311int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) { 354int
312 if (CBS_peek_asn1_tag(cbs, tag)) { 355CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag)
313 if (!CBS_get_asn1(cbs, out, tag)) { 356{
314 return 0; 357 if (CBS_peek_asn1_tag(cbs, tag)) {
315 } 358 if (!CBS_get_asn1(cbs, out, tag))
316 *out_present = 1; 359 return 0;
317 } else { 360
318 *out_present = 0; 361 *out_present = 1;
319 } 362 } else {
320 return 1; 363 *out_present = 0;
364 }
365 return 1;
321} 366}
322 367
323int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, 368int
324 unsigned tag) { 369CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
325 CBS child; 370 unsigned tag)
326 int present; 371{
327 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { 372 CBS child;
328 return 0; 373 int present;
329 } 374
330 if (present) { 375 if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
331 if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) || 376 return 0;
332 CBS_len(&child) != 0) { 377
333 return 0; 378 if (present) {
334 } 379 if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
335 } else { 380 CBS_len(&child) != 0)
336 CBS_init(out, NULL, 0); 381 return 0;
337 } 382 } else {
338 if (out_present) { 383 CBS_init(out, NULL, 0);
339 *out_present = present; 384 }
340 } 385 if (out_present)
341 return 1; 386 *out_present = present;
387
388 return 1;
342} 389}
343 390
344int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag, 391int
345 uint64_t default_value) { 392CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
346 CBS child; 393 uint64_t default_value)
347 int present; 394{
348 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { 395 CBS child;
349 return 0; 396 int present;
350 } 397
351 if (present) { 398 if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
352 if (!CBS_get_asn1_uint64(&child, out) || 399 return 0;
353 CBS_len(&child) != 0) { 400
354 return 0; 401 if (present) {
355 } 402 if (!CBS_get_asn1_uint64(&child, out) ||
356 } else { 403 CBS_len(&child) != 0)
357 *out = default_value; 404 return 0;
358 } 405 } else {
359 return 1; 406 *out = default_value;
407 }
408 return 1;
360} 409}
361 410
362int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, 411int
363 int default_value) { 412CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, int default_value)
364 CBS child, child2; 413{
365 int present; 414 CBS child, child2;
366 if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { 415 int present;
367 return 0; 416
368 } 417 if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
369 if (present) { 418 return 0;
370 uint8_t boolean; 419
371 420 if (present) {
372 if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) || 421 uint8_t boolean;
373 CBS_len(&child2) != 1 || 422
374 CBS_len(&child) != 0) { 423 if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
375 return 0; 424 CBS_len(&child2) != 1 || CBS_len(&child) != 0)
376 } 425 return 0;
377 426
378 boolean = CBS_data(&child2)[0]; 427 boolean = CBS_data(&child2)[0];
379 if (boolean == 0) { 428 if (boolean == 0)
380 *out = 0; 429 *out = 0;
381 } else if (boolean == 0xff) { 430 else if (boolean == 0xff)
382 *out = 1; 431 *out = 1;
383 } else { 432 else
384 return 0; 433 return 0;
385 } 434
386 } else { 435 } else {
387 *out = default_value; 436 *out = default_value;
388 } 437 }
389 return 1; 438 return 1;
390} 439}
diff --git a/src/lib/libssl/src/ssl/bytestring.h b/src/lib/libssl/src/ssl/bytestring.h
index 3c4e8eaaf3..09414af056 100644
--- a/src/lib/libssl/src/ssl/bytestring.h
+++ b/src/lib/libssl/src/ssl/bytestring.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: bytestring.h,v 1.1 2015/02/06 09:36:16 doug Exp $ */ 1/* $OpenBSD: bytestring.h,v 1.2 2015/02/06 22:22:33 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -26,96 +26,127 @@ extern "C" {
26 26
27#include <openssl/opensslconf.h> 27#include <openssl/opensslconf.h>
28 28
29/* Bytestrings are used for parsing and building TLS and ASN.1 messages. 29/*
30 * Bytestrings are used for parsing and building TLS and ASN.1 messages.
30 * 31 *
31 * A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and 32 * A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and
32 * provides utility functions for safely parsing length-prefixed structures 33 * provides utility functions for safely parsing length-prefixed structures
33 * like TLS and ASN.1 from it. 34 * like TLS and ASN.1 from it.
34 * 35 *
35 * A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and 36 * A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and
36 * provides utility functions for building length-prefixed messages. */ 37 * provides utility functions for building length-prefixed messages.
37 38 */
38 39
39/* CRYPTO ByteString */ 40/* CRYPTO ByteString */
40
41typedef struct cbs_st { 41typedef struct cbs_st {
42 const uint8_t *data; 42 const uint8_t *data;
43 size_t len; 43 size_t len;
44} CBS; 44} CBS;
45 45
46/* CBS_init sets |cbs| to point to |data|. It does not take ownership of 46/*
47 * |data|. */ 47 * CBS_init sets |cbs| to point to |data|. It does not take ownership of
48 * |data|.
49 */
48void CBS_init(CBS *cbs, const uint8_t *data, size_t len); 50void CBS_init(CBS *cbs, const uint8_t *data, size_t len);
49 51
50/* CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero 52/*
51 * otherwise. */ 53 * CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero
54 * otherwise.
55 */
52int CBS_skip(CBS *cbs, size_t len); 56int CBS_skip(CBS *cbs, size_t len);
53 57
54/* CBS_data returns a pointer to the contains of |cbs|. */ 58/*
59 * CBS_data returns a pointer to the contains of |cbs|.
60 */
55const uint8_t *CBS_data(const CBS *cbs); 61const uint8_t *CBS_data(const CBS *cbs);
56 62
57/* CBS_len returns the number of bytes remaining in |cbs|. */ 63/*
64 * CBS_len returns the number of bytes remaining in |cbs|.
65 */
58size_t CBS_len(const CBS *cbs); 66size_t CBS_len(const CBS *cbs);
59 67
60/* CBS_stow copies the current contents of |cbs| into |*out_ptr| and 68/*
69 * CBS_stow copies the current contents of |cbs| into |*out_ptr| and
61 * |*out_len|. If |*out_ptr| is not NULL, the contents are freed with 70 * |*out_len|. If |*out_ptr| is not NULL, the contents are freed with
62 * OPENSSL_free. It returns one on success and zero on allocation failure. On 71 * OPENSSL_free. It returns one on success and zero on allocation failure. On
63 * success, |*out_ptr| should be freed with OPENSSL_free. If |cbs| is empty, 72 * success, |*out_ptr| should be freed with OPENSSL_free. If |cbs| is empty,
64 * |*out_ptr| will be NULL. */ 73 * |*out_ptr| will be NULL.
74 */
65int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len); 75int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len);
66 76
67/* CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a 77/*
78 * CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a
68 * NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed 79 * NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed
69 * with OPENSSL_free. It returns one on success and zero on allocation 80 * with OPENSSL_free. It returns one on success and zero on allocation
70 * failure. On success, |*out_ptr| should be freed with OPENSSL_free. 81 * failure. On success, |*out_ptr| should be freed with OPENSSL_free.
71 * 82 *
72 * NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call 83 * NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call
73 * |CBS_contains_zero_byte(cbs)| to check for NUL bytes. */ 84 * |CBS_contains_zero_byte(cbs)| to check for NUL bytes.
85 */
74int CBS_strdup(const CBS *cbs, char **out_ptr); 86int CBS_strdup(const CBS *cbs, char **out_ptr);
75 87
76/* CBS_contains_zero_byte returns one if the current contents of |cbs| contains 88/*
77 * a NUL byte and zero otherwise. */ 89 * CBS_contains_zero_byte returns one if the current contents of |cbs| contains
90 * a NUL byte and zero otherwise.
91 */
78int CBS_contains_zero_byte(const CBS *cbs); 92int CBS_contains_zero_byte(const CBS *cbs);
79 93
80/* CBS_mem_equal compares the current contents of |cbs| with the |len| bytes 94/*
95 * CBS_mem_equal compares the current contents of |cbs| with the |len| bytes
81 * starting at |data|. If they're equal, it returns one, otherwise zero. If the 96 * starting at |data|. If they're equal, it returns one, otherwise zero. If the
82 * lengths match, it uses a constant-time comparison. */ 97 * lengths match, it uses a constant-time comparison.
83int CBS_mem_equal(const CBS *cbs, const uint8_t *data, 98 */
84 size_t len); 99int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len);
85 100
86/* CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It 101/*
87 * returns one on success and zero on error. */ 102 * CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It
103 * returns one on success and zero on error.
104 */
88int CBS_get_u8(CBS *cbs, uint8_t *out); 105int CBS_get_u8(CBS *cbs, uint8_t *out);
89 106
90/* CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and 107/*
91 * advances |cbs|. It returns one on success and zero on error. */ 108 * CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and
109 * advances |cbs|. It returns one on success and zero on error.
110 */
92int CBS_get_u16(CBS *cbs, uint16_t *out); 111int CBS_get_u16(CBS *cbs, uint16_t *out);
93 112
94/* CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and 113/*
95 * advances |cbs|. It returns one on success and zero on error. */ 114 * CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and
115 * advances |cbs|. It returns one on success and zero on error.
116 */
96int CBS_get_u24(CBS *cbs, uint32_t *out); 117int CBS_get_u24(CBS *cbs, uint32_t *out);
97 118
98/* CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs| 119/*
99 * and advances |cbs|. It returns one on success and zero on error. */ 120 * CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs|
121 * and advances |cbs|. It returns one on success and zero on error.
122 */
100int CBS_get_u32(CBS *cbs, uint32_t *out); 123int CBS_get_u32(CBS *cbs, uint32_t *out);
101 124
102/* CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances 125/*
103 * |cbs|. It returns one on success and zero on error. */ 126 * CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances
127 * |cbs|. It returns one on success and zero on error.
128 */
104int CBS_get_bytes(CBS *cbs, CBS *out, size_t len); 129int CBS_get_bytes(CBS *cbs, CBS *out, size_t len);
105 130
106/* CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit, 131/*
132 * CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit,
107 * length-prefixed value from |cbs| and advances |cbs| over it. It returns one 133 * length-prefixed value from |cbs| and advances |cbs| over it. It returns one
108 * on success and zero on error. */ 134 * on success and zero on error.
135 */
109int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out); 136int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out);
110 137
111/* CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit, 138/*
139 * CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit,
112 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It 140 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
113 * returns one on success and zero on error. */ 141 * returns one on success and zero on error.
142 */
114int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out); 143int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out);
115 144
116/* CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit, 145/*
146 * CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit,
117 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It 147 * big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It
118 * returns one on success and zero on error. */ 148 * returns one on success and zero on error.
149 */
119int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); 150int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
120 151
121 152
@@ -133,80 +164,95 @@ int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
133#define CBS_ASN1_CONSTRUCTED 0x20 164#define CBS_ASN1_CONSTRUCTED 0x20
134#define CBS_ASN1_CONTEXT_SPECIFIC 0x80 165#define CBS_ASN1_CONTEXT_SPECIFIC 0x80
135 166
136/* CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not 167/*
168 * CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not
137 * including tag and length bytes) and advances |cbs| over it. The ASN.1 169 * including tag and length bytes) and advances |cbs| over it. The ASN.1
138 * element must match |tag_value|. It returns one on success and zero 170 * element must match |tag_value|. It returns one on success and zero
139 * on error. 171 * on error.
140 * 172 *
141 * Tag numbers greater than 31 are not supported. */ 173 * Tag numbers greater than 31 are not supported.
174 */
142int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value); 175int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value);
143 176
144/* CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the 177/*
145 * ASN.1 header bytes too. */ 178 * CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the
179 * ASN.1 header bytes too.
180 */
146int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value); 181int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value);
147 182
148/* CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one 183/*
184 * CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one
149 * if the next ASN.1 element on |cbs| would have tag |tag_value|. If 185 * if the next ASN.1 element on |cbs| would have tag |tag_value|. If
150 * |cbs| is empty or the tag does not match, it returns zero. Note: if 186 * |cbs| is empty or the tag does not match, it returns zero. Note: if
151 * it returns one, CBS_get_asn1 may still fail if the rest of the 187 * it returns one, CBS_get_asn1 may still fail if the rest of the
152 * element is malformed. */ 188 * element is malformed.
189 */
153int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value); 190int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value);
154 191
155/* CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from 192/*
193 * CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
156 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to 194 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
157 * the tag number and |*out_header_len| to the length of the ASN.1 header. If 195 * the tag number and |*out_header_len| to the length of the ASN.1 header. If
158 * the element has indefinite length then |*out| will only contain the 196 * the element has indefinite length then |*out| will only contain the
159 * header. Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore 197 * header. Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore
160 * the value. 198 * the value.
161 * 199 *
162 * Tag numbers greater than 31 are not supported. */ 200 * Tag numbers greater than 31 are not supported.
163int CBS_get_any_asn1_element(CBS *cbs, CBS *out, 201 */
164 unsigned *out_tag, 202int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
165 size_t *out_header_len); 203 size_t *out_header_len);
166 204
167/* CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1| 205/*
206 * CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1|
168 * and sets |*out| to its value. It returns one on success and zero on error, 207 * and sets |*out| to its value. It returns one on success and zero on error,
169 * where error includes the integer being negative, or too large to represent 208 * where error includes the integer being negative, or too large to represent
170 * in 64 bits. */ 209 * in 64 bits.
210 */
171int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out); 211int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out);
172 212
173/* CBS_get_optional_asn1 gets an optional explicitly-tagged element 213/*
214 * CBS_get_optional_asn1 gets an optional explicitly-tagged element
174 * from |cbs| tagged with |tag| and sets |*out| to its contents. If 215 * from |cbs| tagged with |tag| and sets |*out| to its contents. If
175 * present, it sets |*out_present| to one, otherwise zero. It returns 216 * present, it sets |*out_present| to one, otherwise zero. It returns
176 * one on success, whether or not the element was present, and zero on 217 * one on success, whether or not the element was present, and zero on
177 * decode failure. */ 218 * decode failure.
178int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, 219 */
179 unsigned tag); 220int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag);
180 221
181/* CBS_get_optional_asn1_octet_string gets an optional 222/*
223 * CBS_get_optional_asn1_octet_string gets an optional
182 * explicitly-tagged OCTET STRING from |cbs|. If present, it sets 224 * explicitly-tagged OCTET STRING from |cbs|. If present, it sets
183 * |*out| to the string and |*out_present| to one. Otherwise, it sets 225 * |*out| to the string and |*out_present| to one. Otherwise, it sets
184 * |*out| to empty and |*out_present| to zero. |out_present| may be 226 * |*out| to empty and |*out_present| to zero. |out_present| may be
185 * NULL. It returns one on success, whether or not the element was 227 * NULL. It returns one on success, whether or not the element was
186 * present, and zero on decode failure. */ 228 * present, and zero on decode failure.
187int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, 229 */
188 int *out_present, 230int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
189 unsigned tag); 231 unsigned tag);
190 232
191/* CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged 233/*
234 * CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged
192 * INTEGER from |cbs|. If present, it sets |*out| to the 235 * INTEGER from |cbs|. If present, it sets |*out| to the
193 * value. Otherwise, it sets |*out| to |default_value|. It returns one 236 * value. Otherwise, it sets |*out| to |default_value|. It returns one
194 * on success, whether or not the element was present, and zero on 237 * on success, whether or not the element was present, and zero on
195 * decode failure. */ 238 * decode failure.
196int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, 239 */
197 unsigned tag, 240int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag,
198 uint64_t default_value); 241 uint64_t default_value);
199 242
200/* CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from 243/*
244 * CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from
201 * |cbs|. If present, it sets |*out| to either zero or one, based on the 245 * |cbs|. If present, it sets |*out| to either zero or one, based on the
202 * boolean. Otherwise, it sets |*out| to |default_value|. It returns one on 246 * boolean. Otherwise, it sets |*out| to |default_value|. It returns one on
203 * success, whether or not the element was present, and zero on decode 247 * success, whether or not the element was present, and zero on decode
204 * failure. */ 248 * failure.
249 */
205int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, 250int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
206 int default_value); 251 int default_value);
207 252
208 253
209/* CRYPTO ByteBuilder. 254/*
255 * CRYPTO ByteBuilder.
210 * 256 *
211 * |CBB| objects allow one to build length-prefixed serialisations. A |CBB| 257 * |CBB| objects allow one to build length-prefixed serialisations. A |CBB|
212 * object is associated with a buffer and new buffers are created with 258 * object is associated with a buffer and new buffers are created with
@@ -218,111 +264,162 @@ int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag,
218 * not be used again. 264 * not be used again.
219 * 265 *
220 * If one needs to force a length prefix to be written out because a |CBB| is 266 * If one needs to force a length prefix to be written out because a |CBB| is
221 * going out of scope, use |CBB_flush|. */ 267 * going out of scope, use |CBB_flush|.
268 */
222 269
223struct cbb_buffer_st { 270struct cbb_buffer_st {
224 uint8_t *buf; 271 uint8_t *buf;
225 size_t len; /* The number of valid bytes. */ 272
226 size_t cap; /* The size of buf. */ 273 /* The number of valid bytes. */
227 char can_resize; /* One iff |buf| is owned by this object. If not then |buf| 274 size_t len;
228 cannot be resized. */ 275
276 /* The size of buf. */
277 size_t cap;
278
279 /*
280 * One iff |buf| is owned by this object. If not then |buf| cannot be
281 * resized.
282 */
283 char can_resize;
229}; 284};
230 285
231typedef struct cbb_st { 286typedef struct cbb_st {
232 struct cbb_buffer_st *base; 287 struct cbb_buffer_st *base;
233 /* offset is the offset from the start of |base->buf| to the position of any 288
234 * pending length-prefix. */ 289 /*
235 size_t offset; 290 * offset is the offset from the start of |base->buf| to the position of any
236 /* child points to a child CBB if a length-prefix is pending. */ 291 * pending length-prefix.
237 struct cbb_st *child; 292 */
238 /* pending_len_len contains the number of bytes in a pending length-prefix, 293 size_t offset;
239 * or zero if no length-prefix is pending. */ 294
240 uint8_t pending_len_len; 295 /* child points to a child CBB if a length-prefix is pending. */
241 char pending_is_asn1; 296 struct cbb_st *child;
242 /* is_top_level is true iff this is a top-level |CBB| (as opposed to a child 297
243 * |CBB|). Top-level objects are valid arguments for |CBB_finish|. */ 298 /*
244 char is_top_level; 299 * pending_len_len contains the number of bytes in a pending length-prefix,
300 * or zero if no length-prefix is pending.
301 */
302 uint8_t pending_len_len;
303
304 char pending_is_asn1;
305
306 /*
307 * is_top_level is true iff this is a top-level |CBB| (as opposed to a child
308 * |CBB|). Top-level objects are valid arguments for |CBB_finish|.
309 */
310 char is_top_level;
245} CBB; 311} CBB;
246 312
247/* CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as 313/*
314 * CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as
248 * needed, the |initial_capacity| is just a hint. It returns one on success or 315 * needed, the |initial_capacity| is just a hint. It returns one on success or
249 * zero on error. */ 316 * zero on error.
317 */
250int CBB_init(CBB *cbb, size_t initial_capacity); 318int CBB_init(CBB *cbb, size_t initial_capacity);
251 319
252/* CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since 320/*
321 * CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since
253 * |buf| cannot grow, trying to write more than |len| bytes will cause CBB 322 * |buf| cannot grow, trying to write more than |len| bytes will cause CBB
254 * functions to fail. It returns one on success or zero on error. */ 323 * functions to fail. It returns one on success or zero on error.
324 */
255int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len); 325int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len);
256 326
257/* CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects 327/*
328 * CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects
258 * writing to the same buffer. This should be used in an error case where a 329 * writing to the same buffer. This should be used in an error case where a
259 * serialisation is abandoned. */ 330 * serialisation is abandoned.
331 */
260void CBB_cleanup(CBB *cbb); 332void CBB_cleanup(CBB *cbb);
261 333
262/* CBB_finish completes any pending length prefix and sets |*out_data| to a 334/*
335 * CBB_finish completes any pending length prefix and sets |*out_data| to a
263 * malloced buffer and |*out_len| to the length of that buffer. The caller 336 * malloced buffer and |*out_len| to the length of that buffer. The caller
264 * takes ownership of the buffer and, unless the buffer was fixed with 337 * takes ownership of the buffer and, unless the buffer was fixed with
265 * |CBB_init_fixed|, must call |OPENSSL_free| when done. 338 * |CBB_init_fixed|, must call |OPENSSL_free| when done.
266 * 339 *
267 * It can only be called on a "top level" |CBB|, i.e. one initialised with 340 * It can only be called on a "top level" |CBB|, i.e. one initialised with
268 * |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on 341 * |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on
269 * error. */ 342 * error.
343 */
270int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len); 344int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
271 345
272/* CBB_flush causes any pending length prefixes to be written out and any child 346/*
347 * CBB_flush causes any pending length prefixes to be written out and any child
273 * |CBB| objects of |cbb| to be invalidated. It returns one on success or zero 348 * |CBB| objects of |cbb| to be invalidated. It returns one on success or zero
274 * on error. */ 349 * on error.
350 */
275int CBB_flush(CBB *cbb); 351int CBB_flush(CBB *cbb);
276 352
277/* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The 353/*
354 * CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The
278 * data written to |*out_contents| will be prefixed in |cbb| with an 8-bit 355 * data written to |*out_contents| will be prefixed in |cbb| with an 8-bit
279 * length. It returns one on success or zero on error. */ 356 * length. It returns one on success or zero on error.
357 */
280int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents); 358int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents);
281 359
282/* CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|. 360/*
361 * CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|.
283 * The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit, 362 * The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit,
284 * big-endian length. It returns one on success or zero on error. */ 363 * big-endian length. It returns one on success or zero on error.
364 */
285int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents); 365int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents);
286 366
287/* CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|. 367/*
368 * CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|.
288 * The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit, 369 * The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit,
289 * big-endian length. It returns one on success or zero on error. */ 370 * big-endian length. It returns one on success or zero on error.
371 */
290int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents); 372int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
291 373
292/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an 374/*
375 * CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
293 * ASN.1 object can be written. The |tag| argument will be used as the tag for 376 * ASN.1 object can be written. The |tag| argument will be used as the tag for
294 * the object. It returns one on success or zero on error. */ 377 * the object. It returns one on success or zero on error.
378 */
295int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag); 379int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
296 380
297/* CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on 381/*
298 * success and zero otherwise. */ 382 * CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on
383 * success and zero otherwise.
384 */
299int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len); 385int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len);
300 386
301/* CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to 387/*
388 * CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to
302 * the beginning of that space. The caller must then write |len| bytes of 389 * the beginning of that space. The caller must then write |len| bytes of
303 * actual contents to |*out_data|. It returns one on success and zero 390 * actual contents to |*out_data|. It returns one on success and zero
304 * otherwise. */ 391 * otherwise.
392 */
305int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len); 393int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len);
306 394
307/* CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on 395/*
308 * success and zero otherwise. */ 396 * CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on
397 * success and zero otherwise.
398 */
309int CBB_add_u8(CBB *cbb, uint8_t value); 399int CBB_add_u8(CBB *cbb, uint8_t value);
310 400
311/* CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It 401/*
312 * returns one on success and zero otherwise. */ 402 * CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It
403 * returns one on success and zero otherwise.
404 */
313int CBB_add_u16(CBB *cbb, uint16_t value); 405int CBB_add_u16(CBB *cbb, uint16_t value);
314 406
315/* CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It 407/*
316 * returns one on success and zero otherwise. */ 408 * CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It
409 * returns one on success and zero otherwise.
410 */
317int CBB_add_u24(CBB *cbb, uint32_t value); 411int CBB_add_u24(CBB *cbb, uint32_t value);
318 412
319/* CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| 413/*
414 * CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1|
320 * and writes |value| in its contents. It returns one on success and zero on 415 * and writes |value| in its contents. It returns one on success and zero on
321 * error. */ 416 * error.
417 */
322int CBB_add_asn1_uint64(CBB *cbb, uint64_t value); 418int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
323 419
324#ifdef LIBRESSL_INTERNAL 420#ifdef LIBRESSL_INTERNAL
325/* CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds 421/*
422 * CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds
326 * indefinite-length elements then it attempts to convert the BER data to DER 423 * indefinite-length elements then it attempts to convert the BER data to DER
327 * and sets |*out| and |*out_length| to describe a malloced buffer containing 424 * and sets |*out| and |*out_length| to describe a malloced buffer containing
328 * the DER data. Additionally, |*in| will be advanced over the ASN.1 data. 425 * the DER data. Additionally, |*in| will be advanced over the ASN.1 data.
@@ -335,7 +432,8 @@ int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
335 * structure itself. However, this sufficies to handle the PKCS#7 and #12 output 432 * structure itself. However, this sufficies to handle the PKCS#7 and #12 output
336 * from NSS. 433 * from NSS.
337 * 434 *
338 * It returns one on success and zero otherwise. */ 435 * It returns one on success and zero otherwise.
436 */
339int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len); 437int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len);
340#endif /* LIBRESSL_INTERNAL */ 438#endif /* LIBRESSL_INTERNAL */
341 439