summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordoug <>2015-06-13 09:24:12 +0000
committerdoug <>2015-06-13 09:24:12 +0000
commit885a73ca83bdc02d64138bdfa717065346335fc9 (patch)
tree42faf58d35b37fb26ab03da179143b678c23e900 /src
parentfadd4ace92124dcbfa36fd97cb37e60b63a399fb (diff)
downloadopenbsd-885a73ca83bdc02d64138bdfa717065346335fc9.tar.gz
openbsd-885a73ca83bdc02d64138bdfa717065346335fc9.tar.bz2
openbsd-885a73ca83bdc02d64138bdfa717065346335fc9.zip
Split up the logic in CBB_flush to separately handle the lengths.
Also, add comments about assuming short-form. ok miod@, tweak + ok jsing@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libssl/bs_cbb.c53
-rw-r--r--src/lib/libssl/src/ssl/bs_cbb.c53
2 files changed, 64 insertions, 42 deletions
diff --git a/src/lib/libssl/bs_cbb.c b/src/lib/libssl/bs_cbb.c
index 904edb9fb1..e86bb926ab 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.10 2015/06/13 09:16:42 doug Exp $ */ 1/* $OpenBSD: bs_cbb.c,v 1.11 2015/06/13 09:24:12 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -194,40 +194,46 @@ CBB_flush(CBB *cbb)
194 194
195 if (cbb->pending_is_asn1) { 195 if (cbb->pending_is_asn1) {
196 /* 196 /*
197 * For ASN.1 we assume that we'll only need a single byte for 197 * For ASN.1, we assumed that we were using short form which
198 * the length. If that turned out to be incorrect, we have to 198 * only requires a single byte for the length octet.
199 * move the contents along in order to make space. 199 *
200 * If it turns out that we need long form, we have to move
201 * the contents along in order to make space for more length
202 * octets.
200 */ 203 */
201 size_t len_len; 204 size_t len_len = 1; /* total number of length octets */
202 uint8_t initial_length_byte; 205 uint8_t initial_length_byte;
203 206
207 /* We already wrote 1 byte for the length. */
204 assert (cbb->pending_len_len == 1); 208 assert (cbb->pending_len_len == 1);
205 209
206 if (len > 0xfffffffe) { 210 /* Check for long form */
207 /* Too large. */ 211 if (len > 0xfffffffe)
208 return 0; 212 return 0; /* 0xffffffff is reserved */
209 } else if (len > 0xffffff) { 213 else if (len > 0xffffff)
210 len_len = 5; 214 len_len = 5;
211 initial_length_byte = 0x80 | 4; 215 else if (len > 0xffff)
212 } else if (len > 0xffff) {
213 len_len = 4; 216 len_len = 4;
214 initial_length_byte = 0x80 | 3; 217 else if (len > 0xff)
215 } else if (len > 0xff) {
216 len_len = 3; 218 len_len = 3;
217 initial_length_byte = 0x80 | 2; 219 else if (len > 0x7f)
218 } else if (len > 0x7f) {
219 len_len = 2; 220 len_len = 2;
220 initial_length_byte = 0x80 | 1; 221
221 } else { 222 if (len_len == 1) {
222 len_len = 1; 223 /* For short form, the initial byte is the length. */
223 initial_length_byte = len; 224 initial_length_byte = len;
224 len = 0; 225 len = 0;
225 }
226 226
227 if (len_len != 1) { 227 } else {
228 /*
229 * For long form, the initial byte is the number of
230 * subsequent length octets (plus bit 8 set).
231 */
232 initial_length_byte = 0x80 | (len_len - 1);
233
228 /* 234 /*
229 * We need to move the contents along in order to make 235 * We need to move the contents along in order to make
230 * space. 236 * space for the long form length octets.
231 */ 237 */
232 size_t extra_bytes = len_len - 1; 238 size_t extra_bytes = len_len - 1;
233 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) 239 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes))
@@ -304,9 +310,14 @@ CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag)
304 if ((tag & 0x1f) == 0x1f) 310 if ((tag & 0x1f) == 0x1f)
305 return 0; 311 return 0;
306 312
313 /* Short-form identifier octet only needs a single byte */
307 if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag)) 314 if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag))
308 return 0; 315 return 0;
309 316
317 /*
318 * Add 1 byte to cover the short-form length octet case. If it turns
319 * out we need long-form, it will be extended later.
320 */
310 cbb->offset = cbb->base->len; 321 cbb->offset = cbb->base->len;
311 if (!CBB_add_u8(cbb, 0)) 322 if (!CBB_add_u8(cbb, 0))
312 return 0; 323 return 0;
diff --git a/src/lib/libssl/src/ssl/bs_cbb.c b/src/lib/libssl/src/ssl/bs_cbb.c
index 904edb9fb1..e86bb926ab 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.10 2015/06/13 09:16:42 doug Exp $ */ 1/* $OpenBSD: bs_cbb.c,v 1.11 2015/06/13 09:24:12 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -194,40 +194,46 @@ CBB_flush(CBB *cbb)
194 194
195 if (cbb->pending_is_asn1) { 195 if (cbb->pending_is_asn1) {
196 /* 196 /*
197 * For ASN.1 we assume that we'll only need a single byte for 197 * For ASN.1, we assumed that we were using short form which
198 * the length. If that turned out to be incorrect, we have to 198 * only requires a single byte for the length octet.
199 * move the contents along in order to make space. 199 *
200 * If it turns out that we need long form, we have to move
201 * the contents along in order to make space for more length
202 * octets.
200 */ 203 */
201 size_t len_len; 204 size_t len_len = 1; /* total number of length octets */
202 uint8_t initial_length_byte; 205 uint8_t initial_length_byte;
203 206
207 /* We already wrote 1 byte for the length. */
204 assert (cbb->pending_len_len == 1); 208 assert (cbb->pending_len_len == 1);
205 209
206 if (len > 0xfffffffe) { 210 /* Check for long form */
207 /* Too large. */ 211 if (len > 0xfffffffe)
208 return 0; 212 return 0; /* 0xffffffff is reserved */
209 } else if (len > 0xffffff) { 213 else if (len > 0xffffff)
210 len_len = 5; 214 len_len = 5;
211 initial_length_byte = 0x80 | 4; 215 else if (len > 0xffff)
212 } else if (len > 0xffff) {
213 len_len = 4; 216 len_len = 4;
214 initial_length_byte = 0x80 | 3; 217 else if (len > 0xff)
215 } else if (len > 0xff) {
216 len_len = 3; 218 len_len = 3;
217 initial_length_byte = 0x80 | 2; 219 else if (len > 0x7f)
218 } else if (len > 0x7f) {
219 len_len = 2; 220 len_len = 2;
220 initial_length_byte = 0x80 | 1; 221
221 } else { 222 if (len_len == 1) {
222 len_len = 1; 223 /* For short form, the initial byte is the length. */
223 initial_length_byte = len; 224 initial_length_byte = len;
224 len = 0; 225 len = 0;
225 }
226 226
227 if (len_len != 1) { 227 } else {
228 /*
229 * For long form, the initial byte is the number of
230 * subsequent length octets (plus bit 8 set).
231 */
232 initial_length_byte = 0x80 | (len_len - 1);
233
228 /* 234 /*
229 * We need to move the contents along in order to make 235 * We need to move the contents along in order to make
230 * space. 236 * space for the long form length octets.
231 */ 237 */
232 size_t extra_bytes = len_len - 1; 238 size_t extra_bytes = len_len - 1;
233 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) 239 if (!cbb_buffer_add(cbb->base, NULL, extra_bytes))
@@ -304,9 +310,14 @@ CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag)
304 if ((tag & 0x1f) == 0x1f) 310 if ((tag & 0x1f) == 0x1f)
305 return 0; 311 return 0;
306 312
313 /* Short-form identifier octet only needs a single byte */
307 if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag)) 314 if (!CBB_flush(cbb) || !CBB_add_u8(cbb, tag))
308 return 0; 315 return 0;
309 316
317 /*
318 * Add 1 byte to cover the short-form length octet case. If it turns
319 * out we need long-form, it will be extended later.
320 */
310 cbb->offset = cbb->base->len; 321 cbb->offset = cbb->base->len;
311 if (!CBB_add_u8(cbb, 0)) 322 if (!CBB_add_u8(cbb, 0))
312 return 0; 323 return 0;