Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Unified Diff: net/cert/ct_serialization.cc

Issue 1575543002: Minor improvements to ct_serialization.cc (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/cert/ct_serialization.cc
diff --git a/net/cert/ct_serialization.cc b/net/cert/ct_serialization.cc
index 235d37e65ad1fc8106a05d602c3c9f04b4e61a48..ebeda1fd234f000ee933f47f21c7595adecbf3e4 100644
--- a/net/cert/ct_serialization.cc
+++ b/net/cert/ct_serialization.cc
@@ -4,8 +4,7 @@
#include "net/cert/ct_serialization.h"
-#include <stdint.h>
-
+#include <cstdint>
Ryan Sleevi 2016/01/08 19:46:31 Chromium code recommends stdint.h (and, in general
Rob Percival 2016/01/10 03:48:56 No, I just wasn't aware of that recommendation - I
#include <limits>
#include "base/logging.h"
@@ -66,14 +65,18 @@ bool ReadUint(size_t length, base::StringPiece* in, T* out) {
}
// Reads a TLS-encoded field length from |in|.
-// The bytes read from |in| are discarded (i.e. |in|'s prefix removed)
-// |prefix_length| indicates the bytes needed to represent the length (e.g. 3)
+// The bytes read from |in| are discarded (i.e. |in|'s prefix removed).
+// |prefix_length| indicates the bytes needed to represent the length (e.g. 3).
+// Max |prefix_length| is 8.
// success, returns true and stores the result in |*out|.
bool ReadLength(size_t prefix_length, base::StringPiece* in, size_t* out) {
- size_t length;
+ uint64_t length = 0;
if (!ReadUint(prefix_length, in, &length))
return false;
- *out = length;
+ if (length > std::numeric_limits<size_t>::max()) {
+ return false;
+ }
Ryan Sleevi 2016/01/08 19:46:31 CONSISTENCY: No braces for one-line conditionals
Rob Percival 2016/01/10 03:48:56 Done.
+ *out = static_cast<size_t>(length);
return true;
}
@@ -96,7 +99,7 @@ bool ReadFixedBytes(size_t length,
bool ReadVariableBytes(size_t prefix_length,
base::StringPiece* in,
base::StringPiece* out) {
- size_t length;
+ size_t length = 0;
Ryan Sleevi 2016/01/08 19:46:31 Why? (I mean, on a mere pedantry that adds an extr
Rob Percival 2016/01/10 03:48:56 It's a little more defensive against bugs than tru
if (!ReadLength(prefix_length, in, &length))
return false;
return ReadFixedBytes(length, in, out);
@@ -184,7 +187,7 @@ void WriteUint(size_t length, T value, std::string* output) {
DCHECK(length == sizeof(T) || value >> (length * 8) == 0);
for (; length > 0; --length) {
- output->push_back((value >> ((length - 1)* 8)) & 0xFF);
+ output->push_back((value >> ((length - 1) * 8)) & 0xFF);
}
}
@@ -195,25 +198,33 @@ void WriteUint(size_t length, T value, std::string* output) {
// length when reading.
// If the length of |input| is dynamic and data is expected to follow it,
// WriteVariableBytes must be used.
-void WriteEncodedBytes(const base::StringPiece& input, std::string* output) {
+// Returns the number of bytes written (the length of |input|).
+size_t WriteEncodedBytes(const base::StringPiece& input, std::string* output) {
input.AppendToString(output);
+ return input.size();
}
// Writes a variable-length array to |output|.
// |prefix_length| indicates the number of bytes needed to represnt the length.
// |input| is the array itself.
-// If the size of |input| is less than 2^|prefix_length| - 1, encode the
-// length and data and return true. Otherwise, return false.
+// If 1 <= |prefix_length| <= 8 and the size of |input| is less than
+// 2^|prefix_length| - 1, encode the length and data and return true.
+// Otherwise, return false.
bool WriteVariableBytes(size_t prefix_length,
const base::StringPiece& input,
std::string* output) {
- size_t input_size = input.size();
- size_t max_allowed_input_size =
- static_cast<size_t>(((1 << (prefix_length * 8)) - 1));
+ // Use uint64_t instead of size_t to allow a |prefix_length| up to 8 bytes,
+ // even on 32-bit builds.
Ryan Sleevi 2016/01/08 19:46:31 Why? input.size() will never exceed 4 bytes on 32-
Rob Percival 2016/01/10 03:48:56 The catch here is that WriteUint (below) is a temp
Ryan Sleevi 2016/01/12 00:10:15 Isn't this moreso a bug in line 186/187 having bad
Rob Percival 2016/01/13 00:55:52 How about we replace the preconditions of WriteUin
+ uint64_t input_size = input.size();
+ if (prefix_length > sizeof(input_size)) {
+ return false;
+ }
Ryan Sleevi 2016/01/08 19:46:31 Consistency: Braces
Rob Percival 2016/01/10 03:48:56 Done.
+
+ uint64_t max_allowed_input_size = ((1 << (prefix_length * 8)) - 1);
if (input_size > max_allowed_input_size)
return false;
- WriteUint(prefix_length, input.size(), output);
+ WriteUint(prefix_length, input_size, output);
WriteEncodedBytes(input, output);
return true;
@@ -291,6 +302,26 @@ bool EncodeLogEntry(const LogEntry& input, std::string* output) {
return false;
}
+static bool ReadTimeSinceEpoch(base::StringPiece* input, base::Time* output) {
+ uint64_t time_since_epoch = 0;
+ if (!ReadUint(kTimestampLength, input, &time_since_epoch)) {
+ return false;
+ }
+
+ if (time_since_epoch >
+ static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
Ryan Sleevi 2016/01/08 19:46:31 There's stuff in base/safe_numerics to help with t
Rob Percival 2016/01/10 03:48:56 Done.
+ DVLOG(1) << "Timestamp value too big to cast to int64_t: "
+ << time_since_epoch;
+ return false;
+ }
+
+ *output =
+ base::Time::UnixEpoch() +
+ base::TimeDelta::FromMilliseconds(static_cast<int64_t>(time_since_epoch));
+
+ return true;
+}
+
static void WriteTimeSinceEpoch(const base::Time& timestamp,
std::string* output) {
base::TimeDelta time_since_epoch = timestamp - base::Time::UnixEpoch();
@@ -351,28 +382,17 @@ bool DecodeSignedCertificateTimestamp(
}
result->version = SignedCertificateTimestamp::SCT_VERSION_1;
- uint64_t timestamp;
base::StringPiece log_id;
base::StringPiece extensions;
if (!ReadFixedBytes(kLogIdLength, input, &log_id) ||
- !ReadUint(kTimestampLength, input, &timestamp) ||
- !ReadVariableBytes(kExtensionsLengthBytes, input,
- &extensions) ||
+ !ReadTimeSinceEpoch(input, &result->timestamp) ||
+ !ReadVariableBytes(kExtensionsLengthBytes, input, &extensions) ||
!DecodeDigitallySigned(input, &result->signature)) {
return false;
}
- if (timestamp > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
- DVLOG(1) << "Timestamp value too big to cast to int64_t: " << timestamp;
- return false;
- }
-
log_id.CopyToString(&result->log_id);
extensions.CopyToString(&result->extensions);
- result->timestamp =
- base::Time::UnixEpoch() +
- base::TimeDelta::FromMilliseconds(static_cast<int64_t>(timestamp));
-
output->swap(result);
return true;
}
@@ -381,7 +401,7 @@ bool EncodeSCTListForTesting(const base::StringPiece& sct,
std::string* output) {
std::string encoded_sct;
return WriteVariableBytes(kSerializedSCTLengthBytes, sct, &encoded_sct) &&
- WriteVariableBytes(kSCTListLengthBytes, encoded_sct, output);
+ WriteVariableBytes(kSCTListLengthBytes, encoded_sct, output);
}
} // namespace ct
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698