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 /src/lib/libssl/bs_ber.c | |
| 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@
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/bs_ber.c | 42 |
1 files changed, 23 insertions, 19 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 | } |
