diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-15 15:56:19 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-15 15:56:19 +0000 |
commit | b8b73cf0f4c915d1ba5c2cecdc886f06871e7226 (patch) | |
tree | c6de0f42f4201ab173ab9516821066d9c0e654b0 /net | |
parent | 44894a7d77b6f28e60b85d978f4b513daabf761d (diff) | |
download | chromium_src-b8b73cf0f4c915d1ba5c2cecdc886f06871e7226.zip chromium_src-b8b73cf0f4c915d1ba5c2cecdc886f06871e7226.tar.gz chromium_src-b8b73cf0f4c915d1ba5c2cecdc886f06871e7226.tar.bz2 |
net: Switch SSLHostInfo to using Pickle.
BUG=none
TEST=none
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69262 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/net.gyp | 43 | ||||
-rw-r--r-- | net/socket/ssl_client_socket.h | 2 | ||||
-rw-r--r-- | net/socket/ssl_host_info.cc | 123 | ||||
-rw-r--r-- | net/socket/ssl_host_info.h | 5 | ||||
-rw-r--r-- | net/socket/ssl_host_info.proto | 34 |
5 files changed, 81 insertions, 126 deletions
diff --git a/net/net.gyp b/net/net.gyp index 495d8b7..89abccff 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -338,7 +338,6 @@ '../third_party/zlib/zlib.gyp:zlib', 'net_base', 'net_resources', - 'ssl_host_info', ], 'sources': [ 'disk_cache/addr.cc', @@ -609,6 +608,8 @@ 'socket/ssl_client_socket_win.h', 'socket/ssl_error_params.cc', 'socket/ssl_error_params.h', + 'socket/ssl_host_info.cc', + 'socket/ssl_host_info.h', 'socket/tcp_client_socket.cc', 'socket/tcp_client_socket.h', 'socket/tcp_client_socket_libevent.cc', @@ -1040,46 +1041,6 @@ ], }, { - # This is a separate target in order to limit the scope of the protobuf - # includes. - 'target_name': 'ssl_host_info', - 'type': '<(library)', - 'dependencies': [ - '../base/base.gyp:base', - '../third_party/protobuf/protobuf.gyp:protobuf_lite', - '../third_party/protobuf/protobuf.gyp:protoc#host', - ], - 'sources': [ - 'socket/ssl_host_info.proto', - 'socket/ssl_host_info.cc', - 'socket/ssl_host_info.h', - ], - 'rules': [ - { - 'rule_name': 'genproto', - 'extension': 'proto', - 'inputs': [ - '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', - ], - 'outputs': [ - '<(SHARED_INTERMEDIATE_DIR)/protoc_out/net/socket/<(RULE_INPUT_ROOT).pb.h', - '<(SHARED_INTERMEDIATE_DIR)/protoc_out/net/socket/<(RULE_INPUT_ROOT).pb.cc', - ], - 'action': [ - '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', - 'socket/<(RULE_INPUT_ROOT)<(RULE_INPUT_EXT)', - '--cpp_out=<(SHARED_INTERMEDIATE_DIR)/protoc_out/net', - ], - 'message': 'Generating C++ code from <(RULE_INPUT_PATH)', - 'process_outputs_as_sources': 1, - }, - ], - 'include_dirs': [ - '<(SHARED_INTERMEDIATE_DIR)/protoc_out/net', - '<(SHARED_INTERMEDIATE_DIR)/protoc_out', - ], - }, - { 'target_name': 'net_perftests', 'type': 'executable', 'dependencies': [ diff --git a/net/socket/ssl_client_socket.h b/net/socket/ssl_client_socket.h index 1b424fb..0778e85 100644 --- a/net/socket/ssl_client_socket.h +++ b/net/socket/ssl_client_socket.h @@ -50,6 +50,8 @@ class SSLClientSocket : public ClientSocket { // an agreement about the application level protocol to speak over a // connection. enum NextProtoStatus { + // WARNING: These values are serialised to disk. Don't change them. + kNextProtoUnsupported = 0, // The server doesn't support NPN. kNextProtoNegotiated = 1, // We agreed on a protocol. kNextProtoNoOverlap = 2, // No protocols in common. We requested diff --git a/net/socket/ssl_host_info.cc b/net/socket/ssl_host_info.cc index 61b5aaf..104f0c8 100644 --- a/net/socket/ssl_host_info.cc +++ b/net/socket/ssl_host_info.cc @@ -5,12 +5,12 @@ #include "net/socket/ssl_host_info.h" #include "base/metrics/histogram.h" +#include "base/pickle.h" #include "base/string_piece.h" #include "net/base/cert_verifier.h" #include "net/base/ssl_config_service.h" #include "net/base/x509_certificate.h" #include "net/socket/ssl_client_socket.h" -#include "net/socket/ssl_host_info.pb.h" namespace net { @@ -21,6 +21,12 @@ SSLHostInfo::State::State() SSLHostInfo::State::~State() {} +void SSLHostInfo::State::Clear() { + certs.clear(); + server_hello.clear(); + npn_valid = false; +} + SSLHostInfo::SSLHostInfo( const std::string& hostname, const SSLConfig& ssl_config) @@ -39,36 +45,6 @@ SSLHostInfo::SSLHostInfo( SSLHostInfo::~SSLHostInfo() {} -// This array and the next two functions serve to map between the internal NPN -// status enum (which might change across versions) and the protocol buffer -// based enum (which will not). -static const struct { - SSLClientSocket::NextProtoStatus npn_status; - SSLHostInfoProto::NextProtoStatus proto_status; -} kNPNStatusMapping[] = { - { SSLClientSocket::kNextProtoUnsupported, SSLHostInfoProto::UNSUPPORTED }, - { SSLClientSocket::kNextProtoNegotiated, SSLHostInfoProto::NEGOTIATED }, - { SSLClientSocket::kNextProtoNoOverlap, SSLHostInfoProto::NO_OVERLAP }, -}; - -static SSLClientSocket::NextProtoStatus NPNStatusFromProtoStatus( - SSLHostInfoProto::NextProtoStatus proto_status) { - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kNPNStatusMapping) - 1; i++) { - if (kNPNStatusMapping[i].proto_status == proto_status) - return kNPNStatusMapping[i].npn_status; - } - return kNPNStatusMapping[ARRAYSIZE_UNSAFE(kNPNStatusMapping) - 1].npn_status; -} - -static SSLHostInfoProto::NextProtoStatus ProtoStatusFromNPNStatus( - SSLClientSocket::NextProtoStatus npn_status) { - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kNPNStatusMapping) - 1; i++) { - if (kNPNStatusMapping[i].npn_status == npn_status) - return kNPNStatusMapping[i].proto_status; - } - return kNPNStatusMapping[ARRAYSIZE_UNSAFE(kNPNStatusMapping)-1].proto_status; -} - const SSLHostInfo::State& SSLHostInfo::state() const { return state_; } @@ -78,25 +54,49 @@ SSLHostInfo::State* SSLHostInfo::mutable_state() { } bool SSLHostInfo::Parse(const std::string& data) { - SSLHostInfoProto proto; State* state = mutable_state(); - state->certs.clear(); - state->server_hello.clear(); - state->npn_valid = false; + state->Clear(); cert_verification_complete_ = false; - if (!proto.ParseFromString(data)) + 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()); + void* iter = NULL; + + int num_der_certs; + if (!p.ReadInt(&iter, &num_der_certs) || + num_der_certs < 0) { return false; + } - for (int i = 0; i < proto.certificate_der_size(); i++) - state->certs.push_back(proto.certificate_der(i)); - if (proto.has_server_hello()) - state->server_hello = proto.server_hello(); - if (proto.has_npn_status() && proto.has_npn_protocol()) { - state->npn_valid = true; - state->npn_status = NPNStatusFromProtoStatus(proto.npn_status()); - state->npn_protocol = proto.npn_protocol(); + 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); + } + + if (!p.ReadString(&iter, &state->server_hello)) + return false; + + if (!p.ReadBool(&iter, &state->npn_valid)) + return false; + + if (state->npn_valid) { + int status; + if (!p.ReadInt(&iter, &status) || + !p.ReadString(&iter, &state->npn_protocol)) { + return false; + } + state->npn_status = static_cast<SSLClientSocket::NextProtoStatus>(status); } if (state->certs.size() > 0) { @@ -127,21 +127,42 @@ bool SSLHostInfo::Parse(const std::string& data) { } std::string SSLHostInfo::Serialize() const { - SSLHostInfoProto proto; + 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++) { - proto.add_certificate_der(*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 ""; + } + + if (!p.WriteString(state_.server_hello) || + !p.WriteBool(state_.npn_valid)) { + return ""; } - if (!state_.server_hello.empty()) - proto.set_server_hello(state_.server_hello); if (state_.npn_valid) { - proto.set_npn_status(ProtoStatusFromNPNStatus(state_.npn_status)); - proto.set_npn_protocol(state_.npn_protocol); + if (!p.WriteInt(state_.npn_status) || + !p.WriteString(state_.npn_protocol)) { + return ""; + } } - return proto.SerializeAsString(); + return std::string(reinterpret_cast<const char *>(p.data()), p.size()); } const CertVerifyResult& SSLHostInfo::cert_verify_result() const { diff --git a/net/socket/ssl_host_info.h b/net/socket/ssl_host_info.h index 7f05b5c..9f579a8 100644 --- a/net/socket/ssl_host_info.h +++ b/net/socket/ssl_host_info.h @@ -58,6 +58,8 @@ class SSLHostInfo { State(); ~State(); + void Clear(); + // certs is a vector of DER encoded X.509 certificates, as the server // returned them and in the same order. std::vector<std::string> certs; @@ -108,6 +110,9 @@ class SSLHostInfo { // This is the callback function which the CertVerifier calls via |callback_|. void VerifyCallback(int rv); + // ParseInner is a helper function for Parse. + bool ParseInner(const std::string& data); + // This is the hostname that we'll validate the certificates against. const std::string hostname_; bool cert_parsing_failed_; diff --git a/net/socket/ssl_host_info.proto b/net/socket/ssl_host_info.proto deleted file mode 100644 index d74a872..0000000 --- a/net/socket/ssl_host_info.proto +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2010 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. - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -package net; - -// SSLHostInfoProto contains information which we store about a given HTTPS -// server. -message SSLHostInfoProto { - // The certificate chain, as returned by the server, as a series of DER - // encoded X.509 certificates. - repeated bytes certificate_der = 1; - // The contents of the server's ServerHello message. Needed in order to - // predict its response in the case of Snap Start. - optional bytes server_hello = 2; - - // This is a mirror of SSLClientSocket::NextProtoStatus. We use this in order - // to be robust against changes to that enum, which isn't required to be - // stable across versions. See the comments there for details. - enum NextProtoStatus { - UNSUPPORTED = 0; - NEGOTIATED = 1; - NO_OVERLAP = 2; - } - - // When doing Snap Start, we also need to know what protocol we expect the - // server to negotiate. - optional NextProtoStatus npn_status = 3; - optional bytes npn_protocol = 4; -}; |