Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/logging.h" | 5 #include "base/logging.h" |
| 6 #include "base/numerics/safe_math.h" | 6 #include "base/numerics/safe_math.h" |
| 7 #include "net/der/parse_values.h" | 7 #include "net/der/parse_values.h" |
| 8 | 8 |
| 9 namespace net { | 9 namespace net { |
| 10 | 10 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 } | 118 } |
| 119 | 119 |
| 120 // BER interprets any non-zero value as true, while DER requires a bool to | 120 // BER interprets any non-zero value as true, while DER requires a bool to |
| 121 // have either all bits zero (false) or all bits one (true). To support | 121 // have either all bits zero (false) or all bits one (true). To support |
| 122 // malformed certs, we recognized the BER encoding instead of failing to | 122 // malformed certs, we recognized the BER encoding instead of failing to |
| 123 // parse. | 123 // parse. |
| 124 bool ParseBoolRelaxed(const Input& in, bool* out) { | 124 bool ParseBoolRelaxed(const Input& in, bool* out) { |
| 125 return ParseBoolInternal(in, out, true /* relaxed */); | 125 return ParseBoolInternal(in, out, true /* relaxed */); |
| 126 } | 126 } |
| 127 | 127 |
| 128 bool ParseUint64(const Input& in, uint64_t* out) { | 128 // ITU-T X.690 section 8.3.2 specifies that an integer value must be encoded |
| 129 ByteReader reader(in); | 129 // in the smallest number of octets. If the encoding consists of more than |
| 130 size_t bytes_read = 0; | 130 // one octet, then the bits of the first octet and the most significant bit |
| 131 uint8_t data; | 131 // of the second octet must not be all zeroes or all ones. |
| 132 uint64_t value = 0; | 132 bool ParseInteger(const Input& in, |
| 133 // Note that for simplicity, this check only admits integers up to 2^63-1. | 133 bool* out_negative, |
| 134 if (in.Length() > sizeof(uint64_t) || in.Length() == 0) | 134 size_t* out_numeric_length) { |
| 135 return false; | 135 der::ByteReader reader(in); |
| 136 while (reader.ReadByte(&data)) { | 136 uint8_t first_byte; |
| 137 if (bytes_read == 0 && (data & 0x80)) { | 137 |
| 138 return false; | 138 if (!reader.ReadByte(&first_byte)) |
| 139 return false; // Empty inputs are not allowed. | |
| 140 | |
| 141 size_t numeric_length = in.Length(); | |
| 142 | |
| 143 uint8_t second_byte; | |
| 144 if (reader.ReadByte(&second_byte)) { | |
| 145 if (first_byte == 0) { | |
| 146 // The first byte in this case doesn't contribute to the number's value | |
| 147 // (just used to determine the sign). | |
| 148 numeric_length -= 1; | |
| 139 } | 149 } |
| 140 value <<= 8; | 150 |
| 141 value |= data; | 151 if ((first_byte == 0x00 || first_byte == 0xFF) && |
| 142 bytes_read++; | 152 (first_byte & 0x80) == (second_byte & 0x80)) { |
| 143 } | 153 // Not a minimal encoding. |
| 144 // ITU-T X.690 section 8.3.2 specifies that an integer value must be encoded | |
| 145 // in the smallest number of octets. If the encoding consists of more than | |
| 146 // one octet, then the bits of the first octet and the most significant bit | |
| 147 // of the second octet must not be all zeroes or all ones. | |
| 148 // Because this function only parses unsigned integers, there's no need to | |
| 149 // check for the all ones case. | |
| 150 if (bytes_read > 1) { | |
| 151 ByteReader first_bytes_reader(in); | |
| 152 uint8_t first_byte; | |
| 153 uint8_t second_byte; | |
| 154 if (!first_bytes_reader.ReadByte(&first_byte) || | |
| 155 !first_bytes_reader.ReadByte(&second_byte)) { | |
| 156 return false; | |
| 157 } | |
| 158 if (first_byte == 0 && !(second_byte & 0x80)) { | |
| 159 return false; | 154 return false; |
| 160 } | 155 } |
| 161 } | 156 } |
| 157 | |
| 158 *out_negative = first_byte & 0x80; | |
|
nharper
2015/08/14 22:23:41
I'm not familiar with C++ type conversion rules -
eroman
2015/08/14 23:19:38
Done. I changed to an explicit boolean (since MSCV
| |
| 159 *out_numeric_length = numeric_length; | |
| 160 return true; | |
| 161 } | |
| 162 | |
| 163 bool ParseUint64(const Input& in, uint64_t* out) { | |
| 164 // Reject non-minimally encoded numbers, negative numbers, and non-negative | |
| 165 // numbers that would overflow the output type. | |
| 166 bool negative; | |
| 167 size_t numeric_length; | |
| 168 if (!ParseInteger(in, &negative, &numeric_length)) | |
| 169 return false; | |
| 170 if (negative || numeric_length > sizeof(*out)) | |
| 171 return false; | |
| 172 | |
| 173 ByteReader reader(in); | |
| 174 uint8_t data; | |
| 175 uint64_t value = 0; | |
| 176 | |
| 177 while (reader.ReadByte(&data)) { | |
| 178 value <<= 8; | |
| 179 value |= data; | |
| 180 } | |
| 162 *out = value; | 181 *out = value; |
| 163 return true; | 182 return true; |
| 164 } | 183 } |
| 165 | 184 |
| 166 BitString::BitString(const Input& bytes, uint8_t unused_bits) | 185 BitString::BitString(const Input& bytes, uint8_t unused_bits) |
| 167 : bytes_(bytes), unused_bits_(unused_bits) { | 186 : bytes_(bytes), unused_bits_(unused_bits) { |
| 168 DCHECK_LT(unused_bits, 8); | 187 DCHECK_LT(unused_bits, 8); |
| 169 DCHECK(unused_bits == 0 || bytes.Length() != 0); | 188 DCHECK(unused_bits == 0 || bytes.Length() != 0); |
| 170 } | 189 } |
| 171 | 190 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 307 return false; | 326 return false; |
| 308 if (!ValidateGeneralizedTime(time)) | 327 if (!ValidateGeneralizedTime(time)) |
| 309 return false; | 328 return false; |
| 310 *value = time; | 329 *value = time; |
| 311 return true; | 330 return true; |
| 312 } | 331 } |
| 313 | 332 |
| 314 } // namespace der | 333 } // namespace der |
| 315 | 334 |
| 316 } // namespace net | 335 } // namespace net |
| OLD | NEW |