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

Unified Diff: net/socket/ssl_host_info.cc

Issue 135373002: Added SSLHostInfo. Storing of server host info to our standard disk cache. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed wtc's comments Created 6 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
Index: net/socket/ssl_host_info.cc
diff --git a/net/socket/ssl_host_info.cc b/net/socket/ssl_host_info.cc
new file mode 100644
index 0000000000000000000000000000000000000000..eea41c7931f9ed75c68039d87bc82f4a83f25bdd
--- /dev/null
+++ b/net/socket/ssl_host_info.cc
@@ -0,0 +1,207 @@
+// Copyright (c) 2012 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/socket/ssl_host_info.h"
+
+#include "base/bind.h"
+#include "base/metrics/histogram.h"
+#include "base/pickle.h"
+#include "base/strings/string_piece.h"
+#include "net/cert/cert_verifier.h"
+#include "net/cert/crl_set.h"
+#include "net/cert/x509_certificate.h"
+#include "net/socket/ssl_client_socket.h"
+#include "net/ssl/ssl_config_service.h"
+
+namespace net {
+
+SSLHostInfo::State::State() {}
+
+SSLHostInfo::State::~State() {}
+
+void SSLHostInfo::State::Clear() {
+ certs.clear();
+}
+
+SSLHostInfo::SSLHostInfo(
+ const std::string& hostname,
+ const SSLConfig& ssl_config,
+ CertVerifier* cert_verifier)
+ : cert_verification_complete_(false),
+ cert_verification_error_(ERR_CERT_INVALID),
+ hostname_(hostname),
+ cert_parsing_failed_(false),
+ rev_checking_enabled_(ssl_config.rev_checking_enabled),
+ verify_ev_cert_(ssl_config.verify_ev_cert),
+ verifier_(cert_verifier),
+ weak_factory_(this) {
+}
+
+SSLHostInfo::~SSLHostInfo() {
+}
+
+const SSLHostInfo::State& SSLHostInfo::state() const {
+ return state_;
+}
+
+SSLHostInfo::State* SSLHostInfo::mutable_state() {
+ return &state_;
+}
+
+bool SSLHostInfo::Parse(const std::string& data) {
+ State* state = mutable_state();
+
+ state->Clear();
+ cert_verification_complete_ = false;
+
+ bool r = ParseInner(data);
+ if (!r)
+ state->Clear();
+ return r;
+}
+
+bool SSLHostInfo::ParseInner(const std::string& data) {
+ State* state = mutable_state();
+
+ Pickle p(data.data(), data.size());
+ PickleIterator iter(p);
+
+ int num_der_certs;
+ if (!p.ReadInt(&iter, &num_der_certs) ||
+ num_der_certs < 0) {
+ return false;
+ }
+
+ for (int i = 0; i < num_der_certs; i++) {
+ std::string der_cert;
+ if (!p.ReadString(&iter, &der_cert))
+ return false;
+ state->certs.push_back(der_cert);
+ }
+
+ // Ignore obsolete members of the State structure.
+ std::string throwaway_string;
+ bool throwaway_bool;
+ // This was state->server_hello.
+ if (!p.ReadString(&iter, &throwaway_string))
+ return false;
+
+ // This was state->npn_valid.
+ if (!p.ReadBool(&iter, &throwaway_bool))
+ return false;
+
+ if (throwaway_bool) {
+ int throwaway_int;
+ // These were state->npn_status and state->npn_protocol.
+ if (!p.ReadInt(&iter, &throwaway_int) ||
+ !p.ReadString(&iter, &throwaway_string)) {
+ return false;
+ }
+ }
+
+ if (!state->certs.empty()) {
+ std::vector<base::StringPiece> der_certs(state->certs.size());
+ for (size_t i = 0; i < state->certs.size(); i++)
+ der_certs[i] = state->certs[i];
+ cert_ = X509Certificate::CreateFromDERCertChain(der_certs);
+ if (cert_.get()) {
+ int flags = 0;
+ if (verify_ev_cert_)
+ flags |= CertVerifier::VERIFY_EV_CERT;
+ if (rev_checking_enabled_)
+ flags |= CertVerifier::VERIFY_REV_CHECKING_ENABLED;
+ VLOG(1) << "Kicking off verification for " << hostname_;
+ verification_start_time_ = base::TimeTicks::Now();
+ verification_end_time_ = base::TimeTicks();
+ scoped_refptr<CRLSet> crl_set(SSLConfigService::GetCRLSet());
+ int rv = verifier_.Verify(
+ cert_.get(), hostname_, flags, crl_set, &cert_verify_result_,
+ base::Bind(&SSLHostInfo::VerifyCallback, weak_factory_.GetWeakPtr()),
+ // TODO(willchan): Figure out how to use NetLog here.
+ BoundNetLog());
+ if (rv != ERR_IO_PENDING)
+ VerifyCallback(rv);
+ } else {
+ cert_parsing_failed_ = true;
+ DCHECK(cert_verification_callback_.is_null());
+ }
+ }
+
+ return true;
+}
+
+std::string SSLHostInfo::Serialize() const {
+ Pickle p(sizeof(Pickle::Header));
+
+ static const unsigned kMaxCertificatesSize = 32 * 1024;
+ unsigned der_certs_size = 0;
+
+ for (std::vector<std::string>::const_iterator
+ i = state_.certs.begin(); i != state_.certs.end(); i++) {
+ der_certs_size += i->size();
+ }
+
+ // We don't care to save the certificates over a certain size.
+ if (der_certs_size > kMaxCertificatesSize)
+ return "";
+
+ if (!p.WriteInt(state_.certs.size()))
+ return "";
+
+ for (std::vector<std::string>::const_iterator
+ i = state_.certs.begin(); i != state_.certs.end(); i++) {
+ if (!p.WriteString(*i))
+ return "";
+ }
+
+ // Write dummy values for obsolete members of the State structure:
+ // state->server_hello and state->npn_valid.
+ if (!p.WriteString("") ||
+ !p.WriteBool(false)) {
+ return "";
+ }
+
+ return std::string(reinterpret_cast<const char *>(p.data()), p.size());
+}
+
+const CertVerifyResult& SSLHostInfo::cert_verify_result() const {
+ return cert_verify_result_;
+}
+
+int SSLHostInfo::WaitForCertVerification(const CompletionCallback& callback) {
+ if (cert_verification_complete_)
+ return cert_verification_error_;
+
+ DCHECK(!cert_parsing_failed_);
+ DCHECK(cert_verification_callback_.is_null());
+ DCHECK(!state_.certs.empty());
+ cert_verification_callback_ = callback;
+ return ERR_IO_PENDING;
+}
+
+void SSLHostInfo::VerifyCallback(int rv) {
+ DCHECK(!verification_start_time_.is_null());
+ base::TimeTicks now = base::TimeTicks::Now();
+ const base::TimeDelta duration = now - verification_start_time();
+ bool is_google = hostname_ == "google.com" ||
+ (hostname_.size() > 11 &&
+ hostname_.rfind(".google.com") == hostname_.size() - 11);
+ if (is_google) {
+ UMA_HISTOGRAM_TIMES("Net.SSLHostInfoVerificationTimeMs_Google", duration);
+ }
+ UMA_HISTOGRAM_TIMES("Net.SSLHostInfoVerificationTimeMs", duration);
+ VLOG(1) << "Verification took " << duration.InMilliseconds() << "ms";
+ verification_end_time_ = now;
+ cert_verification_complete_ = true;
+ cert_verification_error_ = rv;
+ if (!cert_verification_callback_.is_null()) {
+ CompletionCallback callback = cert_verification_callback_;
+ cert_verification_callback_.Reset();
+ callback.Run(rv);
+ }
+}
+
+SSLHostInfoFactory::~SSLHostInfoFactory() {}
+
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698