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/socket | |
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/socket')
-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 |
4 files changed, 79 insertions, 85 deletions
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; -}; |