diff options
author | cvs2svn <admin@example.com> | 2015-03-08 16:48:49 +0000 |
---|---|---|
committer | cvs2svn <admin@example.com> | 2015-03-08 16:48:49 +0000 |
commit | decf84ba5550c1656a7fdb51b5b81969590c3f03 (patch) | |
tree | 44872802e872bdfd60730fa9cf01d9d5751251c1 /src/lib/libssl/bs_cbb.c | |
parent | 7a8f138352aa4eb7b65ac4b1a5fe7630fbee1427 (diff) | |
download | openbsd-libressl-v2.1.5.tar.gz openbsd-libressl-v2.1.5.tar.bz2 openbsd-libressl-v2.1.5.zip |
This commit was manufactured by cvs2git to create branch 'OPENBSD_5_7'.libressl-v2.1.5
Diffstat (limited to 'src/lib/libssl/bs_cbb.c')
-rw-r--r-- | src/lib/libssl/bs_cbb.c | 402 |
1 files changed, 0 insertions, 402 deletions
diff --git a/src/lib/libssl/bs_cbb.c b/src/lib/libssl/bs_cbb.c deleted file mode 100644 index 5546fac97f..0000000000 --- a/src/lib/libssl/bs_cbb.c +++ /dev/null | |||
@@ -1,402 +0,0 @@ | |||
1 | /* $OpenBSD: bs_cbb.c,v 1.5 2015/02/07 06:10:32 doug Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2014, Google Inc. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and/or distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
12 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
14 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
15 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ | ||
16 | |||
17 | #include <assert.h> | ||
18 | #include <stdlib.h> | ||
19 | #include <string.h> | ||
20 | |||
21 | #include <openssl/opensslconf.h> | ||
22 | |||
23 | #include "bytestring.h" | ||
24 | |||
25 | static int | ||
26 | cbb_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 | return 0; | ||
33 | |||
34 | base->buf = buf; | ||
35 | base->len = 0; | ||
36 | base->cap = cap; | ||
37 | base->can_resize = 1; | ||
38 | |||
39 | memset(cbb, 0, sizeof(CBB)); | ||
40 | cbb->base = base; | ||
41 | cbb->is_top_level = 1; | ||
42 | return 1; | ||
43 | } | ||
44 | |||
45 | int | ||
46 | CBB_init(CBB *cbb, size_t initial_capacity) | ||
47 | { | ||
48 | uint8_t *buf; | ||
49 | |||
50 | buf = malloc(initial_capacity); | ||
51 | if (initial_capacity > 0 && buf == NULL) | ||
52 | return 0; | ||
53 | |||
54 | if (!cbb_init(cbb, buf, initial_capacity)) { | ||
55 | free(buf); | ||
56 | return 0; | ||
57 | } | ||
58 | return 1; | ||
59 | } | ||
60 | |||
61 | int | ||
62 | CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) | ||
63 | { | ||
64 | if (!cbb_init(cbb, buf, len)) | ||
65 | return 0; | ||
66 | |||
67 | cbb->base->can_resize = 0; | ||
68 | return 1; | ||
69 | } | ||
70 | |||
71 | void | ||
72 | CBB_cleanup(CBB *cbb) | ||
73 | { | ||
74 | if (cbb->base) { | ||
75 | if (cbb->base->buf && cbb->base->can_resize) | ||
76 | free(cbb->base->buf); | ||
77 | |||
78 | free(cbb->base); | ||
79 | } | ||
80 | cbb->base = NULL; | ||
81 | } | ||
82 | |||
83 | static int | ||
84 | cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, size_t len) | ||
85 | { | ||
86 | size_t newlen; | ||
87 | |||
88 | if (base == NULL) | ||
89 | return 0; | ||
90 | |||
91 | newlen = base->len + len; | ||
92 | if (newlen < base->len) | ||
93 | /* Overflow */ | ||
94 | return 0; | ||
95 | |||
96 | if (newlen > base->cap) { | ||
97 | size_t newcap = base->cap * 2; | ||
98 | uint8_t *newbuf; | ||
99 | |||
100 | if (!base->can_resize) | ||
101 | return 0; | ||
102 | |||
103 | if (newcap < base->cap || newcap < newlen) | ||
104 | newcap = newlen; | ||
105 | |||
106 | newbuf = realloc(base->buf, newcap); | ||
107 | if (newbuf == NULL) | ||
108 | return 0; | ||
109 | |||
110 | base->buf = newbuf; | ||
111 | base->cap = newcap; | ||
112 | } | ||
113 | |||
114 | if (out) | ||
115 | *out = base->buf + base->len; | ||
116 | |||
117 | base->len = newlen; | ||
118 | return 1; | ||
119 | } | ||
120 | |||
121 | static int | ||
122 | cbb_buffer_add_u(struct cbb_buffer_st *base, uint32_t v, size_t len_len) | ||
123 | { | ||
124 | uint8_t *buf; | ||
125 | size_t i; | ||
126 | |||
127 | if (len_len == 0) | ||
128 | return 1; | ||
129 | |||
130 | if (!cbb_buffer_add(base, &buf, len_len)) | ||
131 | return 0; | ||
132 | |||
133 | for (i = len_len - 1; i < len_len; i--) { | ||
134 | buf[i] = v; | ||
135 | v >>= 8; | ||
136 | } | ||
137 | return 1; | ||
138 | } | ||
139 | |||
140 | int | ||
141 | CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) | ||
142 | { | ||
143 | if (!cbb->is_top_level) | ||
144 | return 0; | ||
145 | |||
146 | if (!CBB_flush(cbb)) | ||
147 | return 0; | ||
148 | |||
149 | if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) | ||
150 | /* | ||
151 | * |out_data| and |out_len| can only be NULL if the CBB is | ||
152 | * fixed. | ||
153 | */ | ||
154 | return 0; | ||
155 | |||
156 | if (out_data != NULL) | ||
157 | *out_data = cbb->base->buf; | ||
158 | |||
159 | if (out_len != NULL) | ||
160 | *out_len = cbb->base->len; | ||
161 | |||
162 | cbb->base->buf = NULL; | ||
163 | CBB_cleanup(cbb); | ||
164 | return 1; | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | * CBB_flush recurses and then writes out any pending length prefix. The current | ||
169 | * length of the underlying base is taken to be the length of the | ||
170 | * length-prefixed data. | ||
171 | */ | ||
172 | int | ||
173 | CBB_flush(CBB *cbb) | ||
174 | { | ||
175 | size_t child_start, i, len; | ||
176 | |||
177 | if (cbb->base == NULL) | ||
178 | return 0; | ||
179 | |||
180 | if (cbb->child == NULL || cbb->pending_len_len == 0) | ||
181 | return 1; | ||
182 | |||
183 | child_start = cbb->offset + cbb->pending_len_len; | ||
184 | |||
185 | if (!CBB_flush(cbb->child) || child_start < cbb->offset || | ||
186 | cbb->base->len < child_start) | ||
187 | return 0; | ||
188 | |||
189 | len = cbb->base->len - child_start; | ||
190 | |||
191 | if (cbb->pending_is_asn1) { | ||
192 | /* | ||
193 | * For ASN.1 we assume that we'll only need a single byte for | ||
194 | * the length. If that turned out to be incorrect, we have to | ||
195 | * move the contents along in order to make space. | ||
196 | */ | ||
197 | size_t len_len; | ||
198 | uint8_t initial_length_byte; | ||
199 | |||
200 | assert (cbb->pending_len_len == 1); | ||
201 | |||
202 | if (len > 0xfffffffe) { | ||
203 | /* Too large. */ | ||
204 | return 0; | ||
205 | } else if (len > 0xffffff) { | ||
206 | len_len = 5; | ||
207 | initial_length_byte = 0x80 | 4; | ||
208 | } else if (len > 0xffff) { | ||
209 | len_len = 4; | ||
210 | initial_length_byte = 0x80 | 3; | ||
211 | } else if (len > 0xff) { | ||
212 | len_len = 3; | ||
213 | initial_length_byte = 0x80 | 2; | ||
214 | } else if (len > 0x7f) { | ||
215 | len_len = 2; | ||
216 | initial_length_byte = 0x80 | 1; | ||
217 | } else { | ||
218 | len_len = 1; | ||
219 | initial_length_byte = len; | ||
220 | len = 0; | ||
221 | } | ||
222 | |||
223 | if (len_len != 1) { | ||
224 | /* | ||
225 | * We need to move the contents along in order to make | ||
226 | * space. | ||
227 | */ | ||
228 | size_t extra_bytes = len_len - 1; | ||
229 | if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) | ||
230 | return 0; | ||
231 | |||
232 | memmove(cbb->base->buf + child_start + extra_bytes, | ||
233 | cbb->base->buf + child_start, len); | ||
234 | } | ||
235 | cbb->base->buf[cbb->offset++] = initial_length_byte; | ||
236 | cbb->pending_len_len = len_len - 1; | ||
237 | } | ||
238 | |||
239 | for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) { | ||
240 | cbb->base->buf[cbb->offset + i] = len; | ||
241 | len >>= 8; | ||
242 | } | ||
243 | if (len != 0) | ||
244 | return 0; | ||
245 | |||
246 | cbb->child->base = NULL; | ||
247 | cbb->child = NULL; | ||
248 | cbb->pending_len_len = 0; | ||
249 | cbb->pending_is_asn1 = 0; | ||
250 | cbb->offset = 0; | ||
251 | |||
252 | return 1; | ||
253 | } | ||
254 | |||
255 | |||
256 | static int | ||
257 | cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, size_t len_len) | ||
258 | { | ||
259 | uint8_t *prefix_bytes; | ||
260 | |||
261 | if (!CBB_flush(cbb)) | ||
262 | return 0; | ||
263 | |||
264 | cbb->offset = cbb->base->len; | ||
265 | if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) | ||
266 | return 0; | ||
267 | |||
268 | memset(prefix_bytes, 0, len_len); | ||
269 | memset(out_contents, 0, sizeof(CBB)); | ||
270 | out_contents->base = cbb->base; | ||
271 | cbb->child = out_contents; | ||
272 | cbb->pending_len_len = len_len; | ||
273 | cbb->pending_is_asn1 = 0; | ||
274 | |||
275 | return 1; | ||
276 | } | ||
277 | |||
278 | int | ||
279 | CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) | ||
280 | { | ||
281 | return cbb_add_length_prefixed(cbb, out_contents, 1); | ||
282 | } | ||
283 | |||
284 | int | ||
285 | CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) | ||
286 | { | ||
287 | return cbb_add_length_prefixed(cbb, out_contents, 2); | ||
288 | } | ||
289 | |||
290 | int | ||
291 | CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) | ||
292 | { | ||
293 | return cbb_add_length_prefixed(cbb, out_contents, 3); | ||
294 | } | ||
295 | |||
296 | int | ||
297 | CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) | ||
298 | { | ||
299 | /* Long form identifier octets are not supported. */ | ||
300 | if ((tag & 0x1f) == 0x1f) | ||
301 | return 0; | ||
302 | |||
303 | if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag)) | ||
304 | return 0; | ||
305 | |||
306 | cbb->offset = cbb->base->len; | ||
307 | if (!CBB_add_u8(cbb, 0)) | ||
308 | return 0; | ||
309 | |||
310 | memset(out_contents, 0, sizeof(CBB)); | ||
311 | out_contents->base = cbb->base; | ||
312 | cbb->child = out_contents; | ||
313 | cbb->pending_len_len = 1; | ||
314 | cbb->pending_is_asn1 = 1; | ||
315 | |||
316 | return 1; | ||
317 | } | ||
318 | |||
319 | int | ||
320 | CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) | ||
321 | { | ||
322 | uint8_t *dest; | ||
323 | |||
324 | if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, &dest, len)) | ||
325 | return 0; | ||
326 | |||
327 | memcpy(dest, data, len); | ||
328 | return 1; | ||
329 | } | ||
330 | |||
331 | int | ||
332 | CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) | ||
333 | { | ||
334 | if (!CBB_flush(cbb) || !cbb_buffer_add(cbb->base, out_data, len)) | ||
335 | return 0; | ||
336 | |||
337 | return 1; | ||
338 | } | ||
339 | |||
340 | int | ||
341 | CBB_add_u8(CBB *cbb, uint8_t value) | ||
342 | { | ||
343 | if (!CBB_flush(cbb)) | ||
344 | return 0; | ||
345 | |||
346 | return cbb_buffer_add_u(cbb->base, value, 1); | ||
347 | } | ||
348 | |||
349 | int | ||
350 | CBB_add_u16(CBB *cbb, uint16_t value) | ||
351 | { | ||
352 | if (!CBB_flush(cbb)) | ||
353 | return 0; | ||
354 | |||
355 | return cbb_buffer_add_u(cbb->base, value, 2); | ||
356 | } | ||
357 | |||
358 | int | ||
359 | CBB_add_u24(CBB *cbb, uint32_t value) | ||
360 | { | ||
361 | if (!CBB_flush(cbb)) | ||
362 | return 0; | ||
363 | |||
364 | return cbb_buffer_add_u(cbb->base, value, 3); | ||
365 | } | ||
366 | |||
367 | int | ||
368 | CBB_add_asn1_uint64(CBB *cbb, uint64_t value) | ||
369 | { | ||
370 | CBB child; | ||
371 | size_t i; | ||
372 | int started = 0; | ||
373 | |||
374 | if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) | ||
375 | return 0; | ||
376 | |||
377 | for (i = 0; i < 8; i++) { | ||
378 | uint8_t byte = (value >> 8*(7-i)) & 0xff; | ||
379 | if (!started) { | ||
380 | if (byte == 0) | ||
381 | /* Don't encode leading zeros. */ | ||
382 | continue; | ||
383 | |||
384 | /* | ||
385 | * If the high bit is set, add a padding byte to make it | ||
386 | * unsigned. | ||
387 | */ | ||
388 | if ((byte & 0x80) && !CBB_add_u8(&child, 0)) | ||
389 | return 0; | ||
390 | |||
391 | started = 1; | ||
392 | } | ||
393 | if (!CBB_add_u8(&child, byte)) | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | /* 0 is encoded as a single 0, not the empty string. */ | ||
398 | if (!started && !CBB_add_u8(&child, 0)) | ||
399 | return 0; | ||
400 | |||
401 | return CBB_flush(cbb); | ||
402 | } | ||