summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordoug <>2015-06-15 07:35:49 +0000
committerdoug <>2015-06-15 07:35:49 +0000
commitcc28fbde97d652fc8df85aef456db3f43ee7141f (patch)
treed870273c7da5901692fed25ce0bccf96a3a77d50
parentb5c7960f11d2b64faae5154f9709f34d00462124 (diff)
downloadopenbsd-cc28fbde97d652fc8df85aef456db3f43ee7141f.tar.gz
openbsd-cc28fbde97d652fc8df85aef456db3f43ee7141f.tar.bz2
openbsd-cc28fbde97d652fc8df85aef456db3f43ee7141f.zip
Make CBS_get_any_asn1_element() more compliant with DER encoding.
CBS_get_any_asn1_element violates DER encoding by allowing indefinite form. All callers except bs_ber.c expect DER encoding. The callers must check to see if it was indefinite or not. Rather than exposing all callers to this behavior, cbs_get_any_asn1_element_internal() allows specifying whether you want to allow the normally forbidden indefinite form. This is used by CBS_get_any_asn1_element() for strict DER encoding and by a new static function in bs_ber.c for the relaxed version. While I was here, I added comments to differentiate between ASN.1 restrictions and CBS limitations. ok miod@
-rw-r--r--src/lib/libssl/bs_ber.c26
-rw-r--r--src/lib/libssl/bs_cbs.c68
-rw-r--r--src/lib/libssl/bytestring.h20
-rw-r--r--src/lib/libssl/src/ssl/bs_ber.c26
-rw-r--r--src/lib/libssl/src/ssl/bs_cbs.c68
-rw-r--r--src/lib/libssl/src/ssl/bytestring.h20
6 files changed, 172 insertions, 56 deletions
diff --git a/src/lib/libssl/bs_ber.c b/src/lib/libssl/bs_ber.c
index 2ec91fc800..3d39def111 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.4 2015/04/29 02:11:09 doug Exp $ */ 1/* $OpenBSD: bs_ber.c,v 1.5 2015/06/15 07:35:49 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -27,6 +27,15 @@
27 */ 27 */
28static const unsigned kMaxDepth = 2048; 28static const unsigned kMaxDepth = 2048;
29 29
30/* Non-strict version that allows a relaxed DER with indefinite form. */
31static int
32cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
33 size_t *out_header_len)
34{
35 return cbs_get_any_asn1_element_internal(cbs, out,
36 out_tag, out_header_len, 0);
37}
38
30/* 39/*
31 * cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found| 40 * cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found|
32 * depending on whether an indefinite length element was found. The value of 41 * depending on whether an indefinite length element was found. The value of
@@ -49,10 +58,11 @@ cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth)
49 unsigned tag; 58 unsigned tag;
50 size_t header_len; 59 size_t header_len;
51 60
52 if (!CBS_get_any_asn1_element(&in, &contents, &tag, 61 if (!cbs_nonstrict_get_any_asn1_element(&in, &contents, &tag,
53 &header_len)) 62 &header_len))
54 return 0; 63 return 0;
55 64
65 /* Indefinite form not allowed by DER. */
56 if (CBS_len(&contents) == header_len && header_len > 0 && 66 if (CBS_len(&contents) == header_len && header_len > 0 &&
57 CBS_data(&contents)[header_len - 1] == 0x80) { 67 CBS_data(&contents)[header_len - 1] == 0x80) {
58 *ber_found = 1; 68 *ber_found = 1;
@@ -84,7 +94,8 @@ is_primitive_type(unsigned tag)
84 94
85/* 95/*
86 * is_eoc returns true if |header_len| and |contents|, as returned by 96 * is_eoc returns true if |header_len| and |contents|, as returned by
87 * |CBS_get_any_asn1_element|, indicate an "end of contents" (EOC) value. 97 * |cbs_nonstrict_get_any_asn1_element|, indicate an "end of contents" (EOC)
98 * value.
88 */ 99 */
89static char 100static char
90is_eoc(size_t header_len, CBS *contents) 101is_eoc(size_t header_len, CBS *contents)
@@ -113,7 +124,8 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc,
113 size_t header_len; 124 size_t header_len;
114 CBB *out_contents, out_contents_storage; 125 CBB *out_contents, out_contents_storage;
115 126
116 if (!CBS_get_any_asn1_element(in, &contents, &tag, &header_len)) 127 if (!cbs_nonstrict_get_any_asn1_element(in, &contents, &tag,
128 &header_len))
117 return 0; 129 return 0;
118 130
119 out_contents = out; 131 out_contents = out;
@@ -156,9 +168,9 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc,
156 168
157 CBS_init(&in_copy, CBS_data(in), 169 CBS_init(&in_copy, CBS_data(in),
158 CBS_len(in)); 170 CBS_len(in));
159 if (!CBS_get_any_asn1_element(&in_copy, 171 if (!cbs_nonstrict_get_any_asn1_element(
160 &inner_contents, &inner_tag, 172 &in_copy, &inner_contents,
161 &inner_header_len)) 173 &inner_tag, &inner_header_len))
162 return 0; 174 return 0;
163 175
164 if (CBS_len(&inner_contents) > 176 if (CBS_len(&inner_contents) >
diff --git a/src/lib/libssl/bs_cbs.c b/src/lib/libssl/bs_cbs.c
index c37f81dd60..ba38303c18 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.8 2015/06/13 08:46:00 doug Exp $ */ 1/* $OpenBSD: bs_cbs.c,v 1.9 2015/06/15 07:35:49 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -205,24 +205,45 @@ int
205CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, 205CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
206 size_t *out_header_len) 206 size_t *out_header_len)
207{ 207{
208 return cbs_get_any_asn1_element_internal(cbs, out, out_tag,
209 out_header_len, 1);
210}
211
212/*
213 * Review X.690 for details on ASN.1 DER encoding.
214 *
215 * If non-strict mode is enabled, then DER rules are relaxed
216 * for indefinite constructs (violates DER but a little closer to BER).
217 * Non-strict mode should only be used by bs_ber.c
218 *
219 * Sections 8, 10 and 11 for DER encoding
220 */
221int
222cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned *out_tag,
223 size_t *out_header_len, int strict)
224{
208 uint8_t tag, length_byte; 225 uint8_t tag, length_byte;
209 CBS header = *cbs; 226 CBS header = *cbs;
210 CBS throwaway; 227 CBS throwaway;
228 size_t len;
211 229
212 if (out == NULL) 230 if (out == NULL)
213 out = &throwaway; 231 out = &throwaway;
214 232
233 /*
234 * Get identifier octet and length octet. Only 1 octet for each
235 * is a CBS limitation.
236 */
215 if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte)) 237 if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte))
216 return 0; 238 return 0;
217 239
240 /* CBS limitation: long form tags are not supported. */
218 if ((tag & 0x1f) == 0x1f) 241 if ((tag & 0x1f) == 0x1f)
219 /* Long form tags are not supported. */
220 return 0; 242 return 0;
221 243
222 if (out_tag != NULL) 244 if (out_tag != NULL)
223 *out_tag = tag; 245 *out_tag = tag;
224 246
225 size_t len;
226 if ((length_byte & 0x80) == 0) { 247 if ((length_byte & 0x80) == 0) {
227 /* Short form length. */ 248 /* Short form length. */
228 len = ((size_t) length_byte) + 2; 249 len = ((size_t) length_byte) + 2;
@@ -234,21 +255,40 @@ CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
234 const size_t num_bytes = length_byte & 0x7f; 255 const size_t num_bytes = length_byte & 0x7f;
235 uint32_t len32; 256 uint32_t len32;
236 257
237 if ((tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) { 258 /* ASN.1 reserved value for future extensions */
238 /* indefinite length */ 259 if (num_bytes == 0x7f)
239 if (out_header_len != NULL) 260 return 0;
240 *out_header_len = 2; 261
241 return CBS_get_bytes(cbs, out, 2); 262 /* Handle indefinite form length */
263 if (num_bytes == 0) {
264 /* DER encoding doesn't allow for indefinite form. */
265 if (strict) {
266 return 0;
267
268 } else {
269 if ((tag & CBS_ASN1_CONSTRUCTED) != 0 &&
270 num_bytes == 0) {
271 /* indefinite length */
272 if (out_header_len != NULL)
273 *out_header_len = 2;
274 return CBS_get_bytes(cbs, out, 2);
275 } else {
276 /* Primitive cannot use indefinite. */
277 return 0;
278 }
279 }
242 } 280 }
243 281
244 if (num_bytes == 0 || num_bytes > 4) 282 /* CBS limitation. */
283 if (num_bytes > 4)
245 return 0; 284 return 0;
246 285
247 if (!cbs_get_u(&header, &len32, num_bytes)) 286 if (!cbs_get_u(&header, &len32, num_bytes))
248 return 0; 287 return 0;
249 288
289 /* DER has a minimum length octet requirements. */
250 if (len32 < 128) 290 if (len32 < 128)
251 /* Length should have used short-form encoding. */ 291 /* Should have used short form instead */
252 return 0; 292 return 0;
253 293
254 if ((len32 >> ((num_bytes - 1) * 8)) == 0) 294 if ((len32 >> ((num_bytes - 1) * 8)) == 0)
@@ -279,13 +319,7 @@ cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, int skip_header)
279 out = &throwaway; 319 out = &throwaway;
280 320
281 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) || 321 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
282 tag != tag_value || (header_len > 0 && 322 tag != tag_value)
283 /*
284 * This ensures that the tag is either zero length or
285 * indefinite-length.
286 */
287 CBS_len(out) == header_len &&
288 CBS_data(out)[header_len - 1] == 0x80))
289 return 0; 323 return 0;
290 324
291 if (skip_header && !CBS_skip(out, header_len)) { 325 if (skip_header && !CBS_skip(out, header_len)) {
diff --git a/src/lib/libssl/bytestring.h b/src/lib/libssl/bytestring.h
index b98c930da5..d66ab65b91 100644
--- a/src/lib/libssl/bytestring.h
+++ b/src/lib/libssl/bytestring.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: bytestring.h,v 1.6 2015/06/13 09:02:45 doug Exp $ */ 1/* $OpenBSD: bytestring.h,v 1.7 2015/06/15 07:35:49 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -223,9 +223,8 @@ int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value);
223/* 223/*
224 * CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from 224 * CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
225 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to 225 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
226 * the tag number and |*out_header_len| to the length of the ASN.1 header. If 226 * the tag number and |*out_header_len| to the length of the ASN.1 header.
227 * the element has indefinite length then |*out| will only contain the 227 * Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore
228 * header. Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore
229 * the value. 228 * the value.
230 * 229 *
231 * Tag numbers greater than 30 are not supported (i.e. short form only). 230 * Tag numbers greater than 30 are not supported (i.e. short form only).
@@ -452,6 +451,19 @@ int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
452 451
453#ifdef LIBRESSL_INTERNAL 452#ifdef LIBRESSL_INTERNAL
454/* 453/*
454 * CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
455 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
456 * the tag number and |*out_header_len| to the length of the ASN.1 header. If
457 * strict mode is disabled and the element has indefinite length then |*out|
458 * will only contain the header. Each of |out|, |out_tag|, and
459 * |out_header_len| may be NULL to ignore the value.
460 *
461 * Tag numbers greater than 30 are not supported (i.e. short form only).
462 */
463int cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned *out_tag,
464 size_t *out_header_len, int strict);
465
466/*
455 * CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds 467 * CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds
456 * indefinite-length elements then it attempts to convert the BER data to DER 468 * indefinite-length elements then it attempts to convert the BER data to DER
457 * and sets |*out| and |*out_length| to describe a malloced buffer containing 469 * and sets |*out| and |*out_length| to describe a malloced buffer containing
diff --git a/src/lib/libssl/src/ssl/bs_ber.c b/src/lib/libssl/src/ssl/bs_ber.c
index 2ec91fc800..3d39def111 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.4 2015/04/29 02:11:09 doug Exp $ */ 1/* $OpenBSD: bs_ber.c,v 1.5 2015/06/15 07:35:49 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -27,6 +27,15 @@
27 */ 27 */
28static const unsigned kMaxDepth = 2048; 28static const unsigned kMaxDepth = 2048;
29 29
30/* Non-strict version that allows a relaxed DER with indefinite form. */
31static int
32cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
33 size_t *out_header_len)
34{
35 return cbs_get_any_asn1_element_internal(cbs, out,
36 out_tag, out_header_len, 0);
37}
38
30/* 39/*
31 * cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found| 40 * cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found|
32 * depending on whether an indefinite length element was found. The value of 41 * depending on whether an indefinite length element was found. The value of
@@ -49,10 +58,11 @@ cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth)
49 unsigned tag; 58 unsigned tag;
50 size_t header_len; 59 size_t header_len;
51 60
52 if (!CBS_get_any_asn1_element(&in, &contents, &tag, 61 if (!cbs_nonstrict_get_any_asn1_element(&in, &contents, &tag,
53 &header_len)) 62 &header_len))
54 return 0; 63 return 0;
55 64
65 /* Indefinite form not allowed by DER. */
56 if (CBS_len(&contents) == header_len && header_len > 0 && 66 if (CBS_len(&contents) == header_len && header_len > 0 &&
57 CBS_data(&contents)[header_len - 1] == 0x80) { 67 CBS_data(&contents)[header_len - 1] == 0x80) {
58 *ber_found = 1; 68 *ber_found = 1;
@@ -84,7 +94,8 @@ is_primitive_type(unsigned tag)
84 94
85/* 95/*
86 * is_eoc returns true if |header_len| and |contents|, as returned by 96 * is_eoc returns true if |header_len| and |contents|, as returned by
87 * |CBS_get_any_asn1_element|, indicate an "end of contents" (EOC) value. 97 * |cbs_nonstrict_get_any_asn1_element|, indicate an "end of contents" (EOC)
98 * value.
88 */ 99 */
89static char 100static char
90is_eoc(size_t header_len, CBS *contents) 101is_eoc(size_t header_len, CBS *contents)
@@ -113,7 +124,8 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc,
113 size_t header_len; 124 size_t header_len;
114 CBB *out_contents, out_contents_storage; 125 CBB *out_contents, out_contents_storage;
115 126
116 if (!CBS_get_any_asn1_element(in, &contents, &tag, &header_len)) 127 if (!cbs_nonstrict_get_any_asn1_element(in, &contents, &tag,
128 &header_len))
117 return 0; 129 return 0;
118 130
119 out_contents = out; 131 out_contents = out;
@@ -156,9 +168,9 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc,
156 168
157 CBS_init(&in_copy, CBS_data(in), 169 CBS_init(&in_copy, CBS_data(in),
158 CBS_len(in)); 170 CBS_len(in));
159 if (!CBS_get_any_asn1_element(&in_copy, 171 if (!cbs_nonstrict_get_any_asn1_element(
160 &inner_contents, &inner_tag, 172 &in_copy, &inner_contents,
161 &inner_header_len)) 173 &inner_tag, &inner_header_len))
162 return 0; 174 return 0;
163 175
164 if (CBS_len(&inner_contents) > 176 if (CBS_len(&inner_contents) >
diff --git a/src/lib/libssl/src/ssl/bs_cbs.c b/src/lib/libssl/src/ssl/bs_cbs.c
index c37f81dd60..ba38303c18 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.8 2015/06/13 08:46:00 doug Exp $ */ 1/* $OpenBSD: bs_cbs.c,v 1.9 2015/06/15 07:35:49 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -205,24 +205,45 @@ int
205CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, 205CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
206 size_t *out_header_len) 206 size_t *out_header_len)
207{ 207{
208 return cbs_get_any_asn1_element_internal(cbs, out, out_tag,
209 out_header_len, 1);
210}
211
212/*
213 * Review X.690 for details on ASN.1 DER encoding.
214 *
215 * If non-strict mode is enabled, then DER rules are relaxed
216 * for indefinite constructs (violates DER but a little closer to BER).
217 * Non-strict mode should only be used by bs_ber.c
218 *
219 * Sections 8, 10 and 11 for DER encoding
220 */
221int
222cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned *out_tag,
223 size_t *out_header_len, int strict)
224{
208 uint8_t tag, length_byte; 225 uint8_t tag, length_byte;
209 CBS header = *cbs; 226 CBS header = *cbs;
210 CBS throwaway; 227 CBS throwaway;
228 size_t len;
211 229
212 if (out == NULL) 230 if (out == NULL)
213 out = &throwaway; 231 out = &throwaway;
214 232
233 /*
234 * Get identifier octet and length octet. Only 1 octet for each
235 * is a CBS limitation.
236 */
215 if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte)) 237 if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte))
216 return 0; 238 return 0;
217 239
240 /* CBS limitation: long form tags are not supported. */
218 if ((tag & 0x1f) == 0x1f) 241 if ((tag & 0x1f) == 0x1f)
219 /* Long form tags are not supported. */
220 return 0; 242 return 0;
221 243
222 if (out_tag != NULL) 244 if (out_tag != NULL)
223 *out_tag = tag; 245 *out_tag = tag;
224 246
225 size_t len;
226 if ((length_byte & 0x80) == 0) { 247 if ((length_byte & 0x80) == 0) {
227 /* Short form length. */ 248 /* Short form length. */
228 len = ((size_t) length_byte) + 2; 249 len = ((size_t) length_byte) + 2;
@@ -234,21 +255,40 @@ CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
234 const size_t num_bytes = length_byte & 0x7f; 255 const size_t num_bytes = length_byte & 0x7f;
235 uint32_t len32; 256 uint32_t len32;
236 257
237 if ((tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) { 258 /* ASN.1 reserved value for future extensions */
238 /* indefinite length */ 259 if (num_bytes == 0x7f)
239 if (out_header_len != NULL) 260 return 0;
240 *out_header_len = 2; 261
241 return CBS_get_bytes(cbs, out, 2); 262 /* Handle indefinite form length */
263 if (num_bytes == 0) {
264 /* DER encoding doesn't allow for indefinite form. */
265 if (strict) {
266 return 0;
267
268 } else {
269 if ((tag & CBS_ASN1_CONSTRUCTED) != 0 &&
270 num_bytes == 0) {
271 /* indefinite length */
272 if (out_header_len != NULL)
273 *out_header_len = 2;
274 return CBS_get_bytes(cbs, out, 2);
275 } else {
276 /* Primitive cannot use indefinite. */
277 return 0;
278 }
279 }
242 } 280 }
243 281
244 if (num_bytes == 0 || num_bytes > 4) 282 /* CBS limitation. */
283 if (num_bytes > 4)
245 return 0; 284 return 0;
246 285
247 if (!cbs_get_u(&header, &len32, num_bytes)) 286 if (!cbs_get_u(&header, &len32, num_bytes))
248 return 0; 287 return 0;
249 288
289 /* DER has a minimum length octet requirements. */
250 if (len32 < 128) 290 if (len32 < 128)
251 /* Length should have used short-form encoding. */ 291 /* Should have used short form instead */
252 return 0; 292 return 0;
253 293
254 if ((len32 >> ((num_bytes - 1) * 8)) == 0) 294 if ((len32 >> ((num_bytes - 1) * 8)) == 0)
@@ -279,13 +319,7 @@ cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, int skip_header)
279 out = &throwaway; 319 out = &throwaway;
280 320
281 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) || 321 if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
282 tag != tag_value || (header_len > 0 && 322 tag != tag_value)
283 /*
284 * This ensures that the tag is either zero length or
285 * indefinite-length.
286 */
287 CBS_len(out) == header_len &&
288 CBS_data(out)[header_len - 1] == 0x80))
289 return 0; 323 return 0;
290 324
291 if (skip_header && !CBS_skip(out, header_len)) { 325 if (skip_header && !CBS_skip(out, header_len)) {
diff --git a/src/lib/libssl/src/ssl/bytestring.h b/src/lib/libssl/src/ssl/bytestring.h
index b98c930da5..d66ab65b91 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.6 2015/06/13 09:02:45 doug Exp $ */ 1/* $OpenBSD: bytestring.h,v 1.7 2015/06/15 07:35:49 doug Exp $ */
2/* 2/*
3 * Copyright (c) 2014, Google Inc. 3 * Copyright (c) 2014, Google Inc.
4 * 4 *
@@ -223,9 +223,8 @@ int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value);
223/* 223/*
224 * CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from 224 * CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
225 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to 225 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
226 * the tag number and |*out_header_len| to the length of the ASN.1 header. If 226 * the tag number and |*out_header_len| to the length of the ASN.1 header.
227 * the element has indefinite length then |*out| will only contain the 227 * Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore
228 * header. Each of |out|, |out_tag|, and |out_header_len| may be NULL to ignore
229 * the value. 228 * the value.
230 * 229 *
231 * Tag numbers greater than 30 are not supported (i.e. short form only). 230 * Tag numbers greater than 30 are not supported (i.e. short form only).
@@ -452,6 +451,19 @@ int CBB_add_asn1_uint64(CBB *cbb, uint64_t value);
452 451
453#ifdef LIBRESSL_INTERNAL 452#ifdef LIBRESSL_INTERNAL
454/* 453/*
454 * CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from
455 * |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to
456 * the tag number and |*out_header_len| to the length of the ASN.1 header. If
457 * strict mode is disabled and the element has indefinite length then |*out|
458 * will only contain the header. Each of |out|, |out_tag|, and
459 * |out_header_len| may be NULL to ignore the value.
460 *
461 * Tag numbers greater than 30 are not supported (i.e. short form only).
462 */
463int cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned *out_tag,
464 size_t *out_header_len, int strict);
465
466/*
455 * CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds 467 * CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds
456 * indefinite-length elements then it attempts to convert the BER data to DER 468 * indefinite-length elements then it attempts to convert the BER data to DER
457 * and sets |*out| and |*out_length| to describe a malloced buffer containing 469 * and sets |*out| and |*out_length| to describe a malloced buffer containing