| 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 "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 | 9 |
| 10 namespace net { | 10 namespace net { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 return false; | 146 return false; |
| 147 } | 147 } |
| 148 *out = static_cast<DigitallySigned::HashAlgorithm>(in); | 148 *out = static_cast<DigitallySigned::HashAlgorithm>(in); |
| 149 return true; | 149 return true; |
| 150 } | 150 } |
| 151 | 151 |
| 152 // Checks and converts a signing algorithm. | 152 // Checks and converts a signing algorithm. |
| 153 // |in| is the numeric representation of the algorithm. | 153 // |in| is the numeric representation of the algorithm. |
| 154 // If the signing algorithm value is in a set of known values, fills in |out| | 154 // If the signing algorithm value is in a set of known values, fills in |out| |
| 155 // and returns true. Otherwise, returns false. | 155 // and returns true. Otherwise, returns false. |
| 156 bool ConvertSignatureAlgorithm( | 156 bool ConvertSignatureAlgorithm(unsigned in, |
| 157 unsigned in, | 157 DigitallySigned::SignatureAlgorithm* out) { |
| 158 DigitallySigned::SignatureAlgorithm* out) { | |
| 159 switch (in) { | 158 switch (in) { |
| 160 case DigitallySigned::SIG_ALGO_ANONYMOUS: | 159 case DigitallySigned::SIG_ALGO_ANONYMOUS: |
| 161 case DigitallySigned::SIG_ALGO_RSA: | 160 case DigitallySigned::SIG_ALGO_RSA: |
| 162 case DigitallySigned::SIG_ALGO_DSA: | 161 case DigitallySigned::SIG_ALGO_DSA: |
| 163 case DigitallySigned::SIG_ALGO_ECDSA: | 162 case DigitallySigned::SIG_ALGO_ECDSA: |
| 164 break; | 163 break; |
| 165 default: | 164 default: |
| 166 return false; | 165 return false; |
| 167 } | 166 } |
| 168 *out = static_cast<DigitallySigned::SignatureAlgorithm>(in); | 167 *out = static_cast<DigitallySigned::SignatureAlgorithm>(in); |
| 169 return true; | 168 return true; |
| 170 } | 169 } |
| 171 | 170 |
| 172 // Writes a TLS-encoded variable length unsigned integer to |output|. | 171 // Writes a TLS-encoded variable length unsigned integer to |output|. |
| 173 // |length| indicates the size (in bytes) of the integer. | 172 // |length| indicates the size (in bytes) of the integer. |
| 174 // |value| the value itself to be written. | 173 // |value| the value itself to be written. |
| 175 template <typename T> | 174 template <typename T> |
| 176 void WriteUint(size_t length, T value, std::string* output) { | 175 void WriteUint(size_t length, T value, std::string* output) { |
| 177 DCHECK_LE(length, sizeof(T)); | 176 DCHECK_LE(length, sizeof(T)); |
| 178 DCHECK(length == sizeof(T) || value >> (length * 8) == 0); | 177 DCHECK(length == sizeof(T) || value >> (length * 8) == 0); |
| 179 | 178 |
| 180 for (; length > 0; --length) { | 179 for (; length > 0; --length) { |
| 181 output->push_back((value >> ((length - 1)* 8)) & 0xFF); | 180 output->push_back((value >> ((length - 1) * 8)) & 0xFF); |
| 182 } | 181 } |
| 183 } | 182 } |
| 184 | 183 |
| 185 // Writes an array to |output| from |input|. | 184 // Writes an array to |output| from |input|. |
| 186 // Should be used in one of two cases: | 185 // Should be used in one of two cases: |
| 187 // * The length of |input| has already been encoded into the |output| stream. | 186 // * The length of |input| has already been encoded into the |output| stream. |
| 188 // * The length of |input| is fixed and the reader is expected to specify that | 187 // * The length of |input| is fixed and the reader is expected to specify that |
| 189 // length when reading. | 188 // length when reading. |
| 190 // If the length of |input| is dynamic and data is expected to follow it, | 189 // If the length of |input| is dynamic and data is expected to follow it, |
| 191 // WriteVariableBytes must be used. | 190 // WriteVariableBytes must be used. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 211 WriteEncodedBytes(input, output); | 210 WriteEncodedBytes(input, output); |
| 212 | 211 |
| 213 return true; | 212 return true; |
| 214 } | 213 } |
| 215 | 214 |
| 216 // Writes a LogEntry of type X.509 cert to |output|. | 215 // Writes a LogEntry of type X.509 cert to |output|. |
| 217 // |input| is the LogEntry containing the certificate. | 216 // |input| is the LogEntry containing the certificate. |
| 218 // Returns true if the leaf_certificate in the LogEntry does not exceed | 217 // Returns true if the leaf_certificate in the LogEntry does not exceed |
| 219 // kMaxAsn1CertificateLength and so can be written to |output|. | 218 // kMaxAsn1CertificateLength and so can be written to |output|. |
| 220 bool EncodeAsn1CertLogEntry(const LogEntry& input, std::string* output) { | 219 bool EncodeAsn1CertLogEntry(const LogEntry& input, std::string* output) { |
| 221 return WriteVariableBytes(kAsn1CertificateLengthBytes, | 220 return WriteVariableBytes( |
| 222 input.leaf_certificate, output); | 221 kAsn1CertificateLengthBytes, input.leaf_certificate, output); |
| 223 } | 222 } |
| 224 | 223 |
| 225 // Writes a LogEntry of type PreCertificate to |output|. | 224 // Writes a LogEntry of type PreCertificate to |output|. |
| 226 // |input| is the LogEntry containing the TBSCertificate and issuer key hash. | 225 // |input| is the LogEntry containing the TBSCertificate and issuer key hash. |
| 227 // Returns true if the TBSCertificate component in the LogEntry does not | 226 // Returns true if the TBSCertificate component in the LogEntry does not |
| 228 // exceed kMaxTbsCertificateLength and so can be written to |output|. | 227 // exceed kMaxTbsCertificateLength and so can be written to |output|. |
| 229 bool EncodePrecertLogEntry(const LogEntry& input, std::string* output) { | 228 bool EncodePrecertLogEntry(const LogEntry& input, std::string* output) { |
| 230 WriteEncodedBytes( | 229 WriteEncodedBytes(base::StringPiece(reinterpret_cast<const char*>( |
| 231 base::StringPiece( | 230 input.issuer_key_hash.data), |
| 232 reinterpret_cast<const char*>(input.issuer_key_hash.data), | 231 kLogIdLength), |
| 233 kLogIdLength), | 232 output); |
| 234 output); | 233 return WriteVariableBytes( |
| 235 return WriteVariableBytes(kTbsCertificateLengthBytes, | 234 kTbsCertificateLengthBytes, input.tbs_certificate, output); |
| 236 input.tbs_certificate, output); | |
| 237 } | 235 } |
| 238 | 236 |
| 239 } // namespace | 237 } // namespace |
| 240 | 238 |
| 241 bool EncodeDigitallySigned(const DigitallySigned& input, | 239 bool EncodeDigitallySigned(const DigitallySigned& input, std::string* output) { |
| 242 std::string* output) { | |
| 243 WriteUint(kHashAlgorithmLength, input.hash_algorithm, output); | 240 WriteUint(kHashAlgorithmLength, input.hash_algorithm, output); |
| 244 WriteUint(kSigAlgorithmLength, input.signature_algorithm, | 241 WriteUint(kSigAlgorithmLength, input.signature_algorithm, output); |
| 245 output); | 242 return WriteVariableBytes( |
| 246 return WriteVariableBytes(kSignatureLengthBytes, input.signature_data, | 243 kSignatureLengthBytes, input.signature_data, output); |
| 247 output); | |
| 248 } | 244 } |
| 249 | 245 |
| 250 bool DecodeDigitallySigned(base::StringPiece* input, | 246 bool DecodeDigitallySigned(base::StringPiece* input, DigitallySigned* output) { |
| 251 DigitallySigned* output) { | |
| 252 unsigned hash_algo; | 247 unsigned hash_algo; |
| 253 unsigned sig_algo; | 248 unsigned sig_algo; |
| 254 base::StringPiece sig_data; | 249 base::StringPiece sig_data; |
| 255 | 250 |
| 256 if (!ReadUint(kHashAlgorithmLength, input, &hash_algo) || | 251 if (!ReadUint(kHashAlgorithmLength, input, &hash_algo) || |
| 257 !ReadUint(kSigAlgorithmLength, input, &sig_algo) || | 252 !ReadUint(kSigAlgorithmLength, input, &sig_algo) || |
| 258 !ReadVariableBytes(kSignatureLengthBytes, input, &sig_data)) { | 253 !ReadVariableBytes(kSignatureLengthBytes, input, &sig_data)) { |
| 259 return false; | 254 return false; |
| 260 } | 255 } |
| 261 | 256 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 282 case LogEntry::LOG_ENTRY_TYPE_PRECERT: | 277 case LogEntry::LOG_ENTRY_TYPE_PRECERT: |
| 283 return EncodePrecertLogEntry(input, output); | 278 return EncodePrecertLogEntry(input, output); |
| 284 } | 279 } |
| 285 return false; | 280 return false; |
| 286 } | 281 } |
| 287 | 282 |
| 288 bool EncodeV1SCTSignedData(const base::Time& timestamp, | 283 bool EncodeV1SCTSignedData(const base::Time& timestamp, |
| 289 const std::string& serialized_log_entry, | 284 const std::string& serialized_log_entry, |
| 290 const std::string& extensions, | 285 const std::string& extensions, |
| 291 std::string* output) { | 286 std::string* output) { |
| 292 WriteUint(kVersionLength, SignedCertificateTimestamp::SCT_VERSION_1, | 287 WriteUint(kVersionLength, SignedCertificateTimestamp::SCT_VERSION_1, output); |
| 293 output); | 288 WriteUint(kSignatureTypeLength, SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP, output); |
| 294 WriteUint(kSignatureTypeLength, SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP, | |
| 295 output); | |
| 296 base::TimeDelta time_since_epoch = timestamp - base::Time::UnixEpoch(); | 289 base::TimeDelta time_since_epoch = timestamp - base::Time::UnixEpoch(); |
| 297 WriteUint(kTimestampLength, time_since_epoch.InMilliseconds(), | 290 WriteUint(kTimestampLength, time_since_epoch.InMilliseconds(), output); |
| 298 output); | |
| 299 // NOTE: serialized_log_entry must already be serialized and contain the | 291 // NOTE: serialized_log_entry must already be serialized and contain the |
| 300 // length as the prefix. | 292 // length as the prefix. |
| 301 WriteEncodedBytes(serialized_log_entry, output); | 293 WriteEncodedBytes(serialized_log_entry, output); |
| 302 return WriteVariableBytes(kExtensionsLengthBytes, extensions, output); | 294 return WriteVariableBytes(kExtensionsLengthBytes, extensions, output); |
| 303 } | 295 } |
| 304 | 296 |
| 305 bool DecodeSCTList(base::StringPiece* input, | 297 bool DecodeSCTList(base::StringPiece* input, |
| 306 std::vector<base::StringPiece>* output) { | 298 std::vector<base::StringPiece>* output) { |
| 307 std::vector<base::StringPiece> result; | 299 std::vector<base::StringPiece> result; |
| 308 if (!ReadList(kSCTListLengthBytes, kSerializedSCTLengthBytes, | 300 if (!ReadList( |
| 309 input, &result)) { | 301 kSCTListLengthBytes, kSerializedSCTLengthBytes, input, &result)) { |
| 310 return false; | 302 return false; |
| 311 } | 303 } |
| 312 | 304 |
| 313 if (!input->empty() || result.empty()) | 305 if (!input->empty() || result.empty()) |
| 314 return false; | 306 return false; |
| 315 output->swap(result); | 307 output->swap(result); |
| 316 return true; | 308 return true; |
| 317 } | 309 } |
| 318 | 310 |
| 319 bool DecodeSignedCertificateTimestamp( | 311 bool DecodeSignedCertificateTimestamp( |
| 320 base::StringPiece* input, | 312 base::StringPiece* input, |
| 321 scoped_refptr<SignedCertificateTimestamp>* output) { | 313 scoped_refptr<SignedCertificateTimestamp>* output) { |
| 322 scoped_refptr<SignedCertificateTimestamp> result( | 314 scoped_refptr<SignedCertificateTimestamp> result( |
| 323 new SignedCertificateTimestamp()); | 315 new SignedCertificateTimestamp()); |
| 324 unsigned version; | 316 unsigned version; |
| 325 if (!ReadUint(kVersionLength, input, &version)) | 317 if (!ReadUint(kVersionLength, input, &version)) |
| 326 return false; | 318 return false; |
| 327 if (version != SignedCertificateTimestamp::SCT_VERSION_1) { | 319 if (version != SignedCertificateTimestamp::SCT_VERSION_1) { |
| 328 DVLOG(1) << "Unsupported/invalid version " << version; | 320 DVLOG(1) << "Unsupported/invalid version " << version; |
| 329 return false; | 321 return false; |
| 330 } | 322 } |
| 331 | 323 |
| 332 result->version = SignedCertificateTimestamp::SCT_VERSION_1; | 324 result->version = SignedCertificateTimestamp::SCT_VERSION_1; |
| 333 uint64 timestamp; | 325 uint64 timestamp; |
| 334 base::StringPiece log_id; | 326 base::StringPiece log_id; |
| 335 base::StringPiece extensions; | 327 base::StringPiece extensions; |
| 336 if (!ReadFixedBytes(kLogIdLength, input, &log_id) || | 328 if (!ReadFixedBytes(kLogIdLength, input, &log_id) || |
| 337 !ReadUint(kTimestampLength, input, ×tamp) || | 329 !ReadUint(kTimestampLength, input, ×tamp) || |
| 338 !ReadVariableBytes(kExtensionsLengthBytes, input, | 330 !ReadVariableBytes(kExtensionsLengthBytes, input, &extensions) || |
| 339 &extensions) || | |
| 340 !DecodeDigitallySigned(input, &result->signature)) { | 331 !DecodeDigitallySigned(input, &result->signature)) { |
| 341 return false; | 332 return false; |
| 342 } | 333 } |
| 343 | 334 |
| 344 if (timestamp > static_cast<uint64>(kint64max)) { | 335 if (timestamp > static_cast<uint64>(kint64max)) { |
| 345 DVLOG(1) << "Timestamp value too big to cast to int64: " << timestamp; | 336 DVLOG(1) << "Timestamp value too big to cast to int64: " << timestamp; |
| 346 return false; | 337 return false; |
| 347 } | 338 } |
| 348 | 339 |
| 349 log_id.CopyToString(&result->log_id); | 340 log_id.CopyToString(&result->log_id); |
| 350 extensions.CopyToString(&result->extensions); | 341 extensions.CopyToString(&result->extensions); |
| 351 result->timestamp = | 342 result->timestamp = |
| 352 base::Time::UnixEpoch() + | 343 base::Time::UnixEpoch() + |
| 353 base::TimeDelta::FromMilliseconds(static_cast<int64>(timestamp)); | 344 base::TimeDelta::FromMilliseconds(static_cast<int64>(timestamp)); |
| 354 | 345 |
| 355 output->swap(result); | 346 output->swap(result); |
| 356 return true; | 347 return true; |
| 357 } | 348 } |
| 358 | 349 |
| 359 bool EncodeSCTListForTesting(const base::StringPiece& sct, | 350 bool EncodeSCTListForTesting(const base::StringPiece& sct, |
| 360 std::string* output) { | 351 std::string* output) { |
| 361 std::string encoded_sct; | 352 std::string encoded_sct; |
| 362 return WriteVariableBytes(kSerializedSCTLengthBytes, sct, &encoded_sct) && | 353 return WriteVariableBytes(kSerializedSCTLengthBytes, sct, &encoded_sct) && |
| 363 WriteVariableBytes(kSCTListLengthBytes, encoded_sct, output); | 354 WriteVariableBytes(kSCTListLengthBytes, encoded_sct, output); |
| 364 } | 355 } |
| 365 | 356 |
| 366 } // namespace ct | 357 } // namespace ct |
| 367 | 358 |
| 368 } // namespace net | 359 } // namespace net |
| OLD | NEW |