summaryrefslogtreecommitdiffstats
path: root/net/quic
diff options
context:
space:
mode:
authorrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-12 19:23:47 +0000
committerrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-12 19:23:47 +0000
commita69af0522df416013f4233a94632ce4a4c854ebc (patch)
tree6fccae366ebe46c6fd8b494d502da40b595e448a /net/quic
parent17ed3b87579b34bb4838a8a05619e43909875f92 (diff)
downloadchromium_src-a69af0522df416013f4233a94632ce4a4c854ebc.zip
chromium_src-a69af0522df416013f4233a94632ce4a4c854ebc.tar.gz
chromium_src-a69af0522df416013f4233a94632ce4a4c854ebc.tar.bz2
Implement GetSSLInfo for QUIC/https connections.
- CertVerifyResult is saved in QuicCryptoClientConfig::CachedState after Proof is verified. - Because CertVerifyResult is not RefCounted, the data is copied into CachedState. - QuicCryptoClientStream uses CertVerifyResult from CachedState after handshake is completed. - QuicCryptoClientStream::GetSSLInfo fills SSLInfo data from CertVerifyResult. - UI uses SSLInfo to display connection status. - Hardcoded cipher_suite as TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 in SSLInfo. R=jar@chromium.org, agl@@chromium.org Review URL: https://chromiumcodereview.appspot.com/19037002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@211439 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic')
-rw-r--r--net/quic/crypto/crypto_handshake.cc10
-rw-r--r--net/quic/crypto/crypto_handshake.h9
-rw-r--r--net/quic/crypto/proof_test.cc50
-rw-r--r--net/quic/crypto/proof_verifier.h3
-rw-r--r--net/quic/crypto/proof_verifier_chromium.cc8
-rw-r--r--net/quic/crypto/proof_verifier_chromium.h3
-rw-r--r--net/quic/quic_client_session.cc6
-rw-r--r--net/quic/quic_client_session.h2
-rw-r--r--net/quic/quic_crypto_client_stream.cc43
-rw-r--r--net/quic/quic_crypto_client_stream.h11
-rw-r--r--net/quic/quic_http_stream.cc3
-rw-r--r--net/quic/quic_session.cc6
-rw-r--r--net/quic/quic_session.h4
-rw-r--r--net/quic/reliable_quic_stream.cc4
-rw-r--r--net/quic/reliable_quic_stream.h4
15 files changed, 147 insertions, 19 deletions
diff --git a/net/quic/crypto/crypto_handshake.cc b/net/quic/crypto/crypto_handshake.cc
index abac98a..5cf69f7 100644
--- a/net/quic/crypto/crypto_handshake.cc
+++ b/net/quic/crypto/crypto_handshake.cc
@@ -500,11 +500,21 @@ uint64 QuicCryptoClientConfig::CachedState::generation_counter() const {
return generation_counter_;
}
+const CertVerifyResult*
+QuicCryptoClientConfig::CachedState::cert_verify_result() const {
+ return &cert_verify_result_;
+}
+
void QuicCryptoClientConfig::CachedState::set_source_address_token(
StringPiece token) {
source_address_token_ = token.as_string();
}
+void QuicCryptoClientConfig::CachedState::SetCertVerifyResult(
+ const CertVerifyResult& cert_verify_result) {
+ cert_verify_result_.CopyFrom(cert_verify_result);
+}
+
void QuicCryptoClientConfig::SetDefaults() {
// Version must be 0.
// TODO(agl): this version stuff is obsolete now.
diff --git a/net/quic/crypto/crypto_handshake.h b/net/quic/crypto/crypto_handshake.h
index 89e707b..d2f11f8 100644
--- a/net/quic/crypto/crypto_handshake.h
+++ b/net/quic/crypto/crypto_handshake.h
@@ -12,6 +12,8 @@
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
+#include "net/cert/cert_verify_result.h"
+#include "net/cert/x509_certificate.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/quic_protocol.h"
@@ -279,8 +281,10 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
const std::string& signature() const;
bool proof_valid() const;
uint64 generation_counter() const;
+ const CertVerifyResult* cert_verify_result() const;
void set_source_address_token(base::StringPiece token);
+ void SetCertVerifyResult(const CertVerifyResult& cert_verify_result);
private:
std::string server_config_id_; // An opaque id from the server.
@@ -297,6 +301,11 @@ class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
// server_config_valid_ to false.
uint64 generation_counter_;
+ // The result of certificate verification.
+ // TODO(rtenneti): should we change CertVerifyResult to be
+ // RefCountedThreadSafe object to avoid copying.
+ CertVerifyResult cert_verify_result_;
+
// scfg contains the cached, parsed value of |server_config|.
mutable scoped_ptr<CryptoHandshakeMessage> scfg_;
};
diff --git a/net/quic/crypto/proof_test.cc b/net/quic/crypto/proof_test.cc
index 7b38546..9032953 100644
--- a/net/quic/crypto/proof_test.cc
+++ b/net/quic/crypto/proof_test.cc
@@ -6,6 +6,8 @@
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/base/test_data_directory.h"
+#include "net/cert/cert_status_flags.h"
+#include "net/cert/cert_verify_result.h"
#include "net/cert/x509_certificate.h"
#include "net/quic/crypto/proof_source.h"
#include "net/quic/crypto/proof_verifier.h"
@@ -31,6 +33,7 @@ TEST(Proof, Verify) {
const vector<string>* certs;
const vector<string>* first_certs;
string error_details, signature, first_signature;
+ CertVerifyResult cert_verify_result;
ASSERT_TRUE(source->GetProof(hostname, server_config, &first_certs,
&first_signature));
@@ -43,27 +46,31 @@ TEST(Proof, Verify) {
int rv;
TestCompletionCallback callback;
rv = verifier->VerifyProof(hostname, server_config, *certs, signature,
- &error_details, callback.callback());
+ &error_details, &cert_verify_result,
+ callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(OK, rv);
ASSERT_EQ("", error_details);
+ ASSERT_FALSE(IsCertStatusError(cert_verify_result.cert_status));
rv = verifier->VerifyProof("foo.com", server_config, *certs, signature,
- &error_details, callback.callback());
+ &error_details, &cert_verify_result,
+ callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
rv = verifier->VerifyProof(hostname, server_config.substr(1, string::npos),
*certs, signature, &error_details,
- callback.callback());
+ &cert_verify_result, callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
const string corrupt_signature = "1" + signature;
rv = verifier->VerifyProof(hostname, server_config, *certs, corrupt_signature,
- &error_details, callback.callback());
+ &error_details, &cert_verify_result,
+ callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
@@ -73,7 +80,8 @@ TEST(Proof, Verify) {
wrong_certs.push_back((*certs)[i]);
}
rv = verifier->VerifyProof("foo.com", server_config, wrong_certs, signature,
- &error_details, callback.callback());
+ &error_details, &cert_verify_result,
+ callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
@@ -200,6 +208,7 @@ TEST(Proof, VerifyRSAKnownAnswerTest) {
const string server_config = "server config bytes";
const string hostname = "test.example.com";
string error_details;
+ CertVerifyResult cert_verify_result;
vector<string> certs(2);
certs[0] = PEMCertFileToDER("quic_test.example.com.crt");
@@ -220,20 +229,23 @@ TEST(Proof, VerifyRSAKnownAnswerTest) {
int rv;
TestCompletionCallback callback;
rv = verifier->VerifyProof(hostname, server_config, certs, signature,
- &error_details, callback.callback());
+ &error_details, &cert_verify_result,
+ callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(OK, rv);
ASSERT_EQ("", error_details);
+ ASSERT_FALSE(IsCertStatusError(cert_verify_result.cert_status));
rv = verifier->VerifyProof("foo.com", server_config, certs, signature,
- &error_details, callback.callback());
+ &error_details, &cert_verify_result,
+ callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
rv = verifier->VerifyProof(hostname, server_config.substr(1, string::npos),
certs, signature, &error_details,
- callback.callback());
+ &cert_verify_result, callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
@@ -241,7 +253,7 @@ TEST(Proof, VerifyRSAKnownAnswerTest) {
const string corrupt_signature = "1" + signature;
rv = verifier->VerifyProof(hostname, server_config, certs,
corrupt_signature, &error_details,
- callback.callback());
+ &cert_verify_result, callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
@@ -251,7 +263,8 @@ TEST(Proof, VerifyRSAKnownAnswerTest) {
wrong_certs.push_back(certs[i]);
}
rv = verifier->VerifyProof("foo.com", server_config, wrong_certs, signature,
- &error_details, callback.callback());
+ &error_details, &cert_verify_result,
+ callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
@@ -308,6 +321,7 @@ TEST(Proof, MAYBE_VerifyECDSAKnownAnswerTest) {
const string server_config = "server config bytes";
const string hostname = "test.example.com";
string error_details;
+ CertVerifyResult cert_verify_result;
vector<string> certs(2);
certs[0] = PEMCertFileToDER("quic_test_ecc.example.com.crt");
@@ -328,20 +342,23 @@ TEST(Proof, MAYBE_VerifyECDSAKnownAnswerTest) {
int rv;
TestCompletionCallback callback;
rv = verifier->VerifyProof(hostname, server_config, certs, signature,
- &error_details, callback.callback());
+ &error_details, &cert_verify_result,
+ callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(OK, rv);
ASSERT_EQ("", error_details);
+ ASSERT_FALSE(IsCertStatusError(cert_verify_result.cert_status));
rv = verifier->VerifyProof("foo.com", server_config, certs, signature,
- &error_details, callback.callback());
+ &error_details, &cert_verify_result,
+ callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
rv = verifier->VerifyProof(hostname, server_config.substr(1, string::npos),
certs, signature, &error_details,
- callback.callback());
+ &cert_verify_result, callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
@@ -352,7 +369,7 @@ TEST(Proof, MAYBE_VerifyECDSAKnownAnswerTest) {
corrupt_signature[corrupt_signature.size() - 1] += 1;
rv = verifier->VerifyProof(hostname, server_config, certs,
corrupt_signature, &error_details,
- callback.callback());
+ &cert_verify_result, callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
@@ -361,7 +378,7 @@ TEST(Proof, MAYBE_VerifyECDSAKnownAnswerTest) {
const string bad_der_signature1 = "1" + signature;
rv = verifier->VerifyProof(hostname, server_config, certs,
bad_der_signature1, &error_details,
- callback.callback());
+ &cert_verify_result, callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
@@ -371,7 +388,8 @@ TEST(Proof, MAYBE_VerifyECDSAKnownAnswerTest) {
wrong_certs.push_back(certs[i]);
}
rv = verifier->VerifyProof("foo.com", server_config, wrong_certs, signature,
- &error_details, callback.callback());
+ &error_details, &cert_verify_result,
+ callback.callback());
rv = callback.GetResult(rv);
ASSERT_EQ(ERR_FAILED, rv);
ASSERT_NE("", error_details);
diff --git a/net/quic/crypto/proof_verifier.h b/net/quic/crypto/proof_verifier.h
index 406f41e..eb96898 100644
--- a/net/quic/crypto/proof_verifier.h
+++ b/net/quic/crypto/proof_verifier.h
@@ -13,6 +13,8 @@
namespace net {
+class CertVerifyResult;
+
// A ProofVerifier checks the signature on a server config, and the certificate
// chain that backs the public key.
class NET_EXPORT_PRIVATE ProofVerifier {
@@ -37,6 +39,7 @@ class NET_EXPORT_PRIVATE ProofVerifier {
const std::vector<std::string>& certs,
const std::string& signature,
std::string* error_details,
+ CertVerifyResult* cert_verify_result,
const CompletionCallback& callback) = 0;
};
diff --git a/net/quic/crypto/proof_verifier_chromium.cc b/net/quic/crypto/proof_verifier_chromium.cc
index 0c0b71f..6f54788 100644
--- a/net/quic/crypto/proof_verifier_chromium.cc
+++ b/net/quic/crypto/proof_verifier_chromium.cc
@@ -33,6 +33,7 @@ namespace net {
ProofVerifierChromium::ProofVerifierChromium(CertVerifier* cert_verifier,
const BoundNetLog& net_log)
: cert_verifier_(cert_verifier),
+ cert_verify_result_(NULL),
error_details_(NULL),
next_state_(STATE_NONE),
net_log_(net_log) {
@@ -47,9 +48,12 @@ int ProofVerifierChromium::VerifyProof(const string& hostname,
const vector<string>& certs,
const string& signature,
std::string* error_details,
+ CertVerifyResult* cert_verify_result,
const CompletionCallback& callback) {
DCHECK(error_details);
+ DCHECK(cert_verify_result);
error_details->clear();
+ cert_verify_result->Reset();
DCHECK_EQ(STATE_NONE, next_state_);
if (STATE_NONE != next_state_) {
@@ -73,6 +77,7 @@ int ProofVerifierChromium::VerifyProof(const string& hostname,
if (!cert_.get()) {
*error_details = "Failed to create certificate chain";
DLOG(WARNING) << *error_details;
+ cert_verify_result->cert_status = CERT_STATUS_INVALID;
return ERR_FAILED;
}
@@ -87,6 +92,7 @@ int ProofVerifierChromium::VerifyProof(const string& hostname,
hostname_ = hostname;
callback_ = callback;
error_details_ = error_details;
+ cert_verify_result_ = cert_verify_result;
next_state_ = STATE_VERIFY_CERT;
return DoLoop(OK);
@@ -132,7 +138,7 @@ int ProofVerifierChromium::DoVerifyCert(int result) {
hostname_,
flags,
SSLConfigService::GetCRLSet().get(),
- &cert_verify_result_,
+ cert_verify_result_,
base::Bind(&ProofVerifierChromium::OnIOComplete,
base::Unretained(this)),
net_log_);
diff --git a/net/quic/crypto/proof_verifier_chromium.h b/net/quic/crypto/proof_verifier_chromium.h
index f27cc41..134f62b 100644
--- a/net/quic/crypto/proof_verifier_chromium.h
+++ b/net/quic/crypto/proof_verifier_chromium.h
@@ -37,6 +37,7 @@ class NET_EXPORT_PRIVATE ProofVerifierChromium : public ProofVerifier {
const std::vector<std::string>& certs,
const std::string& signature,
std::string* error_details,
+ CertVerifyResult* cert_verify_result,
const CompletionCallback& callback) OVERRIDE;
private:
@@ -65,7 +66,7 @@ class NET_EXPORT_PRIVATE ProofVerifierChromium : public ProofVerifier {
CompletionCallback callback_;
// The result of certificate verification.
- CertVerifyResult cert_verify_result_;
+ CertVerifyResult* cert_verify_result_;
std::string* error_details_;
// X509Certificate from a chain of DER encoded certificates.
diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc
index b92f365..4f103bf 100644
--- a/net/quic/quic_client_session.cc
+++ b/net/quic/quic_client_session.cc
@@ -16,6 +16,7 @@
#include "net/quic/quic_connection_helper.h"
#include "net/quic/quic_crypto_client_stream_factory.h"
#include "net/quic/quic_stream_factory.h"
+#include "net/ssl/ssl_info.h"
#include "net/udp/datagram_client_socket.h"
namespace net {
@@ -117,6 +118,11 @@ QuicCryptoClientStream* QuicClientSession::GetCryptoStream() {
return crypto_stream_.get();
};
+bool QuicClientSession::GetSSLInfo(SSLInfo* ssl_info) {
+ DCHECK(crypto_stream_.get());
+ return crypto_stream_->GetSSLInfo(ssl_info);
+}
+
int QuicClientSession::CryptoConnect(const CompletionCallback& callback) {
RecordHandshakeState(STATE_STARTED);
if (!crypto_stream_->CryptoConnect()) {
diff --git a/net/quic/quic_client_session.h b/net/quic/quic_client_session.h
index 893cfe6..e4a78dd 100644
--- a/net/quic/quic_client_session.h
+++ b/net/quic/quic_client_session.h
@@ -25,6 +25,7 @@ class DatagramClientSocket;
class QuicConnectionHelper;
class QuicCryptoClientStreamFactory;
class QuicStreamFactory;
+class SSLInfo;
namespace test {
class QuicClientSessionPeer;
@@ -51,6 +52,7 @@ class NET_EXPORT_PRIVATE QuicClientSession : public QuicSession {
virtual QuicCryptoClientStream* GetCryptoStream() OVERRIDE;
virtual void CloseStream(QuicStreamId stream_id) OVERRIDE;
virtual void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) OVERRIDE;
+ virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
// QuicConnectionVisitorInterface methods:
virtual void ConnectionClose(QuicErrorCode error, bool from_peer) OVERRIDE;
diff --git a/net/quic/quic_crypto_client_stream.cc b/net/quic/quic_crypto_client_stream.cc
index ab548b2..78b39e7 100644
--- a/net/quic/quic_crypto_client_stream.cc
+++ b/net/quic/quic_crypto_client_stream.cc
@@ -12,6 +12,8 @@
#include "net/quic/crypto/proof_verifier.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_session.h"
+#include "net/ssl/ssl_connection_status_flags.h"
+#include "net/ssl/ssl_info.h"
namespace net {
@@ -46,6 +48,45 @@ int QuicCryptoClientStream::num_sent_client_hellos() const {
return num_client_hellos_;
}
+bool QuicCryptoClientStream::GetSSLInfo(SSLInfo* ssl_info) {
+ ssl_info->Reset();
+ QuicCryptoClientConfig::CachedState* cached =
+ crypto_config_->LookupOrCreate(server_hostname_);
+ DCHECK(cached);
+ if (!cached) {
+ return false;
+ }
+ const CertVerifyResult* cert_verify_result =
+ cached->cert_verify_result();
+
+ ssl_info->cert_status = cert_verify_result->cert_status;
+ ssl_info->cert = cert_verify_result->verified_cert;
+
+ // TODO(rtenneti): Figure out what to set for the following.
+ // Temporarily hard coded cipher_suite as 0xc031 to represent
+ // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (from
+ // net/ssl/ssl_cipher_suite_names.cc) and encryption as 256.
+ int cipher_suite = 0xc02f;
+ int ssl_connection_status = 0;
+ ssl_connection_status |=
+ (cipher_suite & SSL_CONNECTION_CIPHERSUITE_MASK) <<
+ SSL_CONNECTION_CIPHERSUITE_SHIFT;
+ ssl_connection_status |=
+ (SSL_CONNECTION_VERSION_TLS1_2 & SSL_CONNECTION_VERSION_MASK) <<
+ SSL_CONNECTION_VERSION_SHIFT;
+
+ ssl_info->public_key_hashes = cert_verify_result->public_key_hashes;
+ ssl_info->is_issued_by_known_root =
+ cert_verify_result->is_issued_by_known_root;
+
+ ssl_info->connection_status = ssl_connection_status;
+ ssl_info->client_cert_sent = false;
+ ssl_info->channel_id_sent = false;
+ ssl_info->security_bits = 256;
+ ssl_info->handshake_type = SSLInfo::HANDSHAKE_FULL;
+ return true;
+}
+
// kMaxClientHellos is the maximum number of times that we'll send a client
// hello. The value 3 accounts for:
// * One failure due to an incorrect or missing source-address token.
@@ -170,6 +211,7 @@ void QuicCryptoClientStream::DoHandshakeLoop(
cached->certs(),
cached->signature(),
&error_details_,
+ &cert_verify_result_,
base::Bind(&QuicCryptoClientStream::OnVerifyProofComplete,
weak_factory_.GetWeakPtr()));
if (result == ERR_IO_PENDING) {
@@ -190,6 +232,7 @@ void QuicCryptoClientStream::DoHandshakeLoop(
next_state_ = STATE_VERIFY_PROOF;
} else {
cached->SetProofValid();
+ cached->SetCertVerifyResult(cert_verify_result_);
next_state_ = STATE_SEND_CHLO;
}
break;
diff --git a/net/quic/quic_crypto_client_stream.h b/net/quic/quic_crypto_client_stream.h
index 7234050..4686fed 100644
--- a/net/quic/quic_crypto_client_stream.h
+++ b/net/quic/quic_crypto_client_stream.h
@@ -7,6 +7,8 @@
#include <string>
+#include "net/cert/cert_verify_result.h"
+#include "net/cert/x509_certificate.h"
#include "net/quic/crypto/crypto_handshake.h"
#include "net/quic/quic_config.h"
#include "net/quic/quic_crypto_stream.h"
@@ -14,6 +16,7 @@
namespace net {
class QuicSession;
+class SSLInfo;
namespace test {
class CryptoTestUtils;
@@ -40,6 +43,9 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream {
// than the number of round-trips needed for the handshake.
int num_sent_client_hellos() const;
+ // Gets the SSL connection information.
+ bool GetSSLInfo(SSLInfo* ssl_info);
+
private:
friend class test::CryptoTestUtils;
@@ -80,6 +86,11 @@ class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream {
// Generation counter from QuicCryptoClientConfig's CachedState.
uint64 generation_counter_;
+ // The result of certificate verification.
+ // TODO(rtenneti): should we change CertVerifyResult to be
+ // RefCountedThreadSafe object to avoid copying.
+ CertVerifyResult cert_verify_result_;
+
// Error details for ProofVerifier's VerifyProof call.
std::string error_details_;
diff --git a/net/quic/quic_http_stream.cc b/net/quic/quic_http_stream.cc
index 5976c79..25f81c5 100644
--- a/net/quic/quic_http_stream.cc
+++ b/net/quic/quic_http_stream.cc
@@ -17,6 +17,7 @@
#include "net/spdy/spdy_frame_builder.h"
#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_http_utils.h"
+#include "net/ssl/ssl_info.h"
namespace net {
@@ -217,7 +218,7 @@ bool QuicHttpStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
void QuicHttpStream::GetSSLInfo(SSLInfo* ssl_info) {
DCHECK(stream_);
- NOTIMPLEMENTED();
+ stream_->GetSSLInfo(ssl_info);
}
void QuicHttpStream::GetSSLCertRequestInfo(
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc
index e3bb136..9785e27 100644
--- a/net/quic/quic_session.cc
+++ b/net/quic/quic_session.cc
@@ -7,6 +7,7 @@
#include "base/stl_util.h"
#include "net/quic/crypto/proof_verifier.h"
#include "net/quic/quic_connection.h"
+#include "net/ssl/ssl_info.h"
using base::StringPiece;
using base::hash_map;
@@ -368,6 +369,11 @@ void QuicSession::MarkDecompressionBlocked(QuicHeaderId header_id,
decompression_blocked_streams_[header_id] = stream_id;
}
+bool QuicSession::GetSSLInfo(SSLInfo* ssl_info) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
void QuicSession::PostProcessAfterData() {
STLDeleteElements(&closed_streams_);
closed_streams_.clear();
diff --git a/net/quic/quic_session.h b/net/quic/quic_session.h
index 31a05fe..1c9ab1b 100644
--- a/net/quic/quic_session.h
+++ b/net/quic/quic_session.h
@@ -25,6 +25,7 @@ namespace net {
class QuicCryptoStream;
class ReliableQuicStream;
+class SSLInfo;
class VisitorShim;
namespace test {
@@ -145,6 +146,9 @@ class NET_EXPORT_PRIVATE QuicSession : public QuicConnectionVisitorInterface {
QuicSpdyDecompressor* decompressor() { return &decompressor_; }
QuicSpdyCompressor* compressor() { return &compressor_; }
+ // Gets the SSL connection information.
+ virtual bool GetSSLInfo(SSLInfo* ssl_info);
+
QuicErrorCode error() const { return error_; }
protected:
diff --git a/net/quic/reliable_quic_stream.cc b/net/quic/reliable_quic_stream.cc
index 24cae40..364dde71 100644
--- a/net/quic/reliable_quic_stream.cc
+++ b/net/quic/reliable_quic_stream.cc
@@ -155,6 +155,10 @@ QuicSpdyCompressor* ReliableQuicStream::compressor() {
return session_->compressor();
}
+bool ReliableQuicStream::GetSSLInfo(SSLInfo* ssl_info) {
+ return session_->GetSSLInfo(ssl_info);
+}
+
QuicConsumedData ReliableQuicStream::WriteData(StringPiece data, bool fin) {
DCHECK(data.size() > 0 || fin);
return WriteOrBuffer(data, fin);
diff --git a/net/quic/reliable_quic_stream.h b/net/quic/reliable_quic_stream.h
index effcb8b..05abaef 100644
--- a/net/quic/reliable_quic_stream.h
+++ b/net/quic/reliable_quic_stream.h
@@ -26,6 +26,7 @@ class ReliableQuicStreamPeer;
class IPEndPoint;
class QuicSession;
+class SSLInfo;
// All this does right now is send data to subclasses via the sequencer.
class NET_EXPORT_PRIVATE ReliableQuicStream : public
@@ -112,6 +113,9 @@ class NET_EXPORT_PRIVATE ReliableQuicStream : public
QuicSpdyCompressor* compressor();
+ // Gets the SSL connection information.
+ bool GetSSLInfo(SSLInfo* ssl_info);
+
protected:
// Returns a pair with the number of bytes consumed from data, and a boolean
// indicating if the fin bit was consumed. This does not indicate the data