Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/cert/ct_serialization.h" | 5 #include "net/cert/ct_serialization.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <limits> | 10 #include <limits> |
| 11 | 11 |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/numerics/safe_math.h" | 13 #include "base/numerics/safe_math.h" |
| 14 #include "crypto/sha2.h" | |
| 15 #include "net/cert/merkle_tree_leaf.h" | |
| 14 | 16 |
| 15 namespace net { | 17 namespace net { |
| 16 | 18 |
| 17 namespace ct { | 19 namespace ct { |
| 18 | 20 |
| 19 namespace { | 21 namespace { |
| 20 | 22 |
| 21 // Note: length is always specified in bytes. | 23 // Note: length is always specified in bytes. |
| 22 // Signed Certificate Timestamp (SCT) Version length | 24 // CT protocol version length |
| 23 const size_t kVersionLength = 1; | 25 const size_t kVersionLength = 1; |
| 24 | 26 |
| 27 // Common V1 struct members | |
| 28 const size_t kTimestampLength = 8; | |
| 29 const size_t kLogEntryTypeLength = 2; | |
| 30 const size_t kAsn1CertificateLengthBytes = 3; | |
| 31 const size_t kTbsCertificateLengthBytes = 3; | |
| 32 const size_t kExtensionsLengthBytes = 2; | |
| 33 | |
| 25 // Members of a V1 SCT | 34 // Members of a V1 SCT |
| 26 const size_t kLogIdLength = 32; | 35 const size_t kLogIdLength = crypto::kSHA256Length; |
| 27 const size_t kTimestampLength = 8; | |
| 28 const size_t kExtensionsLengthBytes = 2; | |
| 29 const size_t kHashAlgorithmLength = 1; | 36 const size_t kHashAlgorithmLength = 1; |
| 30 const size_t kSigAlgorithmLength = 1; | 37 const size_t kSigAlgorithmLength = 1; |
| 31 const size_t kSignatureLengthBytes = 2; | 38 const size_t kSignatureLengthBytes = 2; |
| 32 | 39 |
| 33 // Members of the digitally-signed struct of a V1 SCT | 40 // Members of the digitally-signed struct of a V1 SCT |
| 34 const size_t kSignatureTypeLength = 1; | 41 const size_t kSignatureTypeLength = 1; |
| 35 const size_t kLogEntryTypeLength = 2; | |
| 36 const size_t kAsn1CertificateLengthBytes = 3; | |
| 37 const size_t kTbsCertificateLengthBytes = 3; | |
| 38 | 42 |
| 39 const size_t kSCTListLengthBytes = 2; | 43 const size_t kSCTListLengthBytes = 2; |
| 40 const size_t kSerializedSCTLengthBytes = 2; | 44 const size_t kSerializedSCTLengthBytes = 2; |
| 41 | 45 |
| 42 // Members of digitally-signed struct of a STH | 46 // Members of digitally-signed struct of a STH |
| 43 const size_t kTreeSizeLength = 8; | 47 const size_t kTreeSizeLength = 8; |
| 44 | 48 |
| 49 // Members of a V1 MerkleTreeLeaf | |
| 50 const size_t kMerkleLeafTypeLength = 1; | |
| 51 const size_t kIssuerKeyHashLength = crypto::kSHA256Length; | |
| 52 | |
| 45 enum SignatureType { | 53 enum SignatureType { |
| 46 SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP = 0, | 54 SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP = 0, |
| 47 TREE_HASH = 1, | 55 TREE_HASH = 1, |
| 48 }; | 56 }; |
| 49 | 57 |
| 50 // Reads a TLS-encoded variable length unsigned integer from |in|. | 58 // Reads a TLS-encoded variable length unsigned integer from |in|. |
| 51 // The integer is expected to be in big-endian order, which is used by TLS. | 59 // The integer is expected to be in big-endian order, which is used by TLS. |
| 52 // The bytes read from |in| are discarded (i.e. |in|'s prefix removed) | 60 // The bytes read from |in| are discarded (i.e. |in|'s prefix removed) |
| 53 // |length| indicates the size (in bytes) of the integer. On success, returns | 61 // |length| indicates the size (in bytes) of the integer. On success, returns |
| 54 // true and stores the result in |*out|. | 62 // true and stores the result in |*out|. |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 } | 255 } |
| 248 | 256 |
| 249 // Writes a LogEntry of type PreCertificate to |output|. | 257 // Writes a LogEntry of type PreCertificate to |output|. |
| 250 // |input| is the LogEntry containing the TBSCertificate and issuer key hash. | 258 // |input| is the LogEntry containing the TBSCertificate and issuer key hash. |
| 251 // Returns true if the TBSCertificate component in the LogEntry does not | 259 // Returns true if the TBSCertificate component in the LogEntry does not |
| 252 // exceed kMaxTbsCertificateLength and so can be written to |output|. | 260 // exceed kMaxTbsCertificateLength and so can be written to |output|. |
| 253 bool EncodePrecertLogEntry(const LogEntry& input, std::string* output) { | 261 bool EncodePrecertLogEntry(const LogEntry& input, std::string* output) { |
| 254 WriteEncodedBytes( | 262 WriteEncodedBytes( |
| 255 base::StringPiece( | 263 base::StringPiece( |
| 256 reinterpret_cast<const char*>(input.issuer_key_hash.data), | 264 reinterpret_cast<const char*>(input.issuer_key_hash.data), |
| 257 kLogIdLength), | 265 kIssuerKeyHashLength), |
| 258 output); | 266 output); |
| 259 return WriteVariableBytes(kTbsCertificateLengthBytes, | 267 return WriteVariableBytes(kTbsCertificateLengthBytes, |
| 260 input.tbs_certificate, output); | 268 input.tbs_certificate, output); |
| 261 } | 269 } |
| 262 | 270 |
| 263 } // namespace | 271 } // namespace |
| 264 | 272 |
| 265 bool EncodeDigitallySigned(const DigitallySigned& input, | 273 bool EncodeDigitallySigned(const DigitallySigned& input, |
| 266 std::string* output) { | 274 std::string* output) { |
| 267 WriteUint(kHashAlgorithmLength, input.hash_algorithm, output); | 275 WriteUint(kHashAlgorithmLength, input.hash_algorithm, output); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 328 | 336 |
| 329 return true; | 337 return true; |
| 330 } | 338 } |
| 331 | 339 |
| 332 static void WriteTimeSinceEpoch(const base::Time& timestamp, | 340 static void WriteTimeSinceEpoch(const base::Time& timestamp, |
| 333 std::string* output) { | 341 std::string* output) { |
| 334 base::TimeDelta time_since_epoch = timestamp - base::Time::UnixEpoch(); | 342 base::TimeDelta time_since_epoch = timestamp - base::Time::UnixEpoch(); |
| 335 WriteUint(kTimestampLength, time_since_epoch.InMilliseconds(), output); | 343 WriteUint(kTimestampLength, time_since_epoch.InMilliseconds(), output); |
| 336 } | 344 } |
| 337 | 345 |
| 346 bool EncodeTreeLeaf(const MerkleTreeLeaf& leaf, std::string* output) { | |
| 347 WriteUint(kVersionLength, 0, output); // version: 1 | |
| 348 WriteUint(kMerkleLeafTypeLength, 0, output); // type: timestamped entry | |
| 349 WriteTimeSinceEpoch(leaf.timestamp, output); | |
| 350 if (!EncodeLogEntry(leaf.log_entry, output)) | |
| 351 return false; | |
|
eroman
2016/05/07 00:20:52
run "git cl format" -- need to remove some spaces
Rob Percival
2016/05/08 04:08:17
Oddly, "git cl format" doesn't make any changes. F
| |
| 352 if (!WriteVariableBytes(kExtensionsLengthBytes, leaf.extensions, output)) | |
| 353 return false; | |
|
eroman
2016/05/07 00:20:52
Same
Rob Percival
2016/05/08 04:08:17
Done.
| |
| 354 | |
| 355 return true; | |
| 356 } | |
| 357 | |
| 338 bool EncodeV1SCTSignedData(const base::Time& timestamp, | 358 bool EncodeV1SCTSignedData(const base::Time& timestamp, |
| 339 const std::string& serialized_log_entry, | 359 const std::string& serialized_log_entry, |
| 340 const std::string& extensions, | 360 const std::string& extensions, |
| 341 std::string* output) { | 361 std::string* output) { |
| 342 WriteUint(kVersionLength, SignedCertificateTimestamp::SCT_VERSION_1, | 362 WriteUint(kVersionLength, SignedCertificateTimestamp::SCT_VERSION_1, |
| 343 output); | 363 output); |
| 344 WriteUint(kSignatureTypeLength, SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP, | 364 WriteUint(kSignatureTypeLength, SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP, |
| 345 output); | 365 output); |
| 346 WriteTimeSinceEpoch(timestamp, output); | 366 WriteTimeSinceEpoch(timestamp, output); |
| 347 // NOTE: serialized_log_entry must already be serialized and contain the | 367 // NOTE: serialized_log_entry must already be serialized and contain the |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 bool EncodeSCTListForTesting(const base::StringPiece& sct, | 427 bool EncodeSCTListForTesting(const base::StringPiece& sct, |
| 408 std::string* output) { | 428 std::string* output) { |
| 409 std::string encoded_sct; | 429 std::string encoded_sct; |
| 410 return WriteVariableBytes(kSerializedSCTLengthBytes, sct, &encoded_sct) && | 430 return WriteVariableBytes(kSerializedSCTLengthBytes, sct, &encoded_sct) && |
| 411 WriteVariableBytes(kSCTListLengthBytes, encoded_sct, output); | 431 WriteVariableBytes(kSCTListLengthBytes, encoded_sct, output); |
| 412 } | 432 } |
| 413 | 433 |
| 414 } // namespace ct | 434 } // namespace ct |
| 415 | 435 |
| 416 } // namespace net | 436 } // namespace net |
| OLD | NEW |