diff options
author | doug <> | 2015-06-16 06:37:58 +0000 |
---|---|---|
committer | doug <> | 2015-06-16 06:37:58 +0000 |
commit | 924d478ace6d3fb8033502da649ef6094b7ee75a (patch) | |
tree | ca21a350b439c40324eb3a0fa186f4a28038a4fa | |
parent | d44d9785ffbec94f6960b1a4f5dfd26c3faad092 (diff) | |
download | openbsd-924d478ace6d3fb8033502da649ef6094b7ee75a.tar.gz openbsd-924d478ace6d3fb8033502da649ef6094b7ee75a.tar.bz2 openbsd-924d478ace6d3fb8033502da649ef6094b7ee75a.zip |
Be more strict about BER and DER terminology.
bs_ber.c does not convert BER to DER. It's a hack to convert a DER-like
encoding with one violation (indefinite form) to strict DER. Rename
the functions to reflect this.
ok miod@ jsing@
-rw-r--r-- | src/lib/libssl/bs_ber.c | 42 | ||||
-rw-r--r-- | src/lib/libssl/bytestring.h | 19 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/bs_ber.c | 42 | ||||
-rw-r--r-- | src/lib/libssl/src/ssl/bytestring.h | 19 | ||||
-rw-r--r-- | src/regress/lib/libssl/bytestring/bytestringtest.c | 33 |
5 files changed, 84 insertions, 71 deletions
diff --git a/src/lib/libssl/bs_ber.c b/src/lib/libssl/bs_ber.c index 3d39def111..1310d4a94c 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.5 2015/06/15 07:35:49 doug Exp $ */ | 1 | /* $OpenBSD: bs_ber.c,v 1.6 2015/06/16 06:37:58 doug Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014, Google Inc. | 3 | * Copyright (c) 2014, Google Inc. |
4 | * | 4 | * |
@@ -29,7 +29,7 @@ static const unsigned kMaxDepth = 2048; | |||
29 | 29 | ||
30 | /* Non-strict version that allows a relaxed DER with indefinite form. */ | 30 | /* Non-strict version that allows a relaxed DER with indefinite form. */ |
31 | static int | 31 | static int |
32 | cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, | 32 | cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, |
33 | size_t *out_header_len) | 33 | size_t *out_header_len) |
34 | { | 34 | { |
35 | return cbs_get_any_asn1_element_internal(cbs, out, | 35 | return cbs_get_any_asn1_element_internal(cbs, out, |
@@ -37,13 +37,15 @@ cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, | |||
37 | } | 37 | } |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found| | 40 | * cbs_find_indefinite walks an ASN.1 structure in |orig_in| and sets |
41 | * depending on whether an indefinite length element was found. The value of | 41 | * |*indefinite_found| depending on whether an indefinite length element was |
42 | * |in| is not changed. It returns one on success (i.e. |*ber_found| was set) | 42 | * found. The value of |orig_in| is not modified. |
43 | * and zero on error. | 43 | * |
44 | * Returns one on success (i.e. |*indefinite_found| was set) and zero on error. | ||
44 | */ | 45 | */ |
45 | static int | 46 | static int |
46 | cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) | 47 | cbs_find_indefinite(const CBS *orig_in, char *indefinite_found, |
48 | unsigned int depth) | ||
47 | { | 49 | { |
48 | CBS in; | 50 | CBS in; |
49 | 51 | ||
@@ -51,7 +53,6 @@ cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) | |||
51 | return 0; | 53 | return 0; |
52 | 54 | ||
53 | CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); | 55 | CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); |
54 | *ber_found = 0; | ||
55 | 56 | ||
56 | while (CBS_len(&in) > 0) { | 57 | while (CBS_len(&in) > 0) { |
57 | CBS contents; | 58 | CBS contents; |
@@ -65,16 +66,18 @@ cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) | |||
65 | /* Indefinite form not allowed by DER. */ | 66 | /* Indefinite form not allowed by DER. */ |
66 | if (CBS_len(&contents) == header_len && header_len > 0 && | 67 | if (CBS_len(&contents) == header_len && header_len > 0 && |
67 | CBS_data(&contents)[header_len - 1] == 0x80) { | 68 | CBS_data(&contents)[header_len - 1] == 0x80) { |
68 | *ber_found = 1; | 69 | *indefinite_found = 1; |
69 | return 1; | 70 | return 1; |
70 | } | 71 | } |
71 | if (tag & CBS_ASN1_CONSTRUCTED) { | 72 | if (tag & CBS_ASN1_CONSTRUCTED) { |
72 | if (!CBS_skip(&contents, header_len) || | 73 | if (!CBS_skip(&contents, header_len) || |
73 | !cbs_find_ber(&contents, ber_found, depth + 1)) | 74 | !cbs_find_indefinite(&contents, indefinite_found, |
75 | depth + 1)) | ||
74 | return 0; | 76 | return 0; |
75 | } | 77 | } |
76 | } | 78 | } |
77 | 79 | ||
80 | *indefinite_found = 0; | ||
78 | return 1; | 81 | return 1; |
79 | } | 82 | } |
80 | 83 | ||
@@ -104,7 +107,8 @@ is_eoc(size_t header_len, CBS *contents) | |||
104 | } | 107 | } |
105 | 108 | ||
106 | /* | 109 | /* |
107 | * cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If | 110 | * cbs_convert_indefinite reads data with DER encoding (but relaxed to allow |
111 | * indefinite form) from |in| and writes definite form DER data to |out|. If | ||
108 | * |squash_header| is set then the top-level of elements from |in| will not | 112 | * |squash_header| is set then the top-level of elements from |in| will not |
109 | * have their headers written. This is used when concatenating the fragments of | 113 | * have their headers written. This is used when concatenating the fragments of |
110 | * an indefinite length, primitive value. If |looking_for_eoc| is set then any | 114 | * an indefinite length, primitive value. If |looking_for_eoc| is set then any |
@@ -112,8 +116,8 @@ is_eoc(size_t header_len, CBS *contents) | |||
112 | * It returns one on success and zero on error. | 116 | * It returns one on success and zero on error. |
113 | */ | 117 | */ |
114 | static int | 118 | static int |
115 | cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc, | 119 | cbs_convert_indefinite(CBS *in, CBB *out, char squash_header, |
116 | unsigned depth) | 120 | char looking_for_eoc, unsigned depth) |
117 | { | 121 | { |
118 | if (depth > kMaxDepth) | 122 | if (depth > kMaxDepth) |
119 | return 0; | 123 | return 0; |
@@ -143,7 +147,7 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc, | |||
143 | * with a concrete length prefix. | 147 | * with a concrete length prefix. |
144 | * | 148 | * |
145 | * If it's a something else then the contents | 149 | * If it's a something else then the contents |
146 | * will be a series of BER elements of the same | 150 | * will be a series of DER elements of the same |
147 | * type which need to be concatenated. | 151 | * type which need to be concatenated. |
148 | */ | 152 | */ |
149 | const char context_specific = (tag & 0xc0) | 153 | const char context_specific = (tag & 0xc0) |
@@ -193,7 +197,7 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc, | |||
193 | out_contents = &out_contents_storage; | 197 | out_contents = &out_contents_storage; |
194 | } | 198 | } |
195 | 199 | ||
196 | if (!cbs_convert_ber(in, out_contents, | 200 | if (!cbs_convert_indefinite(in, out_contents, |
197 | squash_child_headers, | 201 | squash_child_headers, |
198 | 1 /* looking for eoc */, depth + 1)) | 202 | 1 /* looking for eoc */, depth + 1)) |
199 | return 0; | 203 | return 0; |
@@ -216,7 +220,7 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc, | |||
216 | return 0; | 220 | return 0; |
217 | 221 | ||
218 | if (tag & CBS_ASN1_CONSTRUCTED) { | 222 | if (tag & CBS_ASN1_CONSTRUCTED) { |
219 | if (!cbs_convert_ber(&contents, out_contents, | 223 | if (!cbs_convert_indefinite(&contents, out_contents, |
220 | 0 /* don't squash header */, | 224 | 0 /* don't squash header */, |
221 | 0 /* not looking for eoc */, depth + 1)) | 225 | 0 /* not looking for eoc */, depth + 1)) |
222 | return 0; | 226 | return 0; |
@@ -234,7 +238,7 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc, | |||
234 | } | 238 | } |
235 | 239 | ||
236 | int | 240 | int |
237 | CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) | 241 | CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len) |
238 | { | 242 | { |
239 | CBB cbb; | 243 | CBB cbb; |
240 | 244 | ||
@@ -244,7 +248,7 @@ CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) | |||
244 | * return. | 248 | * return. |
245 | */ | 249 | */ |
246 | char conversion_needed; | 250 | char conversion_needed; |
247 | if (!cbs_find_ber(in, &conversion_needed, 0)) | 251 | if (!cbs_find_indefinite(in, &conversion_needed, 0)) |
248 | return 0; | 252 | return 0; |
249 | 253 | ||
250 | if (!conversion_needed) { | 254 | if (!conversion_needed) { |
@@ -254,7 +258,7 @@ CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) | |||
254 | } | 258 | } |
255 | 259 | ||
256 | CBB_init(&cbb, CBS_len(in)); | 260 | CBB_init(&cbb, CBS_len(in)); |
257 | if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) { | 261 | if (!cbs_convert_indefinite(in, &cbb, 0, 0, 0)) { |
258 | CBB_cleanup(&cbb); | 262 | CBB_cleanup(&cbb); |
259 | return 0; | 263 | return 0; |
260 | } | 264 | } |
diff --git a/src/lib/libssl/bytestring.h b/src/lib/libssl/bytestring.h index ef824a0cea..07be6ddd50 100644 --- a/src/lib/libssl/bytestring.h +++ b/src/lib/libssl/bytestring.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bytestring.h,v 1.8 2015/06/16 06:11:39 doug Exp $ */ | 1 | /* $OpenBSD: bytestring.h,v 1.9 2015/06/16 06:37:58 doug Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014, Google Inc. | 3 | * Copyright (c) 2014, Google Inc. |
4 | * | 4 | * |
@@ -464,22 +464,23 @@ int cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned *out_tag, | |||
464 | size_t *out_header_len, int strict); | 464 | size_t *out_header_len, int strict); |
465 | 465 | ||
466 | /* | 466 | /* |
467 | * CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds | 467 | * CBS_asn1_indefinite_to_definite reads an ASN.1 structure from |in|. If it |
468 | * indefinite-length elements then it attempts to convert the BER data to DER | 468 | * finds indefinite-length elements that otherwise appear to be valid DER, it |
469 | * and sets |*out| and |*out_length| to describe a malloced buffer containing | 469 | * attempts to convert the DER-like data to DER and sets |*out| and |
470 | * the DER data. Additionally, |*in| will be advanced over the ASN.1 data. | 470 | * |*out_length| to describe a malloced buffer containing the DER data. |
471 | * Additionally, |*in| will be advanced over the ASN.1 data. | ||
471 | * | 472 | * |
472 | * If it doesn't find any indefinite-length elements then it sets |*out| to | 473 | * If it doesn't find any indefinite-length elements then it sets |*out| to |
473 | * NULL and |*in| is unmodified. | 474 | * NULL and |*in| is unmodified. |
474 | * | 475 | * |
475 | * A sufficiently complex ASN.1 structure will break this function because it's | 476 | * This is NOT a conversion from BER to DER. There are many restrictions when |
476 | * not possible to generically convert BER to DER without knowledge of the | 477 | * dealing with DER data. This is only concerned with one: indefinite vs. |
477 | * structure itself. However, this sufficies to handle the PKCS#7 and #12 output | 478 | * definite form. However, this suffices to handle the PKCS#7 and PKCS#12 output |
478 | * from NSS. | 479 | * from NSS. |
479 | * | 480 | * |
480 | * It returns one on success and zero otherwise. | 481 | * It returns one on success and zero otherwise. |
481 | */ | 482 | */ |
482 | int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len); | 483 | int CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len); |
483 | #endif /* LIBRESSL_INTERNAL */ | 484 | #endif /* LIBRESSL_INTERNAL */ |
484 | 485 | ||
485 | #if defined(__cplusplus) | 486 | #if defined(__cplusplus) |
diff --git a/src/lib/libssl/src/ssl/bs_ber.c b/src/lib/libssl/src/ssl/bs_ber.c index 3d39def111..1310d4a94c 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.5 2015/06/15 07:35:49 doug Exp $ */ | 1 | /* $OpenBSD: bs_ber.c,v 1.6 2015/06/16 06:37:58 doug Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014, Google Inc. | 3 | * Copyright (c) 2014, Google Inc. |
4 | * | 4 | * |
@@ -29,7 +29,7 @@ static const unsigned kMaxDepth = 2048; | |||
29 | 29 | ||
30 | /* Non-strict version that allows a relaxed DER with indefinite form. */ | 30 | /* Non-strict version that allows a relaxed DER with indefinite form. */ |
31 | static int | 31 | static int |
32 | cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, | 32 | cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag, |
33 | size_t *out_header_len) | 33 | size_t *out_header_len) |
34 | { | 34 | { |
35 | return cbs_get_any_asn1_element_internal(cbs, out, | 35 | return cbs_get_any_asn1_element_internal(cbs, out, |
@@ -37,13 +37,15 @@ cbs_nonstrict_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, | |||
37 | } | 37 | } |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found| | 40 | * cbs_find_indefinite walks an ASN.1 structure in |orig_in| and sets |
41 | * depending on whether an indefinite length element was found. The value of | 41 | * |*indefinite_found| depending on whether an indefinite length element was |
42 | * |in| is not changed. It returns one on success (i.e. |*ber_found| was set) | 42 | * found. The value of |orig_in| is not modified. |
43 | * and zero on error. | 43 | * |
44 | * Returns one on success (i.e. |*indefinite_found| was set) and zero on error. | ||
44 | */ | 45 | */ |
45 | static int | 46 | static int |
46 | cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) | 47 | cbs_find_indefinite(const CBS *orig_in, char *indefinite_found, |
48 | unsigned int depth) | ||
47 | { | 49 | { |
48 | CBS in; | 50 | CBS in; |
49 | 51 | ||
@@ -51,7 +53,6 @@ cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) | |||
51 | return 0; | 53 | return 0; |
52 | 54 | ||
53 | CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); | 55 | CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); |
54 | *ber_found = 0; | ||
55 | 56 | ||
56 | while (CBS_len(&in) > 0) { | 57 | while (CBS_len(&in) > 0) { |
57 | CBS contents; | 58 | CBS contents; |
@@ -65,16 +66,18 @@ cbs_find_ber(CBS *orig_in, char *ber_found, unsigned depth) | |||
65 | /* Indefinite form not allowed by DER. */ | 66 | /* Indefinite form not allowed by DER. */ |
66 | if (CBS_len(&contents) == header_len && header_len > 0 && | 67 | if (CBS_len(&contents) == header_len && header_len > 0 && |
67 | CBS_data(&contents)[header_len - 1] == 0x80) { | 68 | CBS_data(&contents)[header_len - 1] == 0x80) { |
68 | *ber_found = 1; | 69 | *indefinite_found = 1; |
69 | return 1; | 70 | return 1; |
70 | } | 71 | } |
71 | if (tag & CBS_ASN1_CONSTRUCTED) { | 72 | if (tag & CBS_ASN1_CONSTRUCTED) { |
72 | if (!CBS_skip(&contents, header_len) || | 73 | if (!CBS_skip(&contents, header_len) || |
73 | !cbs_find_ber(&contents, ber_found, depth + 1)) | 74 | !cbs_find_indefinite(&contents, indefinite_found, |
75 | depth + 1)) | ||
74 | return 0; | 76 | return 0; |
75 | } | 77 | } |
76 | } | 78 | } |
77 | 79 | ||
80 | *indefinite_found = 0; | ||
78 | return 1; | 81 | return 1; |
79 | } | 82 | } |
80 | 83 | ||
@@ -104,7 +107,8 @@ is_eoc(size_t header_len, CBS *contents) | |||
104 | } | 107 | } |
105 | 108 | ||
106 | /* | 109 | /* |
107 | * cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If | 110 | * cbs_convert_indefinite reads data with DER encoding (but relaxed to allow |
111 | * indefinite form) from |in| and writes definite form DER data to |out|. If | ||
108 | * |squash_header| is set then the top-level of elements from |in| will not | 112 | * |squash_header| is set then the top-level of elements from |in| will not |
109 | * have their headers written. This is used when concatenating the fragments of | 113 | * have their headers written. This is used when concatenating the fragments of |
110 | * an indefinite length, primitive value. If |looking_for_eoc| is set then any | 114 | * an indefinite length, primitive value. If |looking_for_eoc| is set then any |
@@ -112,8 +116,8 @@ is_eoc(size_t header_len, CBS *contents) | |||
112 | * It returns one on success and zero on error. | 116 | * It returns one on success and zero on error. |
113 | */ | 117 | */ |
114 | static int | 118 | static int |
115 | cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc, | 119 | cbs_convert_indefinite(CBS *in, CBB *out, char squash_header, |
116 | unsigned depth) | 120 | char looking_for_eoc, unsigned depth) |
117 | { | 121 | { |
118 | if (depth > kMaxDepth) | 122 | if (depth > kMaxDepth) |
119 | return 0; | 123 | return 0; |
@@ -143,7 +147,7 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc, | |||
143 | * with a concrete length prefix. | 147 | * with a concrete length prefix. |
144 | * | 148 | * |
145 | * If it's a something else then the contents | 149 | * If it's a something else then the contents |
146 | * will be a series of BER elements of the same | 150 | * will be a series of DER elements of the same |
147 | * type which need to be concatenated. | 151 | * type which need to be concatenated. |
148 | */ | 152 | */ |
149 | const char context_specific = (tag & 0xc0) | 153 | const char context_specific = (tag & 0xc0) |
@@ -193,7 +197,7 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc, | |||
193 | out_contents = &out_contents_storage; | 197 | out_contents = &out_contents_storage; |
194 | } | 198 | } |
195 | 199 | ||
196 | if (!cbs_convert_ber(in, out_contents, | 200 | if (!cbs_convert_indefinite(in, out_contents, |
197 | squash_child_headers, | 201 | squash_child_headers, |
198 | 1 /* looking for eoc */, depth + 1)) | 202 | 1 /* looking for eoc */, depth + 1)) |
199 | return 0; | 203 | return 0; |
@@ -216,7 +220,7 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc, | |||
216 | return 0; | 220 | return 0; |
217 | 221 | ||
218 | if (tag & CBS_ASN1_CONSTRUCTED) { | 222 | if (tag & CBS_ASN1_CONSTRUCTED) { |
219 | if (!cbs_convert_ber(&contents, out_contents, | 223 | if (!cbs_convert_indefinite(&contents, out_contents, |
220 | 0 /* don't squash header */, | 224 | 0 /* don't squash header */, |
221 | 0 /* not looking for eoc */, depth + 1)) | 225 | 0 /* not looking for eoc */, depth + 1)) |
222 | return 0; | 226 | return 0; |
@@ -234,7 +238,7 @@ cbs_convert_ber(CBS *in, CBB *out, char squash_header, char looking_for_eoc, | |||
234 | } | 238 | } |
235 | 239 | ||
236 | int | 240 | int |
237 | CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) | 241 | CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len) |
238 | { | 242 | { |
239 | CBB cbb; | 243 | CBB cbb; |
240 | 244 | ||
@@ -244,7 +248,7 @@ CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) | |||
244 | * return. | 248 | * return. |
245 | */ | 249 | */ |
246 | char conversion_needed; | 250 | char conversion_needed; |
247 | if (!cbs_find_ber(in, &conversion_needed, 0)) | 251 | if (!cbs_find_indefinite(in, &conversion_needed, 0)) |
248 | return 0; | 252 | return 0; |
249 | 253 | ||
250 | if (!conversion_needed) { | 254 | if (!conversion_needed) { |
@@ -254,7 +258,7 @@ CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) | |||
254 | } | 258 | } |
255 | 259 | ||
256 | CBB_init(&cbb, CBS_len(in)); | 260 | CBB_init(&cbb, CBS_len(in)); |
257 | if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) { | 261 | if (!cbs_convert_indefinite(in, &cbb, 0, 0, 0)) { |
258 | CBB_cleanup(&cbb); | 262 | CBB_cleanup(&cbb); |
259 | return 0; | 263 | return 0; |
260 | } | 264 | } |
diff --git a/src/lib/libssl/src/ssl/bytestring.h b/src/lib/libssl/src/ssl/bytestring.h index ef824a0cea..07be6ddd50 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.8 2015/06/16 06:11:39 doug Exp $ */ | 1 | /* $OpenBSD: bytestring.h,v 1.9 2015/06/16 06:37:58 doug Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014, Google Inc. | 3 | * Copyright (c) 2014, Google Inc. |
4 | * | 4 | * |
@@ -464,22 +464,23 @@ int cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned *out_tag, | |||
464 | size_t *out_header_len, int strict); | 464 | size_t *out_header_len, int strict); |
465 | 465 | ||
466 | /* | 466 | /* |
467 | * CBS_asn1_ber_to_der reads an ASN.1 structure from |in|. If it finds | 467 | * CBS_asn1_indefinite_to_definite reads an ASN.1 structure from |in|. If it |
468 | * indefinite-length elements then it attempts to convert the BER data to DER | 468 | * finds indefinite-length elements that otherwise appear to be valid DER, it |
469 | * and sets |*out| and |*out_length| to describe a malloced buffer containing | 469 | * attempts to convert the DER-like data to DER and sets |*out| and |
470 | * the DER data. Additionally, |*in| will be advanced over the ASN.1 data. | 470 | * |*out_length| to describe a malloced buffer containing the DER data. |
471 | * Additionally, |*in| will be advanced over the ASN.1 data. | ||
471 | * | 472 | * |
472 | * If it doesn't find any indefinite-length elements then it sets |*out| to | 473 | * If it doesn't find any indefinite-length elements then it sets |*out| to |
473 | * NULL and |*in| is unmodified. | 474 | * NULL and |*in| is unmodified. |
474 | * | 475 | * |
475 | * A sufficiently complex ASN.1 structure will break this function because it's | 476 | * This is NOT a conversion from BER to DER. There are many restrictions when |
476 | * not possible to generically convert BER to DER without knowledge of the | 477 | * dealing with DER data. This is only concerned with one: indefinite vs. |
477 | * structure itself. However, this sufficies to handle the PKCS#7 and #12 output | 478 | * definite form. However, this suffices to handle the PKCS#7 and PKCS#12 output |
478 | * from NSS. | 479 | * from NSS. |
479 | * | 480 | * |
480 | * It returns one on success and zero otherwise. | 481 | * It returns one on success and zero otherwise. |
481 | */ | 482 | */ |
482 | int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len); | 483 | int CBS_asn1_indefinite_to_definite(CBS *in, uint8_t **out, size_t *out_len); |
483 | #endif /* LIBRESSL_INTERNAL */ | 484 | #endif /* LIBRESSL_INTERNAL */ |
484 | 485 | ||
485 | #if defined(__cplusplus) | 486 | #if defined(__cplusplus) |
diff --git a/src/regress/lib/libssl/bytestring/bytestringtest.c b/src/regress/lib/libssl/bytestring/bytestringtest.c index 7ae9397a35..05ca27e8b5 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.4 2015/04/25 15:28:47 doug Exp $ */ | 1 | /* $OpenBSD: bytestringtest.c,v 1.5 2015/06/16 06:37:58 doug Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014, Google Inc. | 3 | * Copyright (c) 2014, Google Inc. |
4 | * | 4 | * |
@@ -484,23 +484,25 @@ err: | |||
484 | } | 484 | } |
485 | 485 | ||
486 | static int | 486 | static int |
487 | do_ber_convert(const char *name, const uint8_t *der_expected, size_t der_len, | 487 | do_indefinite_convert(const char *name, const uint8_t *definite_expected, |
488 | const uint8_t *ber, size_t ber_len) | 488 | size_t definite_len, const uint8_t *indefinite, size_t indefinite_len) |
489 | { | 489 | { |
490 | CBS in; | 490 | CBS in; |
491 | uint8_t *out = NULL; | 491 | uint8_t *out = NULL; |
492 | size_t out_len; | 492 | size_t out_len; |
493 | int ret = 0; | 493 | int ret = 0; |
494 | 494 | ||
495 | CBS_init(&in, ber, ber_len); | 495 | CBS_init(&in, indefinite, indefinite_len); |
496 | if (!CBS_asn1_ber_to_der(&in, &out, &out_len)) { | 496 | if (!CBS_asn1_indefinite_to_definite(&in, &out, &out_len)) { |
497 | fprintf(stderr, "%s: CBS_asn1_ber_to_der failed.\n", name); | 497 | fprintf(stderr, "%s: CBS_asn1_indefinite_to_definite failed.\n", |
498 | name); | ||
498 | goto end; | 499 | goto end; |
499 | } | 500 | } |
500 | 501 | ||
501 | if (out == NULL) { | 502 | if (out == NULL) { |
502 | if (ber_len != der_len || | 503 | if (indefinite_len != definite_len || |
503 | memcmp(der_expected, ber, ber_len) != 0) { | 504 | memcmp(definite_expected, indefinite, indefinite_len) |
505 | != 0) { | ||
504 | fprintf(stderr, "%s: incorrect unconverted result.\n", | 506 | fprintf(stderr, "%s: incorrect unconverted result.\n", |
505 | name); | 507 | name); |
506 | return 0; | 508 | return 0; |
@@ -509,7 +511,8 @@ do_ber_convert(const char *name, const uint8_t *der_expected, size_t der_len, | |||
509 | return 1; | 511 | return 1; |
510 | } | 512 | } |
511 | 513 | ||
512 | if (out_len != der_len || memcmp(out, der_expected, der_len) != 0) { | 514 | if (out_len != definite_len || memcmp(out, definite_expected, |
515 | definite_len) != 0) { | ||
513 | fprintf(stderr, "%s: incorrect converted result.\n", name); | 516 | fprintf(stderr, "%s: incorrect converted result.\n", name); |
514 | goto end; | 517 | goto end; |
515 | } | 518 | } |
@@ -522,7 +525,7 @@ end: | |||
522 | } | 525 | } |
523 | 526 | ||
524 | static int | 527 | static int |
525 | test_ber_convert(void) | 528 | test_indefinite_convert(void) |
526 | { | 529 | { |
527 | static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00}; | 530 | static const uint8_t kSimpleBER[] = {0x01, 0x01, 0x00}; |
528 | 531 | ||
@@ -566,14 +569,14 @@ test_ber_convert(void) | |||
566 | 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, | 569 | 0x6e, 0x10, 0x9b, 0xb8, 0x02, 0x02, 0x07, 0xd0, |
567 | }; | 570 | }; |
568 | 571 | ||
569 | return do_ber_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER), | 572 | return do_indefinite_convert("kSimpleBER", kSimpleBER, sizeof(kSimpleBER), |
570 | kSimpleBER, sizeof(kSimpleBER)) && | 573 | kSimpleBER, sizeof(kSimpleBER)) && |
571 | do_ber_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER, | 574 | do_indefinite_convert("kIndefBER", kIndefDER, sizeof(kIndefDER), kIndefBER, |
572 | sizeof(kIndefBER)) && | 575 | sizeof(kIndefBER)) && |
573 | do_ber_convert("kOctetStringBER", kOctetStringDER, | 576 | do_indefinite_convert("kOctetStringBER", kOctetStringDER, |
574 | sizeof(kOctetStringDER), kOctetStringBER, | 577 | sizeof(kOctetStringDER), kOctetStringBER, |
575 | sizeof(kOctetStringBER)) && | 578 | sizeof(kOctetStringBER)) && |
576 | do_ber_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER, | 579 | do_indefinite_convert("kNSSBER", kNSSDER, sizeof(kNSSDER), kNSSBER, |
577 | sizeof(kNSSBER)); | 580 | sizeof(kNSSBER)); |
578 | } | 581 | } |
579 | 582 | ||
@@ -682,7 +685,7 @@ main(void) | |||
682 | !test_cbb_misuse() || | 685 | !test_cbb_misuse() || |
683 | !test_cbb_prefixed() || | 686 | !test_cbb_prefixed() || |
684 | !test_cbb_asn1() || | 687 | !test_cbb_asn1() || |
685 | !test_ber_convert() || | 688 | !test_indefinite_convert() || |
686 | !test_asn1_uint64() || | 689 | !test_asn1_uint64() || |
687 | !test_get_optional_asn1_bool()) | 690 | !test_get_optional_asn1_bool()) |
688 | return 1; | 691 | return 1; |