diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-01-25 11:39:07 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-01-25 15:20:42 +0000 |
commit | 6c91641271e536ffaa88a1dff5127e42ee99a91e (patch) | |
tree | 703d9dd49602377ddc90cbf886aad37913f2496b /chromium/net/der | |
parent | b145b7fafd36f0c260d6a768c81fc14e32578099 (diff) | |
download | qtwebengine-chromium-6c91641271e536ffaa88a1dff5127e42ee99a91e.tar.gz |
BASELINE: Update Chromium to 49.0.2623.23
Also adds missing printing sources.
Change-Id: I3726b8f0c7d6751c9fc846096c571fadca7108cd
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/net/der')
-rw-r--r-- | chromium/net/der/input.cc | 17 | ||||
-rw-r--r-- | chromium/net/der/input.h | 27 | ||||
-rw-r--r-- | chromium/net/der/input_unittest.cc | 14 | ||||
-rw-r--r-- | chromium/net/der/parse_values.cc | 54 | ||||
-rw-r--r-- | chromium/net/der/parse_values.h | 15 | ||||
-rw-r--r-- | chromium/net/der/parse_values_unittest.cc | 50 | ||||
-rw-r--r-- | chromium/net/der/parser.h | 5 | ||||
-rw-r--r-- | chromium/net/der/tag.cc | 8 | ||||
-rw-r--r-- | chromium/net/der/tag.h | 6 |
9 files changed, 182 insertions, 14 deletions
diff --git a/chromium/net/der/input.cc b/chromium/net/der/input.cc index 75d1c9c1847..871f9f4ec7d 100644 --- a/chromium/net/der/input.cc +++ b/chromium/net/der/input.cc @@ -4,6 +4,8 @@ #include <string.h> +#include <algorithm> + #include "base/logging.h" #include "net/der/input.h" @@ -17,6 +19,11 @@ Input::Input() : data_(nullptr), len_(0) { Input::Input(const uint8_t* data, size_t len) : data_(data), len_(len) { } +Input::Input(const base::StringPiece& in) + : data_(reinterpret_cast<const uint8_t*>(in.data())), len_(in.length()) {} + +Input::Input(const std::string* s) : Input(base::StringPiece(*s)) {} + bool Input::Equals(const Input& other) const { if (len_ != other.len_) return false; @@ -27,6 +34,16 @@ std::string Input::AsString() const { return std::string(reinterpret_cast<const char*>(data_), len_); } +base::StringPiece Input::AsStringPiece() const { + return base::StringPiece(reinterpret_cast<const char*>(data_), len_); +} + +bool operator<(const Input& lhs, const Input& rhs) { + return std::lexicographical_compare( + lhs.UnsafeData(), lhs.UnsafeData() + lhs.Length(), rhs.UnsafeData(), + rhs.UnsafeData() + rhs.Length()); +} + ByteReader::ByteReader(const Input& in) : data_(in.UnsafeData()), len_(in.Length()) { } diff --git a/chromium/net/der/input.h b/chromium/net/der/input.h index c0195ff15f8..9c3f5ca87a4 100644 --- a/chromium/net/der/input.h +++ b/chromium/net/der/input.h @@ -5,10 +5,13 @@ #ifndef NET_DER_INPUT_H_ #define NET_DER_INPUT_H_ +#include <stddef.h> #include <stdint.h> + #include <string> #include "base/compiler_specific.h" +#include "base/strings/string_piece.h" #include "net/base/net_export.h" namespace net { @@ -47,7 +50,15 @@ class NET_EXPORT_PRIVATE Input { : data_(data), len_(N) {} // Creates an Input from the given |data| and |len|. - Input(const uint8_t* data, size_t len); + explicit Input(const uint8_t* data, size_t len); + + // Creates an Input from a base::StringPiece. + explicit Input(const base::StringPiece& sp); + + // Creates an Input from a std::string. The lifetimes are a bit subtle when + // using this function: The constructed Input is only valid so long as |s| is + // still alive and not mutated. + Input(const std::string* s); // Returns the length in bytes of an Input's data. size_t Length() const { return len_; } @@ -64,11 +75,25 @@ class NET_EXPORT_PRIVATE Input { // Returns a copy of the data represented by this object as a std::string. std::string AsString() const; + // Returns a StringPiece pointing to the same data as the Input. The resulting + // StringPiece must not outlive the data that was used to construct this + // Input. + base::StringPiece AsStringPiece() const; + private: + // This constructor is deleted to prevent constructing an Input from a + // std::string r-value. Since the Input points to memory owned by another + // object, such an Input would point to invalid memory. Without this deleted + // constructor, a std::string could be passed in to the base::StringPiece + // constructor because of StringPiece's implicit constructor. + Input(std::string) = delete; const uint8_t* data_; size_t len_; }; +// Returns true if |lhs|'s data is lexicographically less than |rhs|'s data. +NET_EXPORT_PRIVATE bool operator<(const Input& lhs, const Input& rhs); + // This class provides ways to read data from an Input in a bounds-checked way. // The ByteReader is designed to read through the input sequentially. Once a // byte has been read with a ByteReader, the caller can't go back and re-read diff --git a/chromium/net/der/input_unittest.cc b/chromium/net/der/input_unittest.cc index 63fe715c33e..e7193b08b52 100644 --- a/chromium/net/der/input_unittest.cc +++ b/chromium/net/der/input_unittest.cc @@ -11,6 +11,7 @@ namespace der { namespace test { const uint8_t kInput[] = {'t', 'e', 's', 't'}; +const uint8_t kInput2[] = {'t', 'e', 'a', 'l'}; TEST(InputTest, Equals) { Input test(kInput); @@ -27,6 +28,19 @@ TEST(InputTest, Equals) { EXPECT_FALSE(test_truncated.Equals(test)); } +TEST(InputTest, LessThan) { + Input test(kInput); + EXPECT_FALSE(test < test); + + Input test2(kInput2); + EXPECT_FALSE(test < test2); + EXPECT_TRUE(test2 < test); + + Input test_truncated(kInput, arraysize(kInput) - 1); + EXPECT_FALSE(test < test_truncated); + EXPECT_TRUE(test_truncated < test); +} + TEST(InputTest, AsString) { Input input(kInput); std::string expected_string(reinterpret_cast<const char*>(kInput), diff --git a/chromium/net/der/parse_values.cc b/chromium/net/der/parse_values.cc index 7920d9fc89d..a2df4b8af65 100644 --- a/chromium/net/der/parse_values.cc +++ b/chromium/net/der/parse_values.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <tuple> + #include "base/logging.h" #include "base/numerics/safe_math.h" #include "net/der/parse_values.h" @@ -191,10 +193,48 @@ bool ParseUint64(const Input& in, uint64_t* out) { return true; } +bool ParseUint8(const Input& in, uint8_t* out) { + // TODO(eroman): Implement this more directly. + uint64_t value; + if (!ParseUint64(in, &value)) + return false; + + if (value > 0xFF) + return false; + + *out = static_cast<uint8_t>(value); + return true; +} + BitString::BitString(const Input& bytes, uint8_t unused_bits) : bytes_(bytes), unused_bits_(unused_bits) { DCHECK_LT(unused_bits, 8); DCHECK(unused_bits == 0 || bytes.Length() != 0); + // The unused bits must be zero. + DCHECK(bytes.Length() == 0 || + (bytes.UnsafeData()[bytes.Length() - 1] & ((1u << unused_bits) - 1)) == + 0); +} + +bool BitString::AssertsBit(size_t bit_index) const { + // Index of the byte that contains the bit. + size_t byte_index = bit_index / 8; + + // If the bit is outside of the bitstring, by definition it is not + // asserted. + if (byte_index >= bytes_.Length()) + return false; + + // Within a byte, bits are ordered from most significant to least significant. + // Convert |bit_index| to an index within the |byte_index| byte, measured from + // its least significant bit. + uint8_t bit_index_in_byte = 7 - (bit_index - byte_index * 8); + + // BIT STRING parsing already guarantees that unused bits in a byte are zero + // (otherwise it wouldn't be valid DER). Therefore it isn't necessary to check + // |unused_bits_| + uint8_t byte = bytes_.UnsafeData()[byte_index]; + return 0 != (byte & (1 << bit_index_in_byte)); } bool ParseBitString(const Input& in, BitString* out) { @@ -239,17 +279,9 @@ bool ParseBitString(const Input& in, BitString* out) { } bool operator<(const GeneralizedTime& lhs, const GeneralizedTime& rhs) { - if (lhs.year != rhs.year) - return lhs.year < rhs.year; - if (lhs.month != rhs.month) - return lhs.month < rhs.month; - if (lhs.day != rhs.day) - return lhs.day < rhs.day; - if (lhs.hours != rhs.hours) - return lhs.hours < rhs.hours; - if (lhs.minutes != rhs.minutes) - return lhs.minutes < rhs.minutes; - return lhs.seconds < rhs.seconds; + return std::tie(lhs.year, lhs.month, lhs.day, lhs.hours, lhs.minutes, + lhs.seconds) < std::tie(rhs.year, rhs.month, rhs.day, + rhs.hours, rhs.minutes, rhs.seconds); } // A UTC Time in DER encoding should be YYMMDDHHMMSSZ, but some CAs encode diff --git a/chromium/net/der/parse_values.h b/chromium/net/der/parse_values.h index 27a6f5fb7fc..4f503566dfd 100644 --- a/chromium/net/der/parse_values.h +++ b/chromium/net/der/parse_values.h @@ -5,6 +5,8 @@ #ifndef NET_DER_PARSE_VALUES_H_ #define NET_DER_PARSE_VALUES_H_ +#include <stdint.h> + #include "base/compiler_specific.h" #include "net/base/net_export.h" #include "net/der/input.h" @@ -41,6 +43,9 @@ NET_EXPORT bool IsValidInteger(const Input& in, // integer. NET_EXPORT bool ParseUint64(const Input& in, uint64_t* out) WARN_UNUSED_RESULT; +// Same as ParseUint64() but for a uint8_t. +NET_EXPORT bool ParseUint8(const Input& in, uint8_t* out) WARN_UNUSED_RESULT; + // The BitString class is a helper for representing a valid parsed BIT STRING. // // * The bits are ordered within each octet of bytes() from most to least @@ -59,6 +64,14 @@ class NET_EXPORT BitString { const Input& bytes() const { return bytes_; } uint8_t unused_bits() const { return unused_bits_; } + // Returns true if the bit string contains 1 at the specified position. + // Otherwise returns false. + // + // A return value of false can mean either: + // * The bit value at |bit_index| is 0. + // * There is no bit at |bit_index| (index is beyond the end). + bool AssertsBit(size_t bit_index) const WARN_UNUSED_RESULT; + private: Input bytes_; uint8_t unused_bits_; @@ -100,7 +113,7 @@ NET_EXPORT bool ParseUTCTimeRelaxed(const Input& in, // Reads a DER-encoded ASN.1 GeneralizedTime value from |in| and puts the // resulting value in |out|, returning true if the GeneralizedTime could -// be parsed sucessfully. This function is even more restrictive than the +// be parsed successfully. This function is even more restrictive than the // DER rules - it follows the rules from RFC5280, which does not allow for // fractional seconds. NET_EXPORT bool ParseGeneralizedTime(const Input& in, diff --git a/chromium/net/der/parse_values_unittest.cc b/chromium/net/der/parse_values_unittest.cc index b76c4c99c8d..b29634f15ac 100644 --- a/chromium/net/der/parse_values_unittest.cc +++ b/chromium/net/der/parse_values_unittest.cc @@ -214,6 +214,42 @@ TEST(ParseValuesTest, ParseUint64) { } } +struct Uint8TestData { + bool should_pass; + const uint8_t input[9]; + size_t length; + uint8_t expected_value; +}; + +const Uint8TestData kUint8TestData[] = { + {true, {0x00}, 1, 0}, + // This number fails because it is not a minimal representation. + {false, {0x00, 0x00}, 2}, + {true, {0x01}, 1, 1}, + {false, {0x01, 0xFF}, 2}, + {false, {0x03, 0x83}, 2}, + {true, {0x7F}, 1, 0x7F}, + {true, {0x00, 0xFF}, 2, 0xFF}, + // This number fails because it is negative. + {false, {0xFF}, 1}, + {false, {0x80}, 1}, + {false, {0x00, 0x01}, 2}, + {false, {0}, 0}, +}; + +TEST(ParseValuesTest, ParseUint8) { + for (size_t i = 0; i < arraysize(kUint8TestData); i++) { + const Uint8TestData& test_case = kUint8TestData[i]; + SCOPED_TRACE(i); + + uint8_t result; + EXPECT_EQ(test_case.should_pass, + ParseUint8(Input(test_case.input, test_case.length), &result)); + if (test_case.should_pass) + EXPECT_EQ(test_case.expected_value, result); + } +} + struct IsValidIntegerTestData { bool should_pass; const uint8_t input[2]; @@ -269,6 +305,10 @@ TEST(ParseValuesTest, ParseBitStringEmptyNoUnusedBits) { EXPECT_EQ(0u, bit_string.unused_bits()); EXPECT_EQ(0u, bit_string.bytes().Length()); + + EXPECT_FALSE(bit_string.AssertsBit(0)); + EXPECT_FALSE(bit_string.AssertsBit(1)); + EXPECT_FALSE(bit_string.AssertsBit(3)); } // Tests parsing an empty BIT STRING that incorrectly claims one unused bit. @@ -298,6 +338,16 @@ TEST(ParseValuesTest, ParseBitStringSevenOneBits) { EXPECT_EQ(1u, bit_string.unused_bits()); EXPECT_EQ(1u, bit_string.bytes().Length()); EXPECT_EQ(0xFE, bit_string.bytes().UnsafeData()[0]); + + EXPECT_TRUE(bit_string.AssertsBit(0)); + EXPECT_TRUE(bit_string.AssertsBit(1)); + EXPECT_TRUE(bit_string.AssertsBit(2)); + EXPECT_TRUE(bit_string.AssertsBit(3)); + EXPECT_TRUE(bit_string.AssertsBit(4)); + EXPECT_TRUE(bit_string.AssertsBit(5)); + EXPECT_TRUE(bit_string.AssertsBit(6)); + EXPECT_FALSE(bit_string.AssertsBit(7)); + EXPECT_FALSE(bit_string.AssertsBit(8)); } // Tests parsing a BIT STRING of 7 bits each of which are 1. The unused bit diff --git a/chromium/net/der/parser.h b/chromium/net/der/parser.h index 37f1f856c4c..2192371d6c6 100644 --- a/chromium/net/der/parser.h +++ b/chromium/net/der/parser.h @@ -5,7 +5,10 @@ #ifndef NET_DER_PARSER_H_ #define NET_DER_PARSER_H_ +#include <stdint.h> + #include "base/compiler_specific.h" +#include "base/macros.h" #include "base/time/time.h" #include "net/base/net_export.h" #include "net/der/input.h" @@ -146,7 +149,7 @@ class NET_EXPORT Parser { // Expects the current tag to be kInteger, and calls ParseUint64 on the // current value. Note that DER-encoded integers are arbitrary precision, // so this method will fail for valid input that represents an integer - // outside the range of an int64. + // outside the range of an int64_t. // // Note that on failure the Parser is left in an undefined state (the // input may or may not have been advanced). diff --git a/chromium/net/der/tag.cc b/chromium/net/der/tag.cc index a8240243943..99acf8cdfd8 100644 --- a/chromium/net/der/tag.cc +++ b/chromium/net/der/tag.cc @@ -20,10 +20,18 @@ Tag ContextSpecificPrimitive(uint8_t base) { return (base & kTagNumberMask) | kTagPrimitive | kTagContextSpecific; } +bool IsContextSpecific(Tag tag) { + return (tag & kTagClassMask) == kTagContextSpecific; +} + bool IsConstructed(Tag tag) { return (tag & kTagConstructionMask) == kTagConstructed; } +uint8_t GetTagNumber(Tag tag) { + return tag & kTagNumberMask; +} + } // namespace der } // namespace net diff --git a/chromium/net/der/tag.h b/chromium/net/der/tag.h index 4f8752b6173..cb18ac6a7c1 100644 --- a/chromium/net/der/tag.h +++ b/chromium/net/der/tag.h @@ -28,6 +28,7 @@ const Tag kBitString = 0x03; const Tag kOctetString = 0x04; const Tag kNull = 0x05; const Tag kOid = 0x06; +const Tag kEnumerated = 0x0A; const Tag kUtf8String = 0x0C; const Tag kPrintableString = 0x13; const Tag kIA5String = 0x16; @@ -65,8 +66,13 @@ const uint8_t kTagClassMask = 0xC0; NET_EXPORT Tag ContextSpecificConstructed(uint8_t class_number); NET_EXPORT Tag ContextSpecificPrimitive(uint8_t base); + +NET_EXPORT bool IsContextSpecific(Tag tag); + NET_EXPORT bool IsConstructed(Tag tag); +NET_EXPORT uint8_t GetTagNumber(Tag tag); + } // namespace der } // namespace net |