diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/bs_ber.c | 26 |
1 files changed, 19 insertions, 7 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 | */ |
| 28 | static const unsigned kMaxDepth = 2048; | 28 | static const unsigned kMaxDepth = 2048; |
| 29 | 29 | ||
| 30 | /* Non-strict version that allows a relaxed DER with indefinite form. */ | ||
| 31 | static int | ||
| 32 | cbs_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 | */ |
| 89 | static char | 100 | static char |
| 90 | is_eoc(size_t header_len, CBS *contents) | 101 | is_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) > |
