diff options
Diffstat (limited to '')
| -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; |
