summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordoug <>2015-02-06 22:22:33 +0000
committerdoug <>2015-02-06 22:22:33 +0000
commita0cb4a2b0a0d4d75a998e970846e9d9e9dc4432c (patch)
tree4f02f5662cb1e436913f8d4b52df36e1af9dccf1
parent62ba7b329e9291ffb7e77ed61c1d483b9dd6eef2 (diff)
downloadopenbsd-a0cb4a2b0a0d4d75a998e970846e9d9e9dc4432c.tar.gz
openbsd-a0cb4a2b0a0d4d75a998e970846e9d9e9dc4432c.tar.bz2
openbsd-a0cb4a2b0a0d4d75a998e970846e9d9e9dc4432c.zip
KNF bytestring files.
I checked that this doesn't change anything. Compiled with clang using -Wno-pointer-sign -g0 to reduce the differences. Only difference in the asm is due to assert(0) line number changes in bs_cbs.c and bs_cbb.c. miod is ok with the general process.
-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
-rw-r--r--src/regress/lib/libssl/bytestring/bytestringtest.c1178
9 files changed, 2788 insertions, 2398 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
diff --git a/src/regress/lib/libssl/bytestring/bytestringtest.c b/src/regress/lib/libssl/bytestring/bytestringtest.c
index 92e33c02e7..ba768e4bb0 100644
--- a/src/regress/lib/libssl/bytestring/bytestringtest.c
+++ b/src/regress/lib/libssl/bytestring/bytestringtest.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bytestringtest.c,v 1.1 2015/02/06 09:36:16 doug Exp $ */ 1/* $OpenBSD: bytestringtest.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 *
@@ -25,631 +25,645 @@
25/* This is from <openssl/base.h> in boringssl */ 25/* This is from <openssl/base.h> in boringssl */
26#define OPENSSL_U64(x) x##ULL 26#define OPENSSL_U64(x) x##ULL
27 27
28static int test_skip(void) { 28static int
29 static const uint8_t kData[] = {1, 2, 3}; 29test_skip(void)
30 CBS data; 30{
31 31 static const uint8_t kData[] = {1, 2, 3};
32 CBS_init(&data, kData, sizeof(kData)); 32 CBS data;
33 return CBS_len(&data) == 3 && 33
34 CBS_skip(&data, 1) && 34 CBS_init(&data, kData, sizeof(kData));
35 CBS_len(&data) == 2 && 35 return CBS_len(&data) == 3 &&
36 CBS_skip(&data, 2) && 36 CBS_skip(&data, 1) &&
37 CBS_len(&data) == 0 && 37 CBS_len(&data) == 2 &&
38 !CBS_skip(&data, 1); 38 CBS_skip(&data, 2) &&
39 CBS_len(&data) == 0 &&
40 !CBS_skip(&data, 1);
39} 41}
40 42
41static int test_get_u(void) { 43static int
42 static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 44test_get_u(void)
43 uint8_t u8; 45{
44 uint16_t u16; 46 static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
45 uint32_t u32; 47 uint8_t u8;
46 CBS data; 48 uint16_t u16;
47 49 uint32_t u32;
48 CBS_init(&data, kData, sizeof(kData)); 50 CBS data;
49 return CBS_get_u8(&data, &u8) && 51
50 u8 == 1 && 52 CBS_init(&data, kData, sizeof(kData));
51 CBS_get_u16(&data, &u16) && 53 return CBS_get_u8(&data, &u8) &&
52 u16 == 0x203 && 54 u8 == 1 &&
53 CBS_get_u24(&data, &u32) && 55 CBS_get_u16(&data, &u16) &&
54 u32 == 0x40506 && 56 u16 == 0x203 &&
55 CBS_get_u32(&data, &u32) && 57 CBS_get_u24(&data, &u32) &&
56 u32 == 0x708090a && 58 u32 == 0x40506 &&
57 !CBS_get_u8(&data, &u8); 59 CBS_get_u32(&data, &u32) &&
60 u32 == 0x708090a &&
61 !CBS_get_u8(&data, &u8);
58} 62}
59 63
60static int test_get_prefixed(void) { 64static int
61 static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1}; 65test_get_prefixed(void)
62 uint8_t u8; 66{
63 uint16_t u16; 67 static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1};
64 uint32_t u32; 68 uint8_t u8;
65 CBS data, prefixed; 69 uint16_t u16;
66 70 uint32_t u32;
67 CBS_init(&data, kData, sizeof(kData)); 71 CBS data, prefixed;
68 return CBS_get_u8_length_prefixed(&data, &prefixed) && 72
69 CBS_len(&prefixed) == 1 && 73 CBS_init(&data, kData, sizeof(kData));
70 CBS_get_u8(&prefixed, &u8) && 74 return CBS_get_u8_length_prefixed(&data, &prefixed) &&
71 u8 == 2 && 75 CBS_len(&prefixed) == 1 &&
72 CBS_get_u16_length_prefixed(&data, &prefixed) && 76 CBS_get_u8(&prefixed, &u8) &&
73 CBS_len(&prefixed) == 2 && 77 u8 == 2 &&
74 CBS_get_u16(&prefixed, &u16) && 78 CBS_get_u16_length_prefixed(&data, &prefixed) &&
75 u16 == 0x304 && 79 CBS_len(&prefixed) == 2 &&
76 CBS_get_u24_length_prefixed(&data, &prefixed) && 80 CBS_get_u16(&prefixed, &u16) &&
77 CBS_len(&prefixed) == 3 && 81 u16 == 0x304 &&
78 CBS_get_u24(&prefixed, &u32) && 82 CBS_get_u24_length_prefixed(&data, &prefixed) &&
79 u32 == 0x30201; 83 CBS_len(&prefixed) == 3 &&
84 CBS_get_u24(&prefixed, &u32) &&
85 u32 == 0x30201;
80} 86}
81 87
82static int test_get_prefixed_bad(void) { 88static int
83 static const uint8_t kData1[] = {2, 1}; 89test_get_prefixed_bad(void)
84 static const uint8_t kData2[] = {0, 2, 1}; 90{
85 static const uint8_t kData3[] = {0, 0, 2, 1}; 91 static const uint8_t kData1[] = {2, 1};
86 CBS data, prefixed; 92 static const uint8_t kData2[] = {0, 2, 1};
93 static const uint8_t kData3[] = {0, 0, 2, 1};
94 CBS data, prefixed;
87 95
88 CBS_init(&data, kData1, sizeof(kData1)); 96 CBS_init(&data, kData1, sizeof(kData1));
89 if (CBS_get_u8_length_prefixed(&data, &prefixed)) { 97 if (CBS_get_u8_length_prefixed(&data, &prefixed))
90 return 0; 98 return 0;
91 }
92 99
93 CBS_init(&data, kData2, sizeof(kData2)); 100 CBS_init(&data, kData2, sizeof(kData2));
94 if (CBS_get_u16_length_prefixed(&data, &prefixed)) { 101 if (CBS_get_u16_length_prefixed(&data, &prefixed))
95 return 0; 102 return 0;
96 }
97 103
98 CBS_init(&data, kData3, sizeof(kData3)); 104 CBS_init(&data, kData3, sizeof(kData3));
99 if (CBS_get_u24_length_prefixed(&data, &prefixed)) { 105 if (CBS_get_u24_length_prefixed(&data, &prefixed))
100 return 0; 106 return 0;
101 }
102 107
103 return 1; 108 return 1;
104} 109}
105 110
106static int test_get_asn1(void) { 111static int
107 static const uint8_t kData1[] = {0x30, 2, 1, 2}; 112test_get_asn1(void)
108 static const uint8_t kData2[] = {0x30, 3, 1, 2}; 113{
109 static const uint8_t kData3[] = {0x30, 0x80}; 114 static const uint8_t kData1[] = {0x30, 2, 1, 2};
110 static const uint8_t kData4[] = {0x30, 0x81, 1, 1}; 115 static const uint8_t kData2[] = {0x30, 3, 1, 2};
111 static const uint8_t kData5[] = {0x30, 0x82, 0, 1, 1}; 116 static const uint8_t kData3[] = {0x30, 0x80};
112 static const uint8_t kData6[] = {0xa1, 3, 0x4, 1, 1}; 117 static const uint8_t kData4[] = {0x30, 0x81, 1, 1};
113 static const uint8_t kData7[] = {0xa1, 3, 0x4, 2, 1}; 118 static const uint8_t kData5[] = {0x30, 0x82, 0, 1, 1};
114 static const uint8_t kData8[] = {0xa1, 3, 0x2, 1, 1}; 119 static const uint8_t kData6[] = {0xa1, 3, 0x4, 1, 1};
115 static const uint8_t kData9[] = {0xa1, 3, 0x2, 1, 0xff}; 120 static const uint8_t kData7[] = {0xa1, 3, 0x4, 2, 1};
116 121 static const uint8_t kData8[] = {0xa1, 3, 0x2, 1, 1};
117 CBS data, contents; 122 static const uint8_t kData9[] = {0xa1, 3, 0x2, 1, 0xff};
118 int present; 123
119 uint64_t value; 124 CBS data, contents;
120 125 int present;
121 CBS_init(&data, kData1, sizeof(kData1)); 126 uint64_t value;
122 if (CBS_peek_asn1_tag(&data, 0x1) || 127
123 !CBS_peek_asn1_tag(&data, 0x30)) { 128 CBS_init(&data, kData1, sizeof(kData1));
124 return 0; 129 if (CBS_peek_asn1_tag(&data, 0x1) || !CBS_peek_asn1_tag(&data, 0x30))
125 } 130 return 0;
126 if (!CBS_get_asn1(&data, &contents, 0x30) || 131
127 CBS_len(&contents) != 2 || 132 if (!CBS_get_asn1(&data, &contents, 0x30) ||
128 memcmp(CBS_data(&contents), "\x01\x02", 2) != 0) { 133 CBS_len(&contents) != 2 ||
129 return 0; 134 memcmp(CBS_data(&contents), "\x01\x02", 2) != 0)
130 } 135 return 0;
131 136
132 CBS_init(&data, kData2, sizeof(kData2)); 137 CBS_init(&data, kData2, sizeof(kData2));
133 /* data is truncated */ 138 /* data is truncated */
134 if (CBS_get_asn1(&data, &contents, 0x30)) { 139 if (CBS_get_asn1(&data, &contents, 0x30))
135 return 0; 140 return 0;
136 } 141
137 142 CBS_init(&data, kData3, sizeof(kData3));
138 CBS_init(&data, kData3, sizeof(kData3)); 143 /* zero byte length of length */
139 /* zero byte length of length */ 144 if (CBS_get_asn1(&data, &contents, 0x30))
140 if (CBS_get_asn1(&data, &contents, 0x30)) { 145 return 0;
141 return 0; 146
142 } 147 CBS_init(&data, kData4, sizeof(kData4));
143 148 /* long form mistakenly used. */
144 CBS_init(&data, kData4, sizeof(kData4)); 149 if (CBS_get_asn1(&data, &contents, 0x30))
145 /* long form mistakenly used. */ 150 return 0;
146 if (CBS_get_asn1(&data, &contents, 0x30)) { 151
147 return 0; 152 CBS_init(&data, kData5, sizeof(kData5));
148 } 153 /* length takes too many bytes. */
149 154 if (CBS_get_asn1(&data, &contents, 0x30))
150 CBS_init(&data, kData5, sizeof(kData5)); 155 return 0;
151 /* length takes too many bytes. */ 156
152 if (CBS_get_asn1(&data, &contents, 0x30)) { 157 CBS_init(&data, kData1, sizeof(kData1));
153 return 0; 158 /* wrong tag. */
154 } 159 if (CBS_get_asn1(&data, &contents, 0x31))
155 160 return 0;
156 CBS_init(&data, kData1, sizeof(kData1)); 161
157 /* wrong tag. */ 162 CBS_init(&data, NULL, 0);
158 if (CBS_get_asn1(&data, &contents, 0x31)) { 163 /* peek at empty data. */
159 return 0; 164 if (CBS_peek_asn1_tag(&data, 0x30))
160 } 165 return 0;
161 166
162 CBS_init(&data, NULL, 0); 167 CBS_init(&data, NULL, 0);
163 /* peek at empty data. */ 168 /* optional elements at empty data. */
164 if (CBS_peek_asn1_tag(&data, 0x30)) { 169 if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) ||
165 return 0; 170 present ||
166 } 171 !CBS_get_optional_asn1_octet_string(&data, &contents, &present,
167 172 0xa0) ||
168 CBS_init(&data, NULL, 0); 173 present ||
169 /* optional elements at empty data. */ 174 CBS_len(&contents) != 0 ||
170 if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) || 175 !CBS_get_optional_asn1_octet_string(&data, &contents, NULL, 0xa0) ||
171 present || 176 CBS_len(&contents) != 0 ||
172 !CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0) || 177 !CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) ||
173 present || 178 value != 42)
174 CBS_len(&contents) != 0 || 179 return 0;
175 !CBS_get_optional_asn1_octet_string(&data, &contents, NULL, 0xa0) || 180
176 CBS_len(&contents) != 0 || 181 CBS_init(&data, kData6, sizeof(kData6));
177 !CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) || 182 /* optional element. */
178 value != 42) { 183 if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) ||
179 return 0; 184 present ||
180 } 185 !CBS_get_optional_asn1(&data, &contents, &present, 0xa1) ||
181 186 !present ||
182 CBS_init(&data, kData6, sizeof(kData6)); 187 CBS_len(&contents) != 3 ||
183 /* optional element. */ 188 memcmp(CBS_data(&contents), "\x04\x01\x01", 3) != 0)
184 if (!CBS_get_optional_asn1(&data, &contents, &present, 0xa0) || 189 return 0;
185 present || 190
186 !CBS_get_optional_asn1(&data, &contents, &present, 0xa1) || 191 CBS_init(&data, kData6, sizeof(kData6));
187 !present || 192 /* optional octet string. */
188 CBS_len(&contents) != 3 || 193 if (!CBS_get_optional_asn1_octet_string(&data, &contents, &present,
189 memcmp(CBS_data(&contents), "\x04\x01\x01", 3) != 0) { 194 0xa0) ||
190 return 0; 195 present ||
191 } 196 CBS_len(&contents) != 0 ||
192 197 !CBS_get_optional_asn1_octet_string(&data, &contents, &present,
193 CBS_init(&data, kData6, sizeof(kData6)); 198 0xa1) ||
194 /* optional octet string. */ 199 !present ||
195 if (!CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa0) || 200 CBS_len(&contents) != 1 ||
196 present || 201 CBS_data(&contents)[0] != 1)
197 CBS_len(&contents) != 0 || 202 return 0;
198 !CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1) || 203
199 !present || 204 CBS_init(&data, kData7, sizeof(kData7));
200 CBS_len(&contents) != 1 || 205 /* invalid optional octet string. */
201 CBS_data(&contents)[0] != 1) { 206 if (CBS_get_optional_asn1_octet_string(&data, &contents, &present,
202 return 0; 207 0xa1))
203 } 208 return 0;
204 209
205 CBS_init(&data, kData7, sizeof(kData7)); 210 CBS_init(&data, kData8, sizeof(kData8));
206 /* invalid optional octet string. */ 211 /* optional octet string. */
207 if (CBS_get_optional_asn1_octet_string(&data, &contents, &present, 0xa1)) { 212 if (!CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) ||
208 return 0; 213 value != 42 ||
209 } 214 !CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42) ||
210 215 value != 1)
211 CBS_init(&data, kData8, sizeof(kData8)); 216 return 0;
212 /* optional octet string. */ 217
213 if (!CBS_get_optional_asn1_uint64(&data, &value, 0xa0, 42) || 218 CBS_init(&data, kData9, sizeof(kData9));
214 value != 42 || 219 /* invalid optional integer. */
215 !CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42) || 220 if (CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42))
216 value != 1) { 221 return 0;
217 return 0; 222
218 } 223 return 1;
219
220 CBS_init(&data, kData9, sizeof(kData9));
221 /* invalid optional integer. */
222 if (CBS_get_optional_asn1_uint64(&data, &value, 0xa1, 42)) {
223 return 0;
224 }
225
226 return 1;
227} 224}
228 225
229static int test_get_optional_asn1_bool(void) { 226static int
230 CBS data; 227test_get_optional_asn1_bool(void)
231 int val; 228{
232 229 CBS data;
233 static const uint8_t kTrue[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0xff}; 230 int val;
234 static const uint8_t kFalse[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x00}; 231
235 static const uint8_t kInvalid[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x01}; 232 static const uint8_t kTrue[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0xff};
236 233 static const uint8_t kFalse[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x00};
237 CBS_init(&data, NULL, 0); 234 static const uint8_t kInvalid[] = {0x0a, 3, CBS_ASN1_BOOLEAN, 1, 0x01};
238 val = 2; 235
239 if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) || 236 CBS_init(&data, NULL, 0);
240 val != 0) { 237 val = 2;
241 return 0; 238 if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) || val != 0)
242 } 239 return 0;
243 240
244 CBS_init(&data, kTrue, sizeof(kTrue)); 241 CBS_init(&data, kTrue, sizeof(kTrue));
245 val = 2; 242 val = 2;
246 if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) || 243 if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 0) || val != 1)
247 val != 1) { 244 return 0;
248 return 0; 245
249 } 246 CBS_init(&data, kFalse, sizeof(kFalse));
250 247 val = 2;
251 CBS_init(&data, kFalse, sizeof(kFalse)); 248 if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1) || val != 0)
252 val = 2; 249 return 0;
253 if (!CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1) || 250
254 val != 0) { 251 CBS_init(&data, kInvalid, sizeof(kInvalid));
255 return 0; 252 if (CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1))
256 } 253 return 0;
257 254
258 CBS_init(&data, kInvalid, sizeof(kInvalid)); 255 return 1;
259 if (CBS_get_optional_asn1_bool(&data, &val, 0x0a, 1)) {
260 return 0;
261 }
262
263 return 1;
264} 256}
265 257
266static int test_cbb_basic(void) { 258static int
267 static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8}; 259test_cbb_basic(void)
268 uint8_t *buf; 260{
269 size_t buf_len; 261 static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8};
270 int ok; 262 uint8_t *buf;
271 CBB cbb; 263 size_t buf_len;
272 264 int ok;
273 if (!CBB_init(&cbb, 100)) { 265 CBB cbb;
274 return 0; 266
275 } 267 if (!CBB_init(&cbb, 100))
276 CBB_cleanup(&cbb); 268 return 0;
277 269
278 if (!CBB_init(&cbb, 0) || 270 CBB_cleanup(&cbb);
279 !CBB_add_u8(&cbb, 1) || 271
280 !CBB_add_u16(&cbb, 0x203) || 272 if (!CBB_init(&cbb, 0) ||
281 !CBB_add_u24(&cbb, 0x40506) || 273 !CBB_add_u8(&cbb, 1) ||
282 !CBB_add_bytes(&cbb, (const uint8_t*) "\x07\x08", 2) || 274 !CBB_add_u16(&cbb, 0x203) ||
283 !CBB_finish(&cbb, &buf, &buf_len)) { 275 !CBB_add_u24(&cbb, 0x40506) ||
284 return 0; 276 !CBB_add_bytes(&cbb, (const uint8_t*) "\x07\x08", 2) ||
285 } 277 !CBB_finish(&cbb, &buf, &buf_len))
286 278 return 0;
287 ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0; 279
288 free(buf); 280 ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len)
289 return ok; 281 == 0;
282 free(buf);
283 return ok;
290} 284}
291 285
292static int test_cbb_fixed(void) { 286static int
293 CBB cbb; 287test_cbb_fixed(void)
294 uint8_t buf[1]; 288{
295 uint8_t *out_buf; 289 CBB cbb;
296 size_t out_size; 290 uint8_t buf[1];
297 291 uint8_t *out_buf;
298 if (!CBB_init_fixed(&cbb, NULL, 0) || 292 size_t out_size;
299 CBB_add_u8(&cbb, 1) || 293
300 !CBB_finish(&cbb, &out_buf, &out_size) || 294 if (!CBB_init_fixed(&cbb, NULL, 0) ||
301 out_buf != NULL || 295 CBB_add_u8(&cbb, 1) ||
302 out_size != 0) { 296 !CBB_finish(&cbb, &out_buf, &out_size) ||
303 return 0; 297 out_buf != NULL ||
304 } 298 out_size != 0)
305 299 return 0;
306 if (!CBB_init_fixed(&cbb, buf, 1) || 300
307 !CBB_add_u8(&cbb, 1) || 301 if (!CBB_init_fixed(&cbb, buf, 1) ||
308 CBB_add_u8(&cbb, 2) || 302 !CBB_add_u8(&cbb, 1) ||
309 !CBB_finish(&cbb, &out_buf, &out_size) || 303 CBB_add_u8(&cbb, 2) ||
310 out_buf != buf || 304 !CBB_finish(&cbb, &out_buf, &out_size) ||
311 out_size != 1 || 305 out_buf != buf ||
312 buf[0] != 1) { 306 out_size != 1 ||
313 return 0; 307 buf[0] != 1)
314 } 308 return 0;
315 309
316 return 1; 310 return 1;
317} 311}
318 312
319static int test_cbb_finish_child(void) { 313static int
320 CBB cbb, child; 314test_cbb_finish_child(void)
321 uint8_t *out_buf; 315{
322 size_t out_size; 316 CBB cbb, child;
323 317 uint8_t *out_buf;
324 if (!CBB_init(&cbb, 16) || 318 size_t out_size;
325 !CBB_add_u8_length_prefixed(&cbb, &child) || 319
326 CBB_finish(&child, &out_buf, &out_size) || 320 if (!CBB_init(&cbb, 16) ||
327 !CBB_finish(&cbb, &out_buf, &out_size) || 321 !CBB_add_u8_length_prefixed(&cbb, &child) ||
328 out_size != 1 || 322 CBB_finish(&child, &out_buf, &out_size) ||
329 out_buf[0] != 0) { 323 !CBB_finish(&cbb, &out_buf, &out_size) ||
330 return 0; 324 out_size != 1 ||
331 } 325 out_buf[0] != 0)
332 326 return 0;
333 free(out_buf); 327
334 return 1; 328 free(out_buf);
329 return 1;
335} 330}
336 331
337static int test_cbb_prefixed(void) { 332static int
338 static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3, 333test_cbb_prefixed(void)
339 4, 5, 6, 5, 4, 1, 0, 1, 2}; 334{
340 uint8_t *buf; 335 static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3,
341 size_t buf_len; 336 4, 5, 6, 5, 4, 1, 0, 1, 2};
342 CBB cbb, contents, inner_contents, inner_inner_contents; 337 uint8_t *buf;
343 int ok; 338 size_t buf_len;
344 339 CBB cbb, contents, inner_contents, inner_inner_contents;
345 if (!CBB_init(&cbb, 0) || 340 int ok;
346 !CBB_add_u8_length_prefixed(&cbb, &contents) || 341
347 !CBB_add_u8_length_prefixed(&cbb, &contents) || 342 if (!CBB_init(&cbb, 0) ||
348 !CBB_add_u8(&contents, 1) || 343 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
349 !CBB_add_u16_length_prefixed(&cbb, &contents) || 344 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
350 !CBB_add_u16(&contents, 0x203) || 345 !CBB_add_u8(&contents, 1) ||
351 !CBB_add_u24_length_prefixed(&cbb, &contents) || 346 !CBB_add_u16_length_prefixed(&cbb, &contents) ||
352 !CBB_add_u24(&contents, 0x40506) || 347 !CBB_add_u16(&contents, 0x203) ||
353 !CBB_add_u8_length_prefixed(&cbb, &contents) || 348 !CBB_add_u24_length_prefixed(&cbb, &contents) ||
354 !CBB_add_u8_length_prefixed(&contents, &inner_contents) || 349 !CBB_add_u24(&contents, 0x40506) ||
355 !CBB_add_u8(&inner_contents, 1) || 350 !CBB_add_u8_length_prefixed(&cbb, &contents) ||
356 !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) || 351 !CBB_add_u8_length_prefixed(&contents, &inner_contents) ||
357 !CBB_add_u8(&inner_inner_contents, 2) || 352 !CBB_add_u8(&inner_contents, 1) ||
358 !CBB_finish(&cbb, &buf, &buf_len)) { 353 !CBB_add_u16_length_prefixed(&inner_contents,
359 return 0; 354 &inner_inner_contents) ||
360 } 355 !CBB_add_u8(&inner_inner_contents, 2) ||
361 356 !CBB_finish(&cbb, &buf, &buf_len))
362 ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0; 357 return 0;
363 free(buf); 358
364 return ok; 359 ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len)
360 == 0;
361 free(buf);
362 return ok;
365} 363}
366 364
367static int test_cbb_misuse(void) { 365static int
368 CBB cbb, child, contents; 366test_cbb_misuse(void)
369 uint8_t *buf; 367{
370 size_t buf_len; 368 CBB cbb, child, contents;
371 369 uint8_t *buf;
372 if (!CBB_init(&cbb, 0) || 370 size_t buf_len;
373 !CBB_add_u8_length_prefixed(&cbb, &child) || 371
374 !CBB_add_u8(&child, 1) || 372 if (!CBB_init(&cbb, 0) ||
375 !CBB_add_u8(&cbb, 2)) { 373 !CBB_add_u8_length_prefixed(&cbb, &child) ||
376 return 0; 374 !CBB_add_u8(&child, 1) ||
377 } 375 !CBB_add_u8(&cbb, 2))
378 376 return 0;
379 /* Since we wrote to |cbb|, |child| is now invalid and attempts to write to 377
380 * it should fail. */ 378 /*
381 if (CBB_add_u8(&child, 1) || 379 * Since we wrote to |cbb|, |child| is now invalid and attempts to write
382 CBB_add_u16(&child, 1) || 380 * to it should fail.
383 CBB_add_u24(&child, 1) || 381 */
384 CBB_add_u8_length_prefixed(&child, &contents) || 382 if (CBB_add_u8(&child, 1) ||
385 CBB_add_u16_length_prefixed(&child, &contents) || 383 CBB_add_u16(&child, 1) ||
386 CBB_add_asn1(&child, &contents, 1) || 384 CBB_add_u24(&child, 1) ||
387 CBB_add_bytes(&child, (const uint8_t*) "a", 1)) { 385 CBB_add_u8_length_prefixed(&child, &contents) ||
388 fprintf(stderr, "CBB operation on invalid CBB did not fail.\n"); 386 CBB_add_u16_length_prefixed(&child, &contents) ||
389 return 0; 387 CBB_add_asn1(&child, &contents, 1) ||
390 } 388 CBB_add_bytes(&child, (const uint8_t*) "a", 1)) {
391 389 fprintf(stderr, "CBB operation on invalid CBB did not fail.\n");
392 if (!CBB_finish(&cbb, &buf, &buf_len) || 390 return 0;
393 buf_len != 3 || 391 }
394 memcmp(buf, "\x01\x01\x02", 3) != 0) { 392
395 return 0; 393 if (!CBB_finish(&cbb, &buf, &buf_len) || buf_len != 3 ||
396 } 394 memcmp(buf, "\x01\x01\x02", 3) != 0)
397 395 return 0;
398 free(buf); 396
399 397 free(buf);
400 return 1; 398
399 return 1;
401} 400}
402 401
403static int test_cbb_asn1(void) { 402static int
404 static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3}; 403test_cbb_asn1(void)
405 uint8_t *buf, *test_data; 404{
406 size_t buf_len; 405 static const uint8_t kExpected[] = {0x30, 3, 1, 2, 3};
407 CBB cbb, contents, inner_contents; 406 uint8_t *buf, *test_data;
408 407 size_t buf_len;
409 if (!CBB_init(&cbb, 0) || 408 CBB cbb, contents, inner_contents;
410 !CBB_add_asn1(&cbb, &contents, 0x30) || 409
411 !CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 3) || 410 if (!CBB_init(&cbb, 0) ||
412 !CBB_finish(&cbb, &buf, &buf_len)) { 411 !CBB_add_asn1(&cbb, &contents, 0x30) ||
413 return 0; 412 !CBB_add_bytes(&contents, (const uint8_t*) "\x01\x02\x03", 3) ||
414 } 413 !CBB_finish(&cbb, &buf, &buf_len))
415 414 return 0;
416 if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len) != 0) { 415
417 return 0; 416 if (buf_len != sizeof(kExpected) || memcmp(buf, kExpected, buf_len)
418 } 417 != 0)
419 free(buf); 418 return 0;
420 419
421 test_data = malloc(100000); 420 free(buf);
422 memset(test_data, 0x42, 100000); 421
423 422 test_data = malloc(100000);
424 if (!CBB_init(&cbb, 0) || 423 memset(test_data, 0x42, 100000);
425 !CBB_add_asn1(&cbb, &contents, 0x30) || 424
426 !CBB_add_bytes(&contents, test_data, 130) || 425 if (!CBB_init(&cbb, 0) ||
427 !CBB_finish(&cbb, &buf, &buf_len)) { 426 !CBB_add_asn1(&cbb, &contents, 0x30) ||
428 return 0; 427 !CBB_add_bytes(&contents, test_data, 130) ||
429 } 428 !CBB_finish(&cbb, &buf, &buf_len))
430 429 return 0;
431 if (buf_len != 3 + 130 || 430
432 memcmp(buf, "\x30\x81\x82", 3) != 0 || 431 if (buf_len != 3 + 130 ||
433 memcmp(buf + 3, test_data, 130) != 0) { 432 memcmp(buf, "\x30\x81\x82", 3) != 0 ||
434 return 0; 433 memcmp(buf + 3, test_data, 130) != 0) {
435 } 434 return 0;
436 free(buf); 435 }
437 436 free(buf);
438 if (!CBB_init(&cbb, 0) || 437
439 !CBB_add_asn1(&cbb, &contents, 0x30) || 438 if (!CBB_init(&cbb, 0) ||
440 !CBB_add_bytes(&contents, test_data, 1000) || 439 !CBB_add_asn1(&cbb, &contents, 0x30) ||
441 !CBB_finish(&cbb, &buf, &buf_len)) { 440 !CBB_add_bytes(&contents, test_data, 1000) ||
442 return 0; 441 !CBB_finish(&cbb, &buf, &buf_len))
443 } 442 return 0;
444 443
445 if (buf_len != 4 + 1000 || 444 if (buf_len != 4 + 1000 ||
446 memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 || 445 memcmp(buf, "\x30\x82\x03\xe8", 4) != 0 ||
447 memcmp(buf + 4, test_data, 1000)) { 446 memcmp(buf + 4, test_data, 1000)) {
448 return 0; 447 return 0;
449 } 448 }
450 free(buf); 449 free(buf);
451 450
452 if (!CBB_init(&cbb, 0) || 451 if (!CBB_init(&cbb, 0) ||
453 !CBB_add_asn1(&cbb, &contents, 0x30) || 452 !CBB_add_asn1(&cbb, &contents, 0x30) ||
454 !CBB_add_asn1(&contents, &inner_contents, 0x30) || 453 !CBB_add_asn1(&contents, &inner_contents, 0x30) ||
455 !CBB_add_bytes(&inner_contents, test_data, 100000) || 454 !CBB_add_bytes(&inner_contents, test_data, 100000) ||
456 !CBB_finish(&cbb, &buf, &buf_len)) { 455 !CBB_finish(&cbb, &buf, &buf_len))
457 return 0; 456 return 0;
458 } 457
459 458 if (buf_len != 5 + 5 + 100000 ||
460 if (buf_len != 5 + 5 + 100000 || 459 memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) != 0 ||
461 memcmp(buf, "\x30\x83\x01\x86\xa5\x30\x83\x01\x86\xa0", 10) != 0 || 460 memcmp(buf + 10, test_data, 100000))
462 memcmp(buf + 10, test_data, 100000)) { 461 return 0;
463 return 0; 462
464 } 463 free(buf);
465 free(buf); 464 free(test_data);
466 465
467 free(test_data); 466 return 1;
468 return 1;
469} 467}
470 468
471static int do_ber_convert(const char *name, 469static int
472 const uint8_t *der_expected, size_t der_len, 470do_ber_convert(const char *name, const uint8_t *der_expected, size_t der_len,
473 const uint8_t *ber, size_t ber_len) { 471 const uint8_t *ber, size_t ber_len)
474 CBS in; 472{
475 uint8_t *out; 473 CBS in;
476 size_t out_len; 474 uint8_t *out;
477 475 size_t out_len;
478 CBS_init(&in, ber, ber_len); 476
479 if (!CBS_asn1_ber_to_der(&in, &out, &out_len)) { 477 CBS_init(&in, ber, ber_len);
480 fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name); 478 if (!CBS_asn1_ber_to_der(&in, &out, &out_len)) {
481 return 0; 479 fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name);
482 } 480 return 0;
483 481 }
484 if (out == NULL) { 482
485 if (ber_len != der_len || 483 if (out == NULL) {
486 memcmp(der_expected, ber, ber_len) != 0) { 484 if (ber_len != der_len ||
487 fprintf(stderr, "%s: incorrect unconverted result.\n", name); 485 memcmp(der_expected, ber, ber_len) != 0) {
488 return 0; 486 fprintf(stderr, "%s: incorrect unconverted result.\n",
489 } 487 name);
490 488 return 0;
491 return 1; 489 }
492 } 490
493 491 return 1;
494 if (out_len != der_len || 492 }
495 memcmp(out, der_expected, der_len) != 0) { 493
496 fprintf(stderr, "%s: incorrect converted result.\n", name); 494 if (out_len != der_len || memcmp(out, der_expected, der_len) != 0) {
497 return 0; 495 fprintf(stderr, "%s: incorrect converted result.\n", name);
498 } 496 return 0;
499 497 }
500 free(out); 498
501 return 1; 499 free(out);
500 return 1;
502} 501}
503 502
504static int test_ber_convert(void) { 503static int
505 static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00}; 504test_ber_convert(void)
506 505{
507 /* kIndefBER contains a SEQUENCE with an indefinite length. */ 506 static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00};
508 static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00, 0x00}; 507
509 static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02}; 508 /* kIndefBER contains a SEQUENCE with an indefinite length. */
510 509 static const uint8_t kIndefBER[] = {0x30, 0x80, 0x01, 0x01, 0x02, 0x00,
511 /* kOctetStringBER contains an indefinite length OCTETSTRING with two parts. 510 0x00};
512 * These parts need to be concatenated in DER form. */ 511 static const uint8_t kIndefDER[] = {0x30, 0x03, 0x01, 0x01, 0x02};
513 static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0, 1, 512
514 0x04, 0x02, 2, 3, 0x00, 0x00}; 513 /*
515 static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3}; 514 * kOctetStringBER contains an indefinite length OCTETSTRING with two
516 515 * parts. These parts need to be concatenated in DER form.
517 /* kNSSBER is part of a PKCS#12 message generated by NSS that uses indefinite 516 */
518 * length elements extensively. */ 517 static const uint8_t kOctetStringBER[] = {0x24, 0x80, 0x04, 0x02, 0,
519 static const uint8_t kNSSBER[] = { 518 1, 0x04, 0x02, 2, 3, 0x00, 0x00};
520 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 519 static const uint8_t kOctetStringDER[] = {0x04, 0x04, 0, 1, 2, 3};
521 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x04, 520
522 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 521 /*
523 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 522 * kNSSBER is part of a PKCS#12 message generated by NSS that uses
524 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 523 * indefinite length elements extensively.
525 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 524 */
526 0x10, 0x38, 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 525 static const uint8_t kNSSBER[] = {
527 0xf0, 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00, 526 0x30, 0x80, 0x02, 0x01, 0x03, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86,
528 }; 527 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80,
529 528 0x04, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
530 static const uint8_t kNSSDER[] = { 529 0x00, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
531 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86, 530 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 0x98, 0xfc, 0x66,
532 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04, 531 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 0x8f, 0xfe, 0x1d,
533 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06, 532 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 0x62, 0xc6, 0x44,
534 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84, 533 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 0x6e, 0x10, 0x9b,
535 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8, 534 0xb8, 0x02, 0x02, 0x07, 0xd0, 0x00, 0x00,
536 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38, 535 };
537 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0, 536
538 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, 537 static const uint8_t kNSSDER[] = {
539 }; 538 0x30, 0x53, 0x02, 0x01, 0x03, 0x30, 0x13, 0x06, 0x09, 0x2a, 0x86,
540 539 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x06, 0x04, 0x04,
541 return do_ber_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER), 540 0x01, 0x02, 0x03, 0x04, 0x30, 0x39, 0x30, 0x21, 0x30, 0x09, 0x06,
542 kSimpleBER, sizeof(kSimpleBER)) && 541 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, 0x84,
543 do_ber_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER, 542 0x98, 0xfc, 0x66, 0x33, 0xee, 0xba, 0xe7, 0x90, 0xc1, 0xb6, 0xe8,
544 sizeof(kIndefBER)) && 543 0x8f, 0xfe, 0x1d, 0xc5, 0xa5, 0x97, 0x93, 0x3e, 0x04, 0x10, 0x38,
545 do_ber_convert("kOctetStringBER", kOctetStringDER, 544 0x62, 0xc6, 0x44, 0x12, 0xd5, 0x30, 0x00, 0xf8, 0xf2, 0x1b, 0xf0,
546 sizeof(kOctetStringDER), kOctetStringBER, 545 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0,
547 sizeof(kOctetStringBER)) && 546 };
548 do_ber_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER, 547
549 sizeof(kNSSBER)); 548 return do_ber_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER),
549 kSimpleBER, sizeof(kSimpleBER)) &&
550 do_ber_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER,
551 sizeof(kIndefBER)) &&
552 do_ber_convert("kOctetStringBER", kOctetStringDER,
553 sizeof(kOctetStringDER), kOctetStringBER,
554 sizeof(kOctetStringBER)) &&
555 do_ber_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER,
556 sizeof(kNSSBER));
550} 557}
551 558
552typedef struct { 559typedef struct {
553 uint64_t value; 560 uint64_t value;
554 const char *encoding; 561 const char *encoding;
555 size_t encoding_len; 562 size_t encoding_len;
556} ASN1_UINT64_TEST; 563} ASN1_UINT64_TEST;
557 564
558static const ASN1_UINT64_TEST kAsn1Uint64Tests[] = { 565static const ASN1_UINT64_TEST kAsn1Uint64Tests[] = {
559 {0, "\x02\x01\x00", 3}, 566 {0, "\x02\x01\x00", 3},
560 {1, "\x02\x01\x01", 3}, 567 {1, "\x02\x01\x01", 3},
561 {127, "\x02\x01\x7f", 3}, 568 {127, "\x02\x01\x7f", 3},
562 {128, "\x02\x02\x00\x80", 4}, 569 {128, "\x02\x02\x00\x80", 4},
563 {0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7}, 570 {0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7},
564 {OPENSSL_U64(0x0102030405060708), 571 {OPENSSL_U64(0x0102030405060708),
565 "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10}, 572 "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
566 {OPENSSL_U64(0xffffffffffffffff), 573 {OPENSSL_U64(0xffffffffffffffff),
567 "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11}, 574 "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
568}; 575};
569 576
570typedef struct { 577typedef struct {
571 const char *encoding; 578 const char *encoding;
572 size_t encoding_len; 579 size_t encoding_len;
573} ASN1_INVALID_UINT64_TEST; 580} ASN1_INVALID_UINT64_TEST;
574 581
575static const ASN1_INVALID_UINT64_TEST kAsn1InvalidUint64Tests[] = { 582static const ASN1_INVALID_UINT64_TEST kAsn1InvalidUint64Tests[] = {
576 /* Bad tag. */ 583 /* Bad tag. */
577 {"\x03\x01\x00", 3}, 584 {"\x03\x01\x00", 3},
578 /* Empty contents. */ 585 /* Empty contents. */
579 {"\x02\x00", 2}, 586 {"\x02\x00", 2},
580 /* Negative number. */ 587 /* Negative number. */
581 {"\x02\x01\x80", 3}, 588 {"\x02\x01\x80", 3},
582 /* Overflow */ 589 /* Overflow */
583 {"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11}, 590 {"\x02\x09\x01\x00\x00\x00\x00\x00\x00\x00\x00", 11},
584}; 591};
585 592
586static int test_asn1_uint64(void) { 593static int
587 size_t i; 594test_asn1_uint64(void)
588 595{
589 for (i = 0; i < sizeof(kAsn1Uint64Tests) / sizeof(kAsn1Uint64Tests[0]); i++) { 596 size_t i;
590 const ASN1_UINT64_TEST *test = &kAsn1Uint64Tests[i]; 597
591 CBS cbs; 598 for (i = 0; i < sizeof(kAsn1Uint64Tests) / sizeof(kAsn1Uint64Tests[0]);
592 uint64_t value; 599 i++) {
593 CBB cbb; 600 const ASN1_UINT64_TEST *test = &kAsn1Uint64Tests[i];
594 uint8_t *out; 601 CBS cbs;
595 size_t len; 602 uint64_t value;
596 603 CBB cbb;
597 CBS_init(&cbs, (const uint8_t *)test->encoding, test->encoding_len); 604 uint8_t *out;
598 if (!CBS_get_asn1_uint64(&cbs, &value) || 605 size_t len;
599 CBS_len(&cbs) != 0 || 606
600 value != test->value) { 607 CBS_init(&cbs, (const uint8_t *)test->encoding,
601 return 0; 608 test->encoding_len);
602 } 609
603 610 if (!CBS_get_asn1_uint64(&cbs, &value) ||
604 if (!CBB_init(&cbb, 0)) { 611 CBS_len(&cbs) != 0 ||
605 return 0; 612 value != test->value)
606 } 613 return 0;
607 if (!CBB_add_asn1_uint64(&cbb, test->value) || 614
608 !CBB_finish(&cbb, &out, &len)) { 615 if (!CBB_init(&cbb, 0))
609 CBB_cleanup(&cbb); 616 return 0;
610 return 0; 617
611 } 618 if (!CBB_add_asn1_uint64(&cbb, test->value) ||
612 if (len != test->encoding_len || memcmp(out, test->encoding, len) != 0) { 619 !CBB_finish(&cbb, &out, &len)) {
613 free(out); 620 CBB_cleanup(&cbb);
614 return 0; 621 return 0;
615 } 622 }
616 free(out); 623
617 } 624 if (len != test->encoding_len || memcmp(out, test->encoding,
618 625 len) != 0) {
619 for (i = 0; 626 free(out);
620 i < sizeof(kAsn1InvalidUint64Tests) / sizeof(kAsn1InvalidUint64Tests[0]); 627 return 0;
621 i++) { 628 }
622 const ASN1_INVALID_UINT64_TEST *test = &kAsn1InvalidUint64Tests[i]; 629 free(out);
623 CBS cbs; 630 }
624 uint64_t value; 631
625 632 for (i = 0; i < sizeof(kAsn1InvalidUint64Tests)
626 CBS_init(&cbs, (const uint8_t *)test->encoding, test->encoding_len); 633 / sizeof(kAsn1InvalidUint64Tests[0]); i++) {
627 if (CBS_get_asn1_uint64(&cbs, &value)) { 634 const ASN1_INVALID_UINT64_TEST *test =
628 return 0; 635 &kAsn1InvalidUint64Tests[i];
629 } 636 CBS cbs;
630 } 637 uint64_t value;
631 638
632 return 1; 639 CBS_init(&cbs, (const uint8_t *)test->encoding,
640 test->encoding_len);
641 if (CBS_get_asn1_uint64(&cbs, &value))
642 return 0;
643 }
644
645 return 1;
633} 646}
634 647
635int main(void) { 648int
636 if (!test_skip() || 649main(void)
637 !test_get_u() || 650{
638 !test_get_prefixed() || 651 if (!test_skip() ||
639 !test_get_prefixed_bad() || 652 !test_get_u() ||
640 !test_get_asn1() || 653 !test_get_prefixed() ||
641 !test_cbb_basic() || 654 !test_get_prefixed_bad() ||
642 !test_cbb_fixed() || 655 !test_get_asn1() ||
643 !test_cbb_finish_child() || 656 !test_cbb_basic() ||
644 !test_cbb_misuse() || 657 !test_cbb_fixed() ||
645 !test_cbb_prefixed() || 658 !test_cbb_finish_child() ||
646 !test_cbb_asn1() || 659 !test_cbb_misuse() ||
647 !test_ber_convert() || 660 !test_cbb_prefixed() ||
648 !test_asn1_uint64() || 661 !test_cbb_asn1() ||
649 !test_get_optional_asn1_bool()) { 662 !test_ber_convert() ||
650 return 1; 663 !test_asn1_uint64() ||
651 } 664 !test_get_optional_asn1_bool())
652 665 return 1;
653 printf("PASS\n"); 666
654 return 0; 667 printf("PASS\n");
668 return 0;
655} 669}