Index: net/cert/ct_serialization.cc |
diff --git a/net/cert/ct_serialization.cc b/net/cert/ct_serialization.cc |
deleted file mode 100644 |
index 489717a9686088c9c41262bfcd8b4ce97058e0d8..0000000000000000000000000000000000000000 |
--- a/net/cert/ct_serialization.cc |
+++ /dev/null |
@@ -1,386 +0,0 @@ |
-// Copyright 2013 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/cert/ct_serialization.h" |
- |
-#include "base/basictypes.h" |
-#include "base/logging.h" |
- |
-namespace net { |
- |
-namespace ct { |
- |
-namespace { |
- |
-// Note: length is always specified in bytes. |
-// Signed Certificate Timestamp (SCT) Version length |
-const size_t kVersionLength = 1; |
- |
-// Members of a V1 SCT |
-const size_t kLogIdLength = 32; |
-const size_t kTimestampLength = 8; |
-const size_t kExtensionsLengthBytes = 2; |
-const size_t kHashAlgorithmLength = 1; |
-const size_t kSigAlgorithmLength = 1; |
-const size_t kSignatureLengthBytes = 2; |
- |
-// Members of the digitally-signed struct of a V1 SCT |
-const size_t kSignatureTypeLength = 1; |
-const size_t kLogEntryTypeLength = 2; |
-const size_t kAsn1CertificateLengthBytes = 3; |
-const size_t kTbsCertificateLengthBytes = 3; |
- |
-const size_t kSCTListLengthBytes = 2; |
-const size_t kSerializedSCTLengthBytes = 2; |
- |
-// Members of digitally-signed struct of a STH |
-const size_t kTreeSizeLength = 8; |
- |
-enum SignatureType { |
- SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP = 0, |
- TREE_HASH = 1, |
-}; |
- |
-// Reads a TLS-encoded variable length unsigned integer from |in|. |
-// The integer is expected to be in big-endian order, which is used by TLS. |
-// The bytes read from |in| are discarded (i.e. |in|'s prefix removed) |
-// |length| indicates the size (in bytes) of the integer. On success, returns |
-// true and stores the result in |*out|. |
-template <typename T> |
-bool ReadUint(size_t length, base::StringPiece* in, T* out) { |
- if (in->size() < length) |
- return false; |
- DCHECK_LE(length, sizeof(T)); |
- |
- T result = 0; |
- for (size_t i = 0; i < length; ++i) { |
- result = (result << 8) | static_cast<unsigned char>((*in)[i]); |
- } |
- in->remove_prefix(length); |
- *out = result; |
- return true; |
-} |
- |
-// 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) |
-// success, returns true and stores the result in |*out|. |
-bool ReadLength(size_t prefix_length, base::StringPiece* in, size_t* out) { |
- size_t length; |
- if (!ReadUint(prefix_length, in, &length)) |
- return false; |
- *out = length; |
- return true; |
-} |
- |
-// Reads |length| bytes from |*in|. If |*in| is too small, returns false. |
-// The bytes read from |in| are discarded (i.e. |in|'s prefix removed) |
-bool ReadFixedBytes(size_t length, |
- base::StringPiece* in, |
- base::StringPiece* out) { |
- if (in->length() < length) |
- return false; |
- out->set(in->data(), length); |
- in->remove_prefix(length); |
- return true; |
-} |
- |
-// Reads a length-prefixed variable amount of bytes from |in|, updating |out| |
-// on success. |prefix_length| indicates the number of bytes needed to represent |
-// the length. |
-// The bytes read from |in| are discarded (i.e. |in|'s prefix removed) |
-bool ReadVariableBytes(size_t prefix_length, |
- base::StringPiece* in, |
- base::StringPiece* out) { |
- size_t length; |
- if (!ReadLength(prefix_length, in, &length)) |
- return false; |
- return ReadFixedBytes(length, in, out); |
-} |
- |
-// Reads a variable-length list that has been TLS encoded. |
-// The bytes read from |in| are discarded (i.e. |in|'s prefix removed) |
-// |max_list_length| contains the overall length of the encoded list. |
-// |max_item_length| contains the maximum length of a single item. |
-// On success, returns true and updates |*out| with the encoded list. |
-bool ReadList(size_t max_list_length, |
- size_t max_item_length, |
- base::StringPiece* in, |
- std::vector<base::StringPiece>* out) { |
- std::vector<base::StringPiece> result; |
- |
- base::StringPiece list_data; |
- if (!ReadVariableBytes(max_list_length, in, &list_data)) |
- return false; |
- |
- while (!list_data.empty()) { |
- base::StringPiece list_item; |
- if (!ReadVariableBytes(max_item_length, &list_data, &list_item)) { |
- DVLOG(1) << "Failed to read item in list."; |
- return false; |
- } |
- if (list_item.empty()) { |
- DVLOG(1) << "Empty item in list"; |
- return false; |
- } |
- result.push_back(list_item); |
- } |
- |
- result.swap(*out); |
- return true; |
-} |
- |
-// Checks and converts a hash algorithm. |
-// |in| is the numeric representation of the algorithm. |
-// If the hash algorithm value is in a set of known values, fills in |out| and |
-// returns true. Otherwise, returns false. |
-bool ConvertHashAlgorithm(unsigned in, DigitallySigned::HashAlgorithm* out) { |
- switch (in) { |
- case DigitallySigned::HASH_ALGO_NONE: |
- case DigitallySigned::HASH_ALGO_MD5: |
- case DigitallySigned::HASH_ALGO_SHA1: |
- case DigitallySigned::HASH_ALGO_SHA224: |
- case DigitallySigned::HASH_ALGO_SHA256: |
- case DigitallySigned::HASH_ALGO_SHA384: |
- case DigitallySigned::HASH_ALGO_SHA512: |
- break; |
- default: |
- return false; |
- } |
- *out = static_cast<DigitallySigned::HashAlgorithm>(in); |
- return true; |
-} |
- |
-// Checks and converts a signing algorithm. |
-// |in| is the numeric representation of the algorithm. |
-// If the signing algorithm value is in a set of known values, fills in |out| |
-// and returns true. Otherwise, returns false. |
-bool ConvertSignatureAlgorithm( |
- unsigned in, |
- DigitallySigned::SignatureAlgorithm* out) { |
- switch (in) { |
- case DigitallySigned::SIG_ALGO_ANONYMOUS: |
- case DigitallySigned::SIG_ALGO_RSA: |
- case DigitallySigned::SIG_ALGO_DSA: |
- case DigitallySigned::SIG_ALGO_ECDSA: |
- break; |
- default: |
- return false; |
- } |
- *out = static_cast<DigitallySigned::SignatureAlgorithm>(in); |
- return true; |
-} |
- |
-// Writes a TLS-encoded variable length unsigned integer to |output|. |
-// |length| indicates the size (in bytes) of the integer. |
-// |value| the value itself to be written. |
-template <typename T> |
-void WriteUint(size_t length, T value, std::string* output) { |
- DCHECK_LE(length, sizeof(T)); |
- DCHECK(length == sizeof(T) || value >> (length * 8) == 0); |
- |
- for (; length > 0; --length) { |
- output->push_back((value >> ((length - 1)* 8)) & 0xFF); |
- } |
-} |
- |
-// Writes an array to |output| from |input|. |
-// Should be used in one of two cases: |
-// * The length of |input| has already been encoded into the |output| stream. |
-// * The length of |input| is fixed and the reader is expected to specify that |
-// 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) { |
- input.AppendToString(output); |
-} |
- |
-// 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. |
-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)); |
- if (input_size > max_allowed_input_size) |
- return false; |
- |
- WriteUint(prefix_length, input.size(), output); |
- WriteEncodedBytes(input, output); |
- |
- return true; |
-} |
- |
-// Writes a LogEntry of type X.509 cert to |output|. |
-// |input| is the LogEntry containing the certificate. |
-// Returns true if the leaf_certificate in the LogEntry does not exceed |
-// kMaxAsn1CertificateLength and so can be written to |output|. |
-bool EncodeAsn1CertLogEntry(const LogEntry& input, std::string* output) { |
- return WriteVariableBytes(kAsn1CertificateLengthBytes, |
- input.leaf_certificate, output); |
-} |
- |
-// Writes a LogEntry of type PreCertificate to |output|. |
-// |input| is the LogEntry containing the TBSCertificate and issuer key hash. |
-// Returns true if the TBSCertificate component in the LogEntry does not |
-// exceed kMaxTbsCertificateLength and so can be written to |output|. |
-bool EncodePrecertLogEntry(const LogEntry& input, std::string* output) { |
- WriteEncodedBytes( |
- base::StringPiece( |
- reinterpret_cast<const char*>(input.issuer_key_hash.data), |
- kLogIdLength), |
- output); |
- return WriteVariableBytes(kTbsCertificateLengthBytes, |
- input.tbs_certificate, output); |
-} |
- |
-} // namespace |
- |
-bool EncodeDigitallySigned(const DigitallySigned& input, |
- std::string* output) { |
- WriteUint(kHashAlgorithmLength, input.hash_algorithm, output); |
- WriteUint(kSigAlgorithmLength, input.signature_algorithm, |
- output); |
- return WriteVariableBytes(kSignatureLengthBytes, input.signature_data, |
- output); |
-} |
- |
-bool DecodeDigitallySigned(base::StringPiece* input, |
- DigitallySigned* output) { |
- unsigned hash_algo; |
- unsigned sig_algo; |
- base::StringPiece sig_data; |
- |
- if (!ReadUint(kHashAlgorithmLength, input, &hash_algo) || |
- !ReadUint(kSigAlgorithmLength, input, &sig_algo) || |
- !ReadVariableBytes(kSignatureLengthBytes, input, &sig_data)) { |
- return false; |
- } |
- |
- DigitallySigned result; |
- if (!ConvertHashAlgorithm(hash_algo, &result.hash_algorithm)) { |
- DVLOG(1) << "Invalid hash algorithm " << hash_algo; |
- return false; |
- } |
- if (!ConvertSignatureAlgorithm(sig_algo, &result.signature_algorithm)) { |
- DVLOG(1) << "Invalid signature algorithm " << sig_algo; |
- return false; |
- } |
- sig_data.CopyToString(&result.signature_data); |
- |
- *output = result; |
- return true; |
-} |
- |
-bool EncodeLogEntry(const LogEntry& input, std::string* output) { |
- WriteUint(kLogEntryTypeLength, input.type, output); |
- switch (input.type) { |
- case LogEntry::LOG_ENTRY_TYPE_X509: |
- return EncodeAsn1CertLogEntry(input, output); |
- case LogEntry::LOG_ENTRY_TYPE_PRECERT: |
- return EncodePrecertLogEntry(input, output); |
- } |
- return false; |
-} |
- |
-static void WriteTimeSinceEpoch(const base::Time& timestamp, |
- std::string* output) { |
- base::TimeDelta time_since_epoch = timestamp - base::Time::UnixEpoch(); |
- WriteUint(kTimestampLength, time_since_epoch.InMilliseconds(), output); |
-} |
- |
-bool EncodeV1SCTSignedData(const base::Time& timestamp, |
- const std::string& serialized_log_entry, |
- const std::string& extensions, |
- std::string* output) { |
- WriteUint(kVersionLength, SignedCertificateTimestamp::SCT_VERSION_1, |
- output); |
- WriteUint(kSignatureTypeLength, SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP, |
- output); |
- WriteTimeSinceEpoch(timestamp, output); |
- // NOTE: serialized_log_entry must already be serialized and contain the |
- // length as the prefix. |
- WriteEncodedBytes(serialized_log_entry, output); |
- return WriteVariableBytes(kExtensionsLengthBytes, extensions, output); |
-} |
- |
-void EncodeTreeHeadSignature(const SignedTreeHead& signed_tree_head, |
- std::string* output) { |
- WriteUint(kVersionLength, signed_tree_head.version, output); |
- WriteUint(kSignatureTypeLength, TREE_HASH, output); |
- WriteTimeSinceEpoch(signed_tree_head.timestamp, output); |
- WriteUint(kTreeSizeLength, signed_tree_head.tree_size, output); |
- WriteEncodedBytes( |
- base::StringPiece(signed_tree_head.sha256_root_hash, kSthRootHashLength), |
- output); |
-} |
- |
-bool DecodeSCTList(base::StringPiece* input, |
- std::vector<base::StringPiece>* output) { |
- std::vector<base::StringPiece> result; |
- if (!ReadList(kSCTListLengthBytes, kSerializedSCTLengthBytes, |
- input, &result)) { |
- return false; |
- } |
- |
- if (!input->empty() || result.empty()) |
- return false; |
- output->swap(result); |
- return true; |
-} |
- |
-bool DecodeSignedCertificateTimestamp( |
- base::StringPiece* input, |
- scoped_refptr<SignedCertificateTimestamp>* output) { |
- scoped_refptr<SignedCertificateTimestamp> result( |
- new SignedCertificateTimestamp()); |
- unsigned version; |
- if (!ReadUint(kVersionLength, input, &version)) |
- return false; |
- if (version != SignedCertificateTimestamp::SCT_VERSION_1) { |
- DVLOG(1) << "Unsupported/invalid version " << version; |
- return false; |
- } |
- |
- result->version = SignedCertificateTimestamp::SCT_VERSION_1; |
- uint64 timestamp; |
- base::StringPiece log_id; |
- base::StringPiece extensions; |
- if (!ReadFixedBytes(kLogIdLength, input, &log_id) || |
- !ReadUint(kTimestampLength, input, ×tamp) || |
- !ReadVariableBytes(kExtensionsLengthBytes, input, |
- &extensions) || |
- !DecodeDigitallySigned(input, &result->signature)) { |
- return false; |
- } |
- |
- if (timestamp > static_cast<uint64>(kint64max)) { |
- DVLOG(1) << "Timestamp value too big to cast to int64: " << timestamp; |
- return false; |
- } |
- |
- log_id.CopyToString(&result->log_id); |
- extensions.CopyToString(&result->extensions); |
- result->timestamp = |
- base::Time::UnixEpoch() + |
- base::TimeDelta::FromMilliseconds(static_cast<int64>(timestamp)); |
- |
- output->swap(result); |
- return true; |
-} |
- |
-bool EncodeSCTListForTesting(const base::StringPiece& sct, |
- std::string* output) { |
- std::string encoded_sct; |
- return WriteVariableBytes(kSerializedSCTLengthBytes, sct, &encoded_sct) && |
- WriteVariableBytes(kSCTListLengthBytes, encoded_sct, output); |
-} |
- |
-} // namespace ct |
- |
-} // namespace net |