Make der::Input a little closer to Span
This adds a bunch of methods from Span, with the end goal of eventually
making it into a typedef for Span<const uint8_t>. In doing so, this
makes Input implicitly convertible to Span<const uint8_t> and every
other span<const uint8_t> type. For the other direction, I've removed
the 'explicit' marker on the Input(Span) constructor.
I've kept the older spellings around to avoid forcing us to fix it all
at once, but after this rolls in to various places, the next things to
do would be:
1. Go through downstream code and switch them to using the span-like
spellings. Better yet, have them just pass to their own span type.
2. Since Input <-> Span converts implicitly, we can freely start making
our APIs take Span instead of Input. Also start cleaning up a bunch
of now unnecessary explicit der::Input(foo) calls now that, like
span, it's implicit.
3. Decide what to do with the char vs uint8_t disaster. I'm thinking we
add free functions to convert between the two.
In doing so, I've also switched some easy places to use more span-y
APIs.
Bug: 661
Change-Id: I731bb110a4fdadd99cb2894e48f016f0b19110ac
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/65668
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Reviewed-by: Matt Mueller <mattm@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/include/openssl/span.h b/include/openssl/span.h
index 044ada1..dd66f88 100644
--- a/include/openssl/span.h
+++ b/include/openssl/span.h
@@ -81,8 +81,6 @@
template <typename T>
class Span : private internal::SpanBase<const T> {
private:
- static const size_t npos = static_cast<size_t>(-1);
-
// Heuristically test whether C is a container type that can be converted into
// a Span by checking for data() and size() member functions.
//
@@ -93,6 +91,19 @@
std::is_integral<decltype(std::declval<C>().size())>::value>;
public:
+ static const size_t npos = static_cast<size_t>(-1);
+
+ using element_type = T;
+ using value_type = std::remove_cv_t<T>;
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+ using pointer = T *;
+ using const_pointer = const T *;
+ using reference = T &;
+ using const_reference = const T &;
+ using iterator = T *;
+ using const_iterator = const T *;
+
constexpr Span() : Span(nullptr, 0) {}
constexpr Span(T *ptr, size_t len) : data_(ptr), size_(len) {}
@@ -113,10 +124,10 @@
constexpr size_t size() const { return size_; }
constexpr bool empty() const { return size_ == 0; }
- constexpr T *begin() const { return data_; }
- constexpr const T *cbegin() const { return data_; }
- constexpr T *end() const { return data_ + size_; }
- constexpr const T *cend() const { return end(); }
+ constexpr iterator begin() const { return data_; }
+ constexpr const_iterator cbegin() const { return data_; }
+ constexpr iterator end() const { return data_ + size_; }
+ constexpr const_iterator cend() const { return end(); }
constexpr T &front() const {
if (size_ == 0) {
diff --git a/pki/cert_error_params.cc b/pki/cert_error_params.cc
index 8d0ab42..5919c1c 100644
--- a/pki/cert_error_params.cc
+++ b/pki/cert_error_params.cc
@@ -43,9 +43,11 @@
static void AppendDer(const char *name, const std::string &der,
std::string *out) {
*out += name;
+ // TODO(crbug.com/boringssl/661): Introduce a convenience function to go
+ // from a Span<const char> to a Span<const uint8_t>.
*out +=
- ": " + bssl::string_util::HexEncode(
- reinterpret_cast<const uint8_t *>(der.data()), der.size());
+ ": " + bssl::string_util::HexEncode(MakeConstSpan(
+ reinterpret_cast<const uint8_t *>(der.data()), der.size()));
}
const char *name1_;
diff --git a/pki/general_names.cc b/pki/general_names.cc
index a881c11..9c7ccc6 100644
--- a/pki/general_names.cc
+++ b/pki/general_names.cc
@@ -170,8 +170,8 @@
// version 4, as specified in [RFC791], the octet string MUST contain
// exactly four octets. For IP version 6, as specified in [RFC2460],
// the octet string MUST contain exactly sixteen octets.
- if ((value.Length() != kIPv4AddressSize &&
- value.Length() != kIPv6AddressSize)) {
+ if ((value.size() != kIPv4AddressSize &&
+ value.size() != kIPv6AddressSize)) {
errors->AddError(kFailedParsingIp);
return false;
}
@@ -188,14 +188,13 @@
// constraint for "class C" subnet 192.0.2.0 is represented as the
// octets C0 00 02 00 FF FF FF 00, representing the CIDR notation
// 192.0.2.0/24 (mask 255.255.255.0).
- if (value.Length() != kIPv4AddressSize * 2 &&
- value.Length() != kIPv6AddressSize * 2) {
+ if (value.size() != kIPv4AddressSize * 2 &&
+ value.size() != kIPv6AddressSize * 2) {
errors->AddError(kFailedParsingIp);
return false;
}
- der::Input addr(value.UnsafeData(), value.Length() / 2);
- der::Input mask(value.UnsafeData() + value.Length() / 2,
- value.Length() / 2);
+ der::Input addr = value.first(value.size() / 2);
+ der::Input mask = value.subspan(value.size() / 2);
if (!IsValidNetmask(mask)) {
errors->AddError(kFailedParsingIp);
return false;
diff --git a/pki/input.cc b/pki/input.cc
index 12ee450..e8c6656 100644
--- a/pki/input.cc
+++ b/pki/input.cc
@@ -4,8 +4,6 @@
#include "input.h"
-#include <algorithm>
-
#include <openssl/base.h>
namespace bssl::der {
@@ -20,42 +18,38 @@
data_.size());
}
-bssl::Span<const uint8_t> Input::AsSpan() const { return data_; }
-
bool operator==(const Input &lhs, const Input &rhs) {
- return lhs.AsSpan() == rhs.AsSpan();
+ return MakeConstSpan(lhs) == MakeConstSpan(rhs);
}
bool operator!=(const Input &lhs, const Input &rhs) { return !(lhs == rhs); }
-ByteReader::ByteReader(const Input &in)
- : data_(in.UnsafeData()), len_(in.Length()) {}
+ByteReader::ByteReader(Input in) : data_(in) {}
bool ByteReader::ReadByte(uint8_t *byte_p) {
if (!HasMore()) {
return false;
}
- *byte_p = *data_;
+ *byte_p = data_[0];
Advance(1);
return true;
}
bool ByteReader::ReadBytes(size_t len, Input *out) {
- if (len > len_) {
+ if (len > data_.size()) {
return false;
}
- *out = Input(data_, len);
+ *out = Input(data_.first(len));
Advance(len);
return true;
}
// Returns whether there is any more data to be read.
-bool ByteReader::HasMore() { return len_ > 0; }
+bool ByteReader::HasMore() { return !data_.empty(); }
void ByteReader::Advance(size_t len) {
- BSSL_CHECK(len <= len_);
- data_ += len;
- len_ -= len;
+ BSSL_CHECK(len <= data_.size());
+ data_ = data_.subspan(len);
}
} // namespace bssl::der
diff --git a/pki/input.h b/pki/input.h
index 2f61a33..8d006a9 100644
--- a/pki/input.h
+++ b/pki/input.h
@@ -26,6 +26,10 @@
// difficult to read memory outside of an Input. ByteReader provides a simple
// API for reading through the Input sequentially. For more complicated uses,
// multiple instances of a ByteReader for a particular Input can be created.
+//
+// TODO(crbug.com/boringssl/661): This class will gradually be replaced with
+// bssl::Span<const uint8_t>. Avoid relying on APIs that are not part of
+// bssl::Span.
class OPENSSL_EXPORT Input {
public:
// Creates an empty Input, one from which no data can be read.
@@ -34,29 +38,36 @@
// Creates an Input from a span. The constructed Input is only valid as long
// as |data| points to live memory. If constructed from, say, a
// |std::vector<uint8_t>|, mutating the vector will invalidate the Input.
- constexpr explicit Input(bssl::Span<const uint8_t> data) : data_(data) {}
+ constexpr Input(bssl::Span<const uint8_t> data) : data_(data) {}
// Creates an Input from the given |data| and |len|.
constexpr explicit Input(const uint8_t *data, size_t len)
- : data_(bssl::MakeConstSpan(data, len)) {}
+ : data_(MakeConstSpan(data, len)) {}
// Creates an Input from a std::string_view. The constructed Input is only
// valid as long as |data| points to live memory. If constructed from, say, a
// |std::string|, mutating the vector will invalidate the Input.
explicit Input(std::string_view str)
- : data_(bssl::MakeConstSpan(reinterpret_cast<const uint8_t *>(str.data()),
- str.size())) {}
+ : data_(MakeConstSpan(reinterpret_cast<const uint8_t *>(str.data()),
+ str.size())) {}
- // Returns the length in bytes of an Input's data.
- constexpr size_t Length() const { return data_.size(); }
-
- // Returns a pointer to the Input's data. This method is marked as "unsafe"
- // because access to the Input's data should be done through ByteReader
- // instead. This method should only be used where using a ByteReader truly
- // is not an option.
- constexpr const uint8_t *UnsafeData() const { return data_.data(); }
-
+ // The following APIs have the same semantics as in |bssl::Span|.
+ constexpr Span<const uint8_t>::iterator begin() const {
+ return data_.begin();
+ }
+ constexpr Span<const uint8_t>::iterator end() const { return data_.end(); }
+ constexpr const uint8_t *data() const { return data_.data(); }
+ constexpr size_t size() const { return data_.size(); }
+ constexpr bool empty() const { return data_.empty(); }
constexpr uint8_t operator[](size_t idx) const { return data_[idx]; }
+ constexpr uint8_t front() const { return data_.front(); }
+ constexpr uint8_t back() const { return data_.back(); }
+ constexpr Input subspan(size_t pos = 0,
+ size_t len = Span<const uint8_t>::npos) const {
+ return Input(data_.subspan(pos, len));
+ }
+ constexpr Input first(size_t len) const { return Input(data_.first(len)); }
+ constexpr Input last(size_t len) const { return Input(data_.last(len)); }
// Returns a copy of the data represented by this object as a std::string.
std::string AsString() const;
@@ -66,13 +77,21 @@
// this Input.
std::string_view AsStringView() const;
+ // Deprecated: This class implicitly converts to bssl::Span<const uint8_t>.
+ //
// Returns a span pointing to the same data as the Input. The resulting span
// must not outlive the data that was used to construct this Input.
- bssl::Span<const uint8_t> AsSpan() const;
+ Span<const uint8_t> AsSpan() const { return *this; }
+
+ // Deprecated: Use size() instead.
+ constexpr size_t Length() const { return size(); }
+
+ // Deprecated: Use data() instead.
+ constexpr const uint8_t *UnsafeData() const { return data(); }
private:
// TODO(crbug.com/770501): Replace this type with span altogether.
- bssl::Span<const uint8_t> data_;
+ Span<const uint8_t> data_;
};
// Return true if |lhs|'s data and |rhs|'s data are byte-wise equal.
@@ -85,10 +104,10 @@
OPENSSL_EXPORT constexpr bool operator<(const Input &lhs, const Input &rhs) {
// This is `std::lexicographical_compare`, but that's not `constexpr` until
// C++-20.
- auto *it1 = lhs.UnsafeData();
- auto *it2 = rhs.UnsafeData();
- const auto *end1 = lhs.UnsafeData() + lhs.Length();
- const auto *end2 = rhs.UnsafeData() + rhs.Length();
+ auto *it1 = lhs.data();
+ auto *it2 = rhs.data();
+ const auto *end1 = lhs.data() + lhs.size();
+ const auto *end2 = rhs.data() + rhs.size();
for (; it1 != end1 && it2 != end2; ++it1, ++it2) {
if (*it1 < *it2) {
return true;
@@ -119,7 +138,7 @@
class OPENSSL_EXPORT ByteReader {
public:
// Creates a ByteReader to read the data represented by an Input.
- explicit ByteReader(const Input &in);
+ explicit ByteReader(Input in);
// Reads a single byte from the input source, putting the byte read in
// |*byte_p|. If a byte cannot be read from the input (because there is
@@ -132,7 +151,7 @@
[[nodiscard]] bool ReadBytes(size_t len, Input *out);
// Returns how many bytes are left to read.
- size_t BytesLeft() const { return len_; }
+ size_t BytesLeft() const { return data_.size(); }
// Returns whether there is any more data to be read.
bool HasMore();
@@ -140,8 +159,7 @@
private:
void Advance(size_t len);
- const uint8_t *data_;
- size_t len_;
+ bssl::Span<const uint8_t> data_;
};
} // namespace bssl::der
diff --git a/pki/input_unittest.cc b/pki/input_unittest.cc
index 42a7cdb..655a808 100644
--- a/pki/input_unittest.cc
+++ b/pki/input_unittest.cc
@@ -48,7 +48,7 @@
TEST(InputTest, StaticArray) {
Input input(kInput);
- EXPECT_EQ(std::size(kInput), input.Length());
+ EXPECT_EQ(std::size(kInput), input.size());
Input input2(kInput);
EXPECT_EQ(input, input2);
@@ -56,17 +56,17 @@
TEST(InputTest, ConstExpr) {
constexpr Input default_input;
- static_assert(default_input.Length() == 0);
- static_assert(default_input.UnsafeData() == nullptr);
+ static_assert(default_input.size() == 0);
+ static_assert(default_input.data() == nullptr);
constexpr Input const_array_input(kInput);
- static_assert(const_array_input.Length() == 4);
- static_assert(const_array_input.UnsafeData() == kInput);
+ static_assert(const_array_input.size() == 4);
+ static_assert(const_array_input.data() == kInput);
static_assert(default_input < const_array_input);
constexpr Input ptr_len_input(kInput, 2);
- static_assert(ptr_len_input.Length() == 2);
- static_assert(ptr_len_input.UnsafeData() == kInput);
+ static_assert(ptr_len_input.size() == 2);
+ static_assert(ptr_len_input.data() == kInput);
static_assert(ptr_len_input < const_array_input);
Input runtime_input(kInput2, 2);
diff --git a/pki/ip_util.cc b/pki/ip_util.cc
index 1983633..663669e 100644
--- a/pki/ip_util.cc
+++ b/pki/ip_util.cc
@@ -7,11 +7,11 @@
namespace bssl {
bool IsValidNetmask(der::Input mask) {
- if (mask.Length() != kIPv4AddressSize && mask.Length() != kIPv6AddressSize) {
+ if (mask.size() != kIPv4AddressSize && mask.size() != kIPv6AddressSize) {
return false;
}
- for (size_t i = 0; i < mask.Length(); i++) {
+ for (size_t i = 0; i < mask.size(); i++) {
uint8_t b = mask[i];
if (b != 0xff) {
// b must be all ones followed by all zeros, so ~b must be all zeros
@@ -21,7 +21,7 @@
return false;
}
// The remaining bytes must be all zeros.
- for (size_t j = i + 1; j < mask.Length(); j++) {
+ for (size_t j = i + 1; j < mask.size(); j++) {
if (mask[j] != 0) {
return false;
}
@@ -35,10 +35,10 @@
bool IPAddressMatchesWithNetmask(der::Input addr1, der::Input addr2,
der::Input mask) {
- if (addr1.Length() != addr2.Length() || addr1.Length() != mask.Length()) {
+ if (addr1.size() != addr2.size() || addr1.size() != mask.size()) {
return false;
}
- for (size_t i = 0; i < addr1.Length(); i++) {
+ for (size_t i = 0; i < addr1.size(); i++) {
if ((addr1[i] & mask[i]) != (addr2[i] & mask[i])) {
return false;
}
diff --git a/pki/name_constraints.cc b/pki/name_constraints.cc
index 6de5b50..6885fd4 100644
--- a/pki/name_constraints.cc
+++ b/pki/name_constraints.cc
@@ -381,7 +381,7 @@
} else {
constraint_count += excluded_subtrees_.directory_names.size() +
permitted_subtrees_.directory_names.size();
- name_count = subject_rdn_sequence.Length();
+ name_count = subject_rdn_sequence.size();
}
// Upper bound the number of possible checks, checking for overflow.
size_t check_count = constraint_count * name_count;
@@ -502,7 +502,7 @@
// This code assumes that criticality condition is checked by the caller, and
// therefore only needs to avoid the IsPermittedDirectoryName check against an
// empty subject in such a case.
- if (subject_alt_names && subject_rdn_sequence.Length() == 0) {
+ if (subject_alt_names && subject_rdn_sequence.empty()) {
return;
}
diff --git a/pki/ocsp.cc b/pki/ocsp.cc
index 54afab5..cdbf202 100644
--- a/pki/ocsp.cc
+++ b/pki/ocsp.cc
@@ -164,7 +164,7 @@
uint8_t hash_buffer[EVP_MAX_MD_SIZE];
return CBB_add_asn1(cbb, &octet_string, CBS_ASN1_OCTETSTRING) &&
- EVP_Digest(value.UnsafeData(), value.Length(), hash_buffer, &hash_len,
+ EVP_Digest(value.data(), value.size(), hash_buffer, &hash_len,
hash_type, nullptr) &&
CBB_add_bytes(&octet_string, hash_buffer, hash_len) && CBB_flush(cbb);
}
@@ -256,7 +256,7 @@
if (key_parser.HasMore()) {
return false;
}
- if (key_hash.Length() != SHA_DIGEST_LENGTH) {
+ if (key_hash.size() != SHA_DIGEST_LENGTH) {
return false;
}
@@ -498,8 +498,8 @@
const der::Input &value) {
unsigned value_hash_len;
uint8_t value_hash[EVP_MAX_MD_SIZE];
- if (!EVP_Digest(value.UnsafeData(), value.Length(), value_hash,
- &value_hash_len, type, nullptr)) {
+ if (!EVP_Digest(value.data(), value.size(), value_hash, &value_hash_len, type,
+ nullptr)) {
return false;
}
@@ -524,7 +524,7 @@
bool GetSubjectPublicKeyBytes(const der::Input &spki_tlv, der::Input *spk_tlv) {
CBS outer, inner, alg, spk;
uint8_t unused_bit_count;
- CBS_init(&outer, spki_tlv.UnsafeData(), spki_tlv.Length());
+ CBS_init(&outer, spki_tlv.data(), spki_tlv.size());
// The subjectPublicKey field includes the unused bit count. For this
// application, the unused bit count must be zero, and is not included in
// the result. We extract the subjectPubicKey bit string, verify the first
@@ -1060,8 +1060,8 @@
if (!CBB_add_asn1(&req_cert, &serial_number, CBS_ASN1_INTEGER)) {
return false;
}
- if (!CBB_add_bytes(&serial_number, cert->tbs().serial_number.UnsafeData(),
- cert->tbs().serial_number.Length())) {
+ if (!CBB_add_bytes(&serial_number, cert->tbs().serial_number.data(),
+ cert->tbs().serial_number.size())) {
return false;
}
diff --git a/pki/parse_certificate.cc b/pki/parse_certificate.cc
index 8335f2f..19c7b26 100644
--- a/pki/parse_certificate.cc
+++ b/pki/parse_certificate.cc
@@ -133,8 +133,8 @@
[[nodiscard]] bool BitStringIsAllZeros(const der::BitString &bits) {
// Note that it is OK to read from the unused bits, since BitString parsing
// guarantees they are all zero.
- for (size_t i = 0; i < bits.bytes().Length(); ++i) {
- if (bits.bytes()[i] != 0) {
+ for (uint8_t b : bits.bytes()) {
+ if (b != 0) {
return false;
}
}
@@ -271,7 +271,7 @@
if (negative) {
errors->AddWarning(kSerialNumberIsNegative);
}
- if (value.Length() == 1 && value[0] == 0) {
+ if (value.size() == 1 && value[0] == 0) {
errors->AddWarning(kSerialNumberIsZero);
}
@@ -280,9 +280,9 @@
// Certificate users MUST be able to handle serialNumber values up to 20
// octets. Conforming CAs MUST NOT use serialNumber values longer than 20
// octets.
- if (value.Length() > 20) {
+ if (value.size() > 20) {
errors->Add(error_severity, kSerialNumberLengthOver20,
- CreateCertErrorParams1SizeT("length", value.Length()));
+ CreateCertErrorParams1SizeT("length", value.size()));
return false;
}
diff --git a/pki/parse_name.cc b/pki/parse_name.cc
index 443bc09..3768d52 100644
--- a/pki/parse_name.cc
+++ b/pki/parse_name.cc
@@ -19,7 +19,7 @@
// string on error.
std::string OidToString(der::Input oid) {
CBS cbs;
- CBS_init(&cbs, oid.UnsafeData(), oid.Length());
+ CBS_init(&cbs, oid.data(), oid.size());
bssl::UniquePtr<char> text(CBS_asn1_oid_to_text(&cbs));
if (!text) {
return std::string();
@@ -104,8 +104,7 @@
if (type_string.empty()) {
return false;
}
- value_string =
- "#" + bssl::string_util::HexEncode(value.UnsafeData(), value.Length());
+ value_string = "#" + bssl::string_util::HexEncode(value);
}
if (value_string.empty()) {
@@ -116,7 +115,7 @@
bool nonprintable = false;
for (unsigned int i = 0; i < unescaped.length(); ++i) {
- unsigned char c = static_cast<unsigned char>(unescaped[i]);
+ uint8_t c = static_cast<uint8_t>(unescaped[i]);
if (i == 0 && c == '#') {
value_string += "\\#";
} else if (i == 0 && c == ' ') {
@@ -129,11 +128,8 @@
value_string += c;
} else if (c < 32 || c > 126) {
nonprintable = true;
- std::string h;
- h += c;
value_string +=
- "\\" + bssl::string_util::HexEncode(
- reinterpret_cast<const uint8_t *>(h.data()), h.length());
+ "\\" + bssl::string_util::HexEncode(MakeConstSpan(&c, 1));
} else {
value_string += c;
}
@@ -142,8 +138,7 @@
// If we have non-printable characters in a TeletexString, we hex encode
// since we don't handle Teletex control codes.
if (nonprintable && value_tag == der::kTeletexString) {
- value_string = "#" + bssl::string_util::HexEncode(value.UnsafeData(),
- value.Length());
+ value_string = "#" + bssl::string_util::HexEncode(value);
}
}
diff --git a/pki/parse_values.cc b/pki/parse_values.cc
index cc7a072..b0d9453 100644
--- a/pki/parse_values.cc
+++ b/pki/parse_values.cc
@@ -20,7 +20,7 @@
// According to ITU-T X.690 section 8.2, a bool is encoded as a single octet
// where the octet of all zeroes is FALSE and a non-zero value for the octet
// is TRUE.
- if (in.Length() != 1) {
+ if (in.size() != 1) {
return false;
}
ByteReader data(in);
@@ -128,7 +128,7 @@
// Returns the number of bytes of numeric precision in a DER encoded INTEGER
// value. |in| must be a valid DER encoding of an INTEGER for this to work.
//
-// Normally the precision of the number is exactly in.Length(). However when
+// Normally the precision of the number is exactly in.size(). However when
// encoding positive numbers using DER it is possible to have a leading zero
// (to prevent number from being interpreted as negative).
//
@@ -141,10 +141,10 @@
return 0; // Not valid DER as |in| was empty.
}
- if (first_byte == 0 && in.Length() > 1) {
- return in.Length() - 1;
+ if (first_byte == 0 && in.size() > 1) {
+ return in.size() - 1;
}
- return in.Length();
+ return in.size();
}
} // namespace
@@ -167,7 +167,7 @@
// of the second octet must not be all zeroes or all ones.
bool IsValidInteger(const Input &in, bool *negative) {
CBS cbs;
- CBS_init(&cbs, in.UnsafeData(), in.Length());
+ CBS_init(&cbs, in.data(), in.size());
int negative_int;
if (!CBS_is_valid_asn1_integer(&cbs, &negative_int)) {
return false;
@@ -219,10 +219,9 @@
BitString::BitString(const Input &bytes, uint8_t unused_bits)
: bytes_(bytes), unused_bits_(unused_bits) {
BSSL_CHECK(unused_bits < 8);
- BSSL_CHECK(unused_bits == 0 || bytes.Length() != 0);
+ BSSL_CHECK(unused_bits == 0 || !bytes.empty());
// The unused bits must be zero.
- BSSL_CHECK(bytes.Length() == 0 ||
- (bytes[bytes.Length() - 1] & ((1u << unused_bits) - 1)) == 0);
+ BSSL_CHECK(bytes.empty() || (bytes.back() & ((1u << unused_bits) - 1)) == 0);
}
bool BitString::AssertsBit(size_t bit_index) const {
@@ -231,7 +230,7 @@
// If the bit is outside of the bitstring, by definition it is not
// asserted.
- if (byte_index >= bytes_.Length()) {
+ if (byte_index >= bytes_.size()) {
return false;
}
@@ -274,10 +273,10 @@
//
// If the bitstring is empty, there shall be no subsequent octets,
// and the initial octet shall be zero.
- if (bytes.Length() == 0) {
+ if (bytes.empty()) {
return std::nullopt;
}
- uint8_t last_byte = bytes[bytes.Length() - 1];
+ uint8_t last_byte = bytes.back();
// From ITU-T X.690, section 11.2.1 (applies to CER and DER, but not BER):
//
@@ -403,14 +402,14 @@
bool ParseTeletexStringAsLatin1(Input in, std::string *out) {
out->clear();
// Convert from Latin-1 to UTF-8.
- size_t utf8_length = in.Length();
- for (size_t i = 0; i < in.Length(); i++) {
+ size_t utf8_length = in.size();
+ for (size_t i = 0; i < in.size(); i++) {
if (in[i] > 0x7f) {
utf8_length++;
}
}
out->reserve(utf8_length);
- for (size_t i = 0; i < in.Length(); i++) {
+ for (size_t i = 0; i < in.size(); i++) {
uint8_t u = in[i];
if (u <= 0x7f) {
out->push_back(u);
@@ -424,14 +423,14 @@
}
bool ParseUniversalString(Input in, std::string *out) {
- if (in.Length() % 4 != 0) {
+ if (in.size() % 4 != 0) {
return false;
}
CBS cbs;
- CBS_init(&cbs, in.UnsafeData(), in.Length());
+ CBS_init(&cbs, in.data(), in.size());
bssl::ScopedCBB cbb;
- if (!CBB_init(cbb.get(), in.Length())) {
+ if (!CBB_init(cbb.get(), in.size())) {
return false;
}
@@ -448,14 +447,14 @@
}
bool ParseBmpString(Input in, std::string *out) {
- if (in.Length() % 2 != 0) {
+ if (in.size() % 2 != 0) {
return false;
}
CBS cbs;
- CBS_init(&cbs, in.UnsafeData(), in.Length());
+ CBS_init(&cbs, in.data(), in.size());
bssl::ScopedCBB cbb;
- if (!CBB_init(cbb.get(), in.Length())) {
+ if (!CBB_init(cbb.get(), in.size())) {
return false;
}
diff --git a/pki/parse_values_unittest.cc b/pki/parse_values_unittest.cc
index ee9e481..e29b4b9 100644
--- a/pki/parse_values_unittest.cc
+++ b/pki/parse_values_unittest.cc
@@ -317,7 +317,7 @@
ASSERT_TRUE(bit_string.has_value());
EXPECT_EQ(0u, bit_string->unused_bits());
- EXPECT_EQ(0u, bit_string->bytes().Length());
+ EXPECT_EQ(0u, bit_string->bytes().size());
EXPECT_FALSE(bit_string->AssertsBit(0));
EXPECT_FALSE(bit_string->AssertsBit(1));
@@ -349,7 +349,7 @@
ASSERT_TRUE(bit_string.has_value());
EXPECT_EQ(1u, bit_string->unused_bits());
- EXPECT_EQ(1u, bit_string->bytes().Length());
+ EXPECT_EQ(1u, bit_string->bytes().size());
EXPECT_EQ(0xFE, bit_string->bytes()[0]);
EXPECT_TRUE(bit_string->AssertsBit(0));
diff --git a/pki/parsed_certificate.cc b/pki/parsed_certificate.cc
index 0e8146c..ab05ed9 100644
--- a/pki/parsed_certificate.cc
+++ b/pki/parsed_certificate.cc
@@ -183,7 +183,7 @@
// extension (e.g., a key bound only to an email address or URI), then the
// subject name MUST be an empty sequence and the subjectAltName extension
// MUST be critical.
- if (subject_value.Length() == 0 &&
+ if (subject_value.empty() &&
!result->subject_alt_names_extension_.critical) {
errors->AddError(kSubjectAltNameNotCritical);
return nullptr;
diff --git a/pki/parsed_certificate_unittest.cc b/pki/parsed_certificate_unittest.cc
index 33cd078..2b4d352 100644
--- a/pki/parsed_certificate_unittest.cc
+++ b/pki/parsed_certificate_unittest.cc
@@ -232,7 +232,7 @@
ASSERT_TRUE(cert->GetExtension(der::Input(kExtKeyUsageOid), &extension));
EXPECT_FALSE(extension.critical);
- EXPECT_EQ(45u, extension.value.Length());
+ EXPECT_EQ(45u, extension.value.size());
EXPECT_TRUE(cert->has_extended_key_usage());
EXPECT_EQ(4u, cert->extended_key_usage().size());
@@ -268,7 +268,7 @@
cert->GetExtension(der::Input(kCertificatePoliciesOid), &extension));
EXPECT_FALSE(extension.critical);
- EXPECT_EQ(95u, extension.value.Length());
+ EXPECT_EQ(95u, extension.value.size());
EXPECT_TRUE(cert->has_policy_oids());
EXPECT_EQ(2u, cert->policy_oids().size());
@@ -320,7 +320,7 @@
cert->GetExtension(der::Input(kCertificatePoliciesOid), &extension));
EXPECT_FALSE(extension.critical);
- EXPECT_EQ(16u, extension.value.Length());
+ EXPECT_EQ(16u, extension.value.size());
// TODO(eroman): Verify the other extensions' values.
}
diff --git a/pki/parser.cc b/pki/parser.cc
index 327c239..0fa377a 100644
--- a/pki/parser.cc
+++ b/pki/parser.cc
@@ -12,7 +12,7 @@
Parser::Parser() { CBS_init(&cbs_, nullptr, 0); }
Parser::Parser(const Input &input) {
- CBS_init(&cbs_, input.UnsafeData(), input.Length());
+ CBS_init(&cbs_, input.data(), input.size());
}
bool Parser::PeekTagAndValue(Tag *tag, Input *out) {
diff --git a/pki/parser_unittest.cc b/pki/parser_unittest.cc
index e510a93..e813bfd 100644
--- a/pki/parser_unittest.cc
+++ b/pki/parser_unittest.cc
@@ -347,7 +347,7 @@
EXPECT_FALSE(parser.HasMore());
EXPECT_EQ(1u, bit_string->unused_bits());
- ASSERT_EQ(2u, bit_string->bytes().Length());
+ ASSERT_EQ(2u, bit_string->bytes().size());
EXPECT_EQ(0xAA, bit_string->bytes()[0]);
EXPECT_EQ(0xBE, bit_string->bytes()[1]);
}
diff --git a/pki/path_builder.cc b/pki/path_builder.cc
index 6aa42e7..07ced15 100644
--- a/pki/path_builder.cc
+++ b/pki/path_builder.cc
@@ -32,8 +32,8 @@
// Returns a hex-encoded sha256 of the DER-encoding of |cert|.
std::string FingerPrintParsedCertificate(const bssl::ParsedCertificate *cert) {
uint8_t digest[SHA256_DIGEST_LENGTH];
- SHA256(cert->der_cert().UnsafeData(), cert->der_cert().Length(), digest);
- return bssl::string_util::HexEncode(digest, sizeof(digest));
+ SHA256(cert->der_cert().data(), cert->der_cert().size(), digest);
+ return bssl::string_util::HexEncode(digest);
}
// TODO(mattm): decide how much debug logging to keep.
diff --git a/pki/path_builder_unittest.cc b/pki/path_builder_unittest.cc
index d231358..eaf10d8 100644
--- a/pki/path_builder_unittest.cc
+++ b/pki/path_builder_unittest.cc
@@ -1523,9 +1523,9 @@
// Create a separate copy of oldintermediate.
std::shared_ptr<const ParsedCertificate> oldintermediate_dupe(
ParsedCertificate::Create(
- bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
- oldintermediate_->der_cert().UnsafeData(),
- oldintermediate_->der_cert().Length(), nullptr)),
+ bssl::UniquePtr<CRYPTO_BUFFER>(
+ CRYPTO_BUFFER_new(oldintermediate_->der_cert().data(),
+ oldintermediate_->der_cert().size(), nullptr)),
{}, nullptr));
// Only newroot is a trusted root.
@@ -1590,8 +1590,8 @@
std::shared_ptr<const ParsedCertificate> newroot_dupe(
ParsedCertificate::Create(
bssl::UniquePtr<CRYPTO_BUFFER>(
- CRYPTO_BUFFER_new(newroot_->der_cert().UnsafeData(),
- newroot_->der_cert().Length(), nullptr)),
+ CRYPTO_BUFFER_new(newroot_->der_cert().data(),
+ newroot_->der_cert().size(), nullptr)),
{}, nullptr));
// Only newroot is a trusted root.
@@ -1785,8 +1785,8 @@
std::shared_ptr<const ParsedCertificate> oldintermediate_dupe(
ParsedCertificate::Create(
bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
- oldintermediate_->der_cert().UnsafeData(),
- oldintermediate_->der_cert().Length(), nullptr)),
+ oldintermediate_->der_cert().data(),
+ oldintermediate_->der_cert().size(), nullptr)),
{}, nullptr));
EXPECT_CALL(*target_issuers_req, GetNext(_))
diff --git a/pki/signature_algorithm.cc b/pki/signature_algorithm.cc
index 341cae5..f68b612 100644
--- a/pki/signature_algorithm.cc
+++ b/pki/signature_algorithm.cc
@@ -122,11 +122,6 @@
const uint8_t kOidMgf1[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x08};
-// Returns true if |input| is empty.
-[[nodiscard]] bool IsEmpty(const der::Input &input) {
- return input.Length() == 0;
-}
-
// Returns true if the entirety of the input is a NULL value.
[[nodiscard]] bool IsNull(const der::Input &input) {
der::Parser parser(input);
@@ -136,7 +131,7 @@
}
// NULL values are TLV encoded; the value is expected to be empty.
- if (!IsEmpty(null_value)) {
+ if (!null_value.empty()) {
return false;
}
@@ -145,7 +140,7 @@
}
[[nodiscard]] bool IsNullOrEmpty(const der::Input &input) {
- return IsNull(input) || IsEmpty(input);
+ return IsNull(input) || input.empty();
}
// Parses a MaskGenAlgorithm as defined by RFC 5912:
@@ -311,7 +306,7 @@
[[nodiscard]] bool ParseHashAlgorithm(const der::Input &input,
DigestAlgorithm *out) {
CBS cbs;
- CBS_init(&cbs, input.UnsafeData(), input.Length());
+ CBS_init(&cbs, input.data(), input.size());
const EVP_MD *md = EVP_parse_digest_algorithm(&cbs);
if (md == EVP_sha1()) {
@@ -365,16 +360,16 @@
// RFC 5912 requires that the parameters for ECDSA algorithms be absent
// ("PARAMS TYPE NULL ARE absent"):
- if (oid == der::Input(kOidEcdsaWithSha1) && IsEmpty(params)) {
+ if (oid == der::Input(kOidEcdsaWithSha1) && params.empty()) {
return SignatureAlgorithm::kEcdsaSha1;
}
- if (oid == der::Input(kOidEcdsaWithSha256) && IsEmpty(params)) {
+ if (oid == der::Input(kOidEcdsaWithSha256) && params.empty()) {
return SignatureAlgorithm::kEcdsaSha256;
}
- if (oid == der::Input(kOidEcdsaWithSha384) && IsEmpty(params)) {
+ if (oid == der::Input(kOidEcdsaWithSha384) && params.empty()) {
return SignatureAlgorithm::kEcdsaSha384;
}
- if (oid == der::Input(kOidEcdsaWithSha512) && IsEmpty(params)) {
+ if (oid == der::Input(kOidEcdsaWithSha512) && params.empty()) {
return SignatureAlgorithm::kEcdsaSha512;
}
diff --git a/pki/string_util.cc b/pki/string_util.cc
index baebc7f..423cd76 100644
--- a/pki/string_util.cc
+++ b/pki/string_util.cc
@@ -71,11 +71,11 @@
return prefix.size() <= str.size() && prefix == str.substr(0, prefix.size());
}
-std::string HexEncode(const uint8_t *data, size_t length) {
+std::string HexEncode(Span<const uint8_t> data) {
std::ostringstream out;
- for (size_t i = 0; i < length; i++) {
+ for (uint8_t b : data) {
out << std::hex << std::setfill('0') << std::setw(2) << std::uppercase
- << int{data[i]};
+ << int{b};
}
return out.str();
}
diff --git a/pki/string_util.h b/pki/string_util.h
index b238c29..27be485 100644
--- a/pki/string_util.h
+++ b/pki/string_util.h
@@ -10,6 +10,7 @@
#include <vector>
#include <openssl/base.h>
+#include <openssl/span.h>
namespace bssl::string_util {
@@ -44,8 +45,8 @@
// Compares |str1| and |suffix|. Returns true if |str1| ends with |suffix|.
OPENSSL_EXPORT bool EndsWith(std::string_view str, std::string_view suffix);
-// Returns a hexadecimal string encoding |data| of length |length|.
-OPENSSL_EXPORT std::string HexEncode(const uint8_t *data, size_t length);
+// Returns a hexadecimal string encoding |data|.
+OPENSSL_EXPORT std::string HexEncode(Span<const uint8_t> data);
// Returns a decimal string representation of |i|.
OPENSSL_EXPORT std::string NumberToDecimalString(int i);
diff --git a/pki/string_util_unittest.cc b/pki/string_util_unittest.cc
index 4929a27..32e446d 100644
--- a/pki/string_util_unittest.cc
+++ b/pki/string_util_unittest.cc
@@ -99,10 +99,10 @@
}
TEST(StringUtilTest, HexEncode) {
- std::string hex(bssl::string_util::HexEncode(nullptr, 0));
+ std::string hex(bssl::string_util::HexEncode({}));
EXPECT_EQ(hex.length(), 0U);
uint8_t bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81};
- hex = bssl::string_util::HexEncode(bytes, sizeof(bytes));
+ hex = bssl::string_util::HexEncode(bytes);
EXPECT_EQ(hex, "01FF02FE038081");
}
diff --git a/pki/test_helpers.cc b/pki/test_helpers.cc
index 3b1b256..d998e56 100644
--- a/pki/test_helpers.cc
+++ b/pki/test_helpers.cc
@@ -47,11 +47,10 @@
// hex-encoded string on error.
std::string OidToString(der::Input oid) {
CBS cbs;
- CBS_init(&cbs, oid.UnsafeData(), oid.Length());
+ CBS_init(&cbs, oid.data(), oid.size());
bssl::UniquePtr<char> text(CBS_asn1_oid_to_text(&cbs));
if (!text) {
- return "invalid:" +
- bssl::string_util::HexEncode(oid.UnsafeData(), oid.Length());
+ return "invalid:" + bssl::string_util::HexEncode(oid);
}
return text.get();
}
@@ -132,12 +131,12 @@
void PrintTo(const Input &data, ::std::ostream *os) {
size_t len;
- if (!EVP_EncodedLength(&len, data.Length())) {
+ if (!EVP_EncodedLength(&len, data.size())) {
*os << "[]";
return;
}
std::vector<uint8_t> encoded(len);
- len = EVP_EncodeBlock(encoded.data(), data.UnsafeData(), data.Length());
+ len = EVP_EncodeBlock(encoded.data(), data.data(), data.size());
// Skip the trailing \0.
std::string b64_encoded(encoded.begin(), encoded.begin() + len);
*os << "[" << b64_encoded << "]";
diff --git a/pki/verify_name_match.cc b/pki/verify_name_match.cc
index 10297b0..e8772ec 100644
--- a/pki/verify_name_match.cc
+++ b/pki/verify_name_match.cc
@@ -350,8 +350,8 @@
// AttributeType ::= OBJECT IDENTIFIER
if (!CBB_add_asn1(&attribute_type_and_value_cbb, &type_cbb,
CBS_ASN1_OBJECT) ||
- !CBB_add_bytes(&type_cbb, type_and_value.type.UnsafeData(),
- type_and_value.type.Length())) {
+ !CBB_add_bytes(&type_cbb, type_and_value.type.data(),
+ type_and_value.type.size())) {
return false;
}
@@ -372,8 +372,8 @@
} else {
if (!CBB_add_asn1(&attribute_type_and_value_cbb, &value_cbb,
type_and_value.value_tag) ||
- !CBB_add_bytes(&value_cbb, type_and_value.value.UnsafeData(),
- type_and_value.value.Length())) {
+ !CBB_add_bytes(&value_cbb, type_and_value.value.data(),
+ type_and_value.value.size())) {
return false;
}
}
diff --git a/pki/verify_signed_data.cc b/pki/verify_signed_data.cc
index 4271366..3948a43 100644
--- a/pki/verify_signed_data.cc
+++ b/pki/verify_signed_data.cc
@@ -50,11 +50,10 @@
algorithm_name.length()) &&
SHA256UpdateWithLengthPrefixedData(&s_ctx, CBB_data(public_key_cbb.get()),
CBB_len(public_key_cbb.get())) &&
- SHA256UpdateWithLengthPrefixedData(&s_ctx,
- signature_value_bytes.UnsafeData(),
- signature_value_bytes.Length()) &&
- SHA256UpdateWithLengthPrefixedData(&s_ctx, signed_data.UnsafeData(),
- signed_data.Length()) &&
+ SHA256UpdateWithLengthPrefixedData(&s_ctx, signature_value_bytes.data(),
+ signature_value_bytes.size()) &&
+ SHA256UpdateWithLengthPrefixedData(&s_ctx, signed_data.data(),
+ signed_data.size()) &&
SHA256_Final(digest, &s_ctx)) {
return std::string(reinterpret_cast<char *>(digest), sizeof(digest));
}
@@ -143,7 +142,7 @@
OpenSSLErrStackTracer err_tracer;
CBS cbs;
- CBS_init(&cbs, public_key_spki.UnsafeData(), public_key_spki.Length());
+ CBS_init(&cbs, public_key_spki.data(), public_key_spki.size());
public_key->reset(EVP_parse_public_key(&cbs));
if (!*public_key || CBS_len(&cbs) != 0) {
public_key->reset();
@@ -269,14 +268,9 @@
}
}
- if (!EVP_DigestVerifyUpdate(ctx.get(), signed_data.UnsafeData(),
- signed_data.Length())) {
- return false;
- }
-
- bool ret =
- 1 == EVP_DigestVerifyFinal(ctx.get(), signature_value_bytes.UnsafeData(),
- signature_value_bytes.Length());
+ bool ret = 1 == EVP_DigestVerify(ctx.get(), signature_value_bytes.data(),
+ signature_value_bytes.size(),
+ signed_data.data(), signed_data.size());
if (!cache_key.empty()) {
cache->Store(cache_key, ret ? SignatureVerifyCache::Value::kValid
: SignatureVerifyCache::Value::kInvalid);