summaryrefslogtreecommitdiff
path: root/chromium/net/der
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-01-25 11:39:07 +0100
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2016-01-25 15:20:42 +0000
commit6c91641271e536ffaa88a1dff5127e42ee99a91e (patch)
tree703d9dd49602377ddc90cbf886aad37913f2496b /chromium/net/der
parentb145b7fafd36f0c260d6a768c81fc14e32578099 (diff)
downloadqtwebengine-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.cc17
-rw-r--r--chromium/net/der/input.h27
-rw-r--r--chromium/net/der/input_unittest.cc14
-rw-r--r--chromium/net/der/parse_values.cc54
-rw-r--r--chromium/net/der/parse_values.h15
-rw-r--r--chromium/net/der/parse_values_unittest.cc50
-rw-r--r--chromium/net/der/parser.h5
-rw-r--r--chromium/net/der/tag.cc8
-rw-r--r--chromium/net/der/tag.h6
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