Add expiry parsing into CertificateView.
PiperOrigin-RevId: 314437222
Change-Id: Ia7ff932ea0c21ef064f68f6242179d7b579d2a9f
diff --git a/common/platform/api/quiche_time_utils.h b/common/platform/api/quiche_time_utils.h
new file mode 100644
index 0000000..7319568
--- /dev/null
+++ b/common/platform/api/quiche_time_utils.h
@@ -0,0 +1,31 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_TIME_UTILS_H_
+#define QUICHE_COMMON_PLATFORM_API_QUICHE_TIME_UTILS_H_
+
+#include <cstdint>
+
+#include "net/quiche/common/platform/impl/quiche_time_utils_impl.h"
+
+namespace quiche {
+
+// Converts a civil time specified in UTC into a number of seconds since the
+// Unix epoch. This function is strict about validity of accepted dates. For
+// instance, it will reject February 29 on non-leap years, or 25 hours in a day.
+// As a notable exception, 60 seconds is accepted to deal with potential leap
+// seconds. If the date predates Unix epoch, nullopt will be returned.
+inline QuicheOptional<int64_t> QuicheUtcDateTimeToUnixSeconds(int year,
+ int month,
+ int day,
+ int hour,
+ int minute,
+ int second) {
+ return QuicheUtcDateTimeToUnixSecondsImpl(year, month, day, hour, minute,
+ second);
+}
+
+} // namespace quiche
+
+#endif // QUICHE_COMMON_PLATFORM_API_QUICHE_TIME_UTILS_H_
diff --git a/common/platform/api/quiche_time_utils_test.cc b/common/platform/api/quiche_time_utils_test.cc
new file mode 100644
index 0000000..0f32b10
--- /dev/null
+++ b/common/platform/api/quiche_time_utils_test.cc
@@ -0,0 +1,51 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/common/platform/api/quiche_time_utils.h"
+
+#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h"
+#include "net/third_party/quiche/src/common/platform/api/quiche_test.h"
+
+namespace quiche {
+namespace {
+
+TEST(QuicheTimeUtilsTest, Basic) {
+ EXPECT_EQ(1, QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 0, 0, 1));
+ EXPECT_EQ(365 * 86400, QuicheUtcDateTimeToUnixSeconds(1971, 1, 1, 0, 0, 0));
+ // Some arbitrary timestamps closer to the present, compared to the output of
+ // "Date(...).getTime()" from the JavaScript console.
+ EXPECT_EQ(1152966896,
+ QuicheUtcDateTimeToUnixSeconds(2006, 7, 15, 12, 34, 56));
+ EXPECT_EQ(1591130001, QuicheUtcDateTimeToUnixSeconds(2020, 6, 2, 20, 33, 21));
+
+ EXPECT_EQ(QuicheNullOpt,
+ QuicheUtcDateTimeToUnixSeconds(1970, 2, 29, 0, 0, 1));
+ EXPECT_NE(QuicheNullOpt,
+ QuicheUtcDateTimeToUnixSeconds(1972, 2, 29, 0, 0, 1));
+}
+
+TEST(QuicheTimeUtilsTest, Bounds) {
+ EXPECT_EQ(QuicheNullOpt,
+ QuicheUtcDateTimeToUnixSeconds(1970, 1, 32, 0, 0, 1));
+ EXPECT_EQ(QuicheNullOpt,
+ QuicheUtcDateTimeToUnixSeconds(1970, 4, 31, 0, 0, 1));
+ EXPECT_EQ(QuicheNullOpt, QuicheUtcDateTimeToUnixSeconds(1970, 1, 0, 0, 0, 1));
+ EXPECT_EQ(QuicheNullOpt,
+ QuicheUtcDateTimeToUnixSeconds(1970, 13, 1, 0, 0, 1));
+ EXPECT_EQ(QuicheNullOpt, QuicheUtcDateTimeToUnixSeconds(1970, 0, 1, 0, 0, 1));
+ EXPECT_EQ(QuicheNullOpt,
+ QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 24, 0, 0));
+ EXPECT_EQ(QuicheNullOpt,
+ QuicheUtcDateTimeToUnixSeconds(1970, 1, 1, 0, 60, 0));
+}
+
+TEST(QuicheTimeUtilsTest, LeapSecond) {
+ EXPECT_EQ(QuicheUtcDateTimeToUnixSeconds(2015, 6, 30, 23, 59, 60),
+ QuicheUtcDateTimeToUnixSeconds(2015, 7, 1, 0, 0, 0));
+ EXPECT_EQ(QuicheUtcDateTimeToUnixSeconds(2015, 6, 30, 25, 59, 60),
+ QuicheNullOpt);
+}
+
+} // namespace
+} // namespace quiche
diff --git a/common/quiche_data_reader.cc b/common/quiche_data_reader.cc
index 3445013..2242fea 100644
--- a/common/quiche_data_reader.cc
+++ b/common/quiche_data_reader.cc
@@ -10,6 +10,7 @@
#include "net/third_party/quiche/src/common/platform/api/quiche_logging.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
+#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
namespace quiche {
@@ -119,6 +120,15 @@
return ReadBytes(tag, sizeof(*tag));
}
+bool QuicheDataReader::ReadDecimal64(size_t num_digits, uint64_t* result) {
+ quiche::QuicheStringPiece digits;
+ if (!ReadStringPiece(&digits, num_digits)) {
+ return false;
+ }
+
+ return QuicheTextUtils::StringToUint64(digits, result);
+}
+
quiche::QuicheStringPiece QuicheDataReader::ReadRemainingPayload() {
quiche::QuicheStringPiece payload = PeekRemainingPayload();
pos_ = len_;
diff --git a/common/quiche_data_reader.h b/common/quiche_data_reader.h
index cf62a16..f74f90d 100644
--- a/common/quiche_data_reader.h
+++ b/common/quiche_data_reader.h
@@ -87,6 +87,11 @@
// endian.
bool ReadTag(uint32_t* tag);
+ // Reads a sequence of a fixed number of decimal digits, parses them as an
+ // unsigned integer and returns them as a uint64_t. Forwards internal
+ // iterator on success, may forward it even in case of failure.
+ bool ReadDecimal64(size_t num_digits, uint64_t* result);
+
// Returns the remaining payload as a quiche::QuicheStringPiece.
//
// NOTE: Does not copy but rather references strings in the underlying buffer.