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 |