diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-10 21:52:27 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-10 21:52:27 +0000 |
commit | b28f19d7901a742c41987c707168f9f71dc3ea0e (patch) | |
tree | f0b8d142fa83c8b161ffac4f1b472e38c7811af5 | |
parent | e1b19760199e7a1004684840c1641f934029f27a (diff) | |
download | chromium_src-b28f19d7901a742c41987c707168f9f71dc3ea0e.zip chromium_src-b28f19d7901a742c41987c707168f9f71dc3ea0e.tar.gz chromium_src-b28f19d7901a742c41987c707168f9f71dc3ea0e.tar.bz2 |
Add GetNextProtocol method to SSLClientSocket.
http://codereview.chromium.org/484005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34288 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/base/ssl_info.h | 18 | ||||
-rw-r--r-- | net/socket/socket_test_util.cc | 7 | ||||
-rw-r--r-- | net/socket/socket_test_util.h | 1 | ||||
-rw-r--r-- | net/socket/ssl_client_socket.h | 19 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_mac.cc | 6 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_mac.h | 1 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 70 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_nss.h | 1 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_win.cc | 6 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_win.h | 1 |
10 files changed, 82 insertions, 48 deletions
diff --git a/net/base/ssl_info.h b/net/base/ssl_info.h index 5b637c7..3fe0ce4 100644 --- a/net/base/ssl_info.h +++ b/net/base/ssl_info.h @@ -16,25 +16,12 @@ namespace net { // This is really a struct. All members are public. class SSLInfo { public: - // Next Protocol Negotiation (NPN) allows a TLS client and server to come to - // an agreement about the application level protocol to speak over a - // connection. See also the next_protos field in SSLConfig. - enum NextProtoStatus { - kNextProtoUnsupported = 0, // The server doesn't support NPN. - kNextProtoNegotiated = 1, // We agreed on a protocol, see next_proto - kNextProtoNoOverlap = 2, // No protocols in common. We requested - // |next_proto|. - }; - - SSLInfo() : cert_status(0), security_bits(-1), - next_proto_status(kNextProtoUnsupported) { } + SSLInfo() : cert_status(0), security_bits(-1) { } void Reset() { cert = NULL; security_bits = -1; cert_status = 0; - next_proto.clear(); - next_proto_status = kNextProtoUnsupported; } bool is_valid() const { return cert != NULL; } @@ -56,9 +43,6 @@ class SSLInfo { // 0 means the connection is not encrypted. // -1 means the security strength is unknown. int security_bits; - - NextProtoStatus next_proto_status; // One of kNextProto* - std::string next_proto; // The negotiated protocol, if any. }; } // namespace net diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc index 275ca84..9e9daba 100644 --- a/net/socket/socket_test_util.cc +++ b/net/socket/socket_test_util.cc @@ -29,6 +29,13 @@ void MockClientSocket::GetSSLCertRequestInfo( NOTREACHED(); } +SSLClientSocket::NextProtoStatus +MockClientSocket::GetNextProtocol(std::string* proto) { + NOTREACHED(); + proto->clear(); + return SSLClientSocket::kNextProtoUnsupported; +} + void MockClientSocket::Disconnect() { connected_ = false; } diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h index 22b1c80..883b793 100644 --- a/net/socket/socket_test_util.h +++ b/net/socket/socket_test_util.h @@ -276,6 +276,7 @@ class MockClientSocket : public net::SSLClientSocket { virtual void GetSSLInfo(net::SSLInfo* ssl_info); virtual void GetSSLCertRequestInfo( net::SSLCertRequestInfo* cert_request_info); + virtual NextProtoStatus GetNextProtocol(std::string* proto); // Socket methods: virtual int Read(net::IOBuffer* buf, int buf_len, diff --git a/net/socket/ssl_client_socket.h b/net/socket/ssl_client_socket.h index 1b12ebc..4ad0320 100644 --- a/net/socket/ssl_client_socket.h +++ b/net/socket/ssl_client_socket.h @@ -20,6 +20,16 @@ class SSLInfo; // class SSLClientSocket : public ClientSocket { public: + // Next Protocol Negotiation (NPN) allows a TLS client and server to come to + // an agreement about the application level protocol to speak over a + // connection. + enum NextProtoStatus { + kNextProtoUnsupported = 0, // The server doesn't support NPN. + kNextProtoNegotiated = 1, // We agreed on a protocol. + kNextProtoNoOverlap = 2, // No protocols in common. We requested + // the first protocol in our list. + }; + // Next Protocol Negotiation (NPN), if successful, results in agreement on an // application-level string that specifies the application level protocol to // use over the TLS connection. NextProto enumerates the application level @@ -38,6 +48,15 @@ class SSLClientSocket : public ClientSocket { virtual void GetSSLCertRequestInfo( SSLCertRequestInfo* cert_request_info) = 0; + // Get the application level protocol that we negotiated with the server. + // *proto is set to the resulting protocol (n.b. that the string may have + // embedded NULs). + // kNextProtoUnsupported: *proto is cleared. + // kNextProtoNegotiated: *proto is set to the negotiated protocol. + // kNextProtoNoOverlap: *proto is set to the first protocol in the + // supported list. + virtual NextProtoStatus GetNextProtocol(std::string* proto) = 0; + static NextProto NextProtoFromString(const std::string& proto_string) { if (proto_string == "http1.1") { return kProtoHTTP11; diff --git a/net/socket/ssl_client_socket_mac.cc b/net/socket/ssl_client_socket_mac.cc index ec67afa..cc66554 100644 --- a/net/socket/ssl_client_socket_mac.cc +++ b/net/socket/ssl_client_socket_mac.cc @@ -462,6 +462,12 @@ void SSLClientSocketMac::GetSSLCertRequestInfo( // TODO(wtc): implement this. } +SSLClientSocket::NextProtoStatus +SSLClientSocketMac::GetNextProtocol(std::string* proto) { + proto->clear(); + return kNextProtoUnsupported; +} + int SSLClientSocketMac::InitializeSSLContext() { OSStatus status = noErr; diff --git a/net/socket/ssl_client_socket_mac.h b/net/socket/ssl_client_socket_mac.h index 704090c..739121c 100644 --- a/net/socket/ssl_client_socket_mac.h +++ b/net/socket/ssl_client_socket_mac.h @@ -36,6 +36,7 @@ class SSLClientSocketMac : public SSLClientSocket { // SSLClientSocket methods: virtual void GetSSLInfo(SSLInfo* ssl_info); virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); + virtual NextProtoStatus GetNextProtocol(std::string* proto); // ClientSocket methods: virtual int Connect(CompletionCallback* callback, LoadLog* load_log); diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index cc3200c..4968823 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -529,37 +529,6 @@ void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { DCHECK(server_cert_ != NULL); ssl_info->cert = server_cert_; -#ifdef SSL_NEXT_PROTO_NEGOTIATED - unsigned char npn_buf[255]; - unsigned npn_len; - int npn_status; - SECStatus rv = SSL_GetNextProto(nss_fd_, &npn_status, npn_buf, &npn_len, - sizeof(npn_buf)); - if (rv != SECSuccess) { - npn_status = SSL_NEXT_PROTO_NO_SUPPORT; - } - - if (npn_status == SSL_NEXT_PROTO_NO_SUPPORT) { - ssl_info->next_proto_status = SSLInfo::kNextProtoUnsupported; - ssl_info->next_proto.clear(); - } else { - ssl_info->next_proto = - std::string(reinterpret_cast<const char *>(npn_buf), npn_len); - switch (npn_status) { - case SSL_NEXT_PROTO_NEGOTIATED: - ssl_info->next_proto_status = SSLInfo::kNextProtoNegotiated; - break; - case SSL_NEXT_PROTO_NO_OVERLAP: - ssl_info->next_proto_status = SSLInfo::kNextProtoNoOverlap; - break; - default: - LOG(ERROR) << "Unknown npn_status: " << npn_status; - ssl_info->next_proto_status = SSLInfo::kNextProtoNoOverlap; - break; - } - } -#endif - LeaveFunction(""); } @@ -571,6 +540,45 @@ void SSLClientSocketNSS::GetSSLCertRequestInfo( LeaveFunction(cert_request_info->client_certs.size()); } +SSLClientSocket::NextProtoStatus +SSLClientSocketNSS::GetNextProtocol(std::string* proto) { +#if !defined(SSL_NEXT_PROTO_NEGOTIATED) + // No NPN support in the libssl that we are building with. + proto->clear(); + return kNextProtoUnsupported; +#else + unsigned char buf[256]; + int state; + unsigned len; + SECStatus rv = SSL_GetNextProto(nss_fd_, &state, buf, &len, sizeof(buf)); + if (rv != SECSuccess) { + NOTREACHED() << "Error return from SSL_GetNextProto: " << rv; + proto->clear(); + return kNextProtoUnsupported; + } + if (len == sizeof(buf)) { + // Based on the wire protocol, it should be impossible for the protocol + // string to be > 255 bytes long. + NOTREACHED() << "NPN protocol name truncated"; + } + switch(state) { + case SSL_NEXT_PROTO_NO_SUPPORT: + proto->clear(); + return kNextProtoUnsupported; + case SSL_NEXT_PROTO_NEGOTIATED: + *proto = std::string(reinterpret_cast<char*>(buf), len); + return kNextProtoNegotiated; + case SSL_NEXT_PROTO_NO_OVERLAP: + *proto = std::string(reinterpret_cast<char*>(buf), len); + return kNextProtoNoOverlap; + default: + NOTREACHED() << "Unknown status from SSL_GetNextProto: " << state; + proto->clear(); + return kNextProtoUnsupported; + } +#endif +} + void SSLClientSocketNSS::DoReadCallback(int rv) { EnterFunction(rv); DCHECK(rv != ERR_IO_PENDING); diff --git a/net/socket/ssl_client_socket_nss.h b/net/socket/ssl_client_socket_nss.h index 73e6c8c..1ef08ff 100644 --- a/net/socket/ssl_client_socket_nss.h +++ b/net/socket/ssl_client_socket_nss.h @@ -41,6 +41,7 @@ class SSLClientSocketNSS : public SSLClientSocket { // SSLClientSocket methods: virtual void GetSSLInfo(SSLInfo* ssl_info); virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); + virtual NextProtoStatus GetNextProtocol(std::string* proto); // ClientSocket methods: virtual int Connect(CompletionCallback* callback, LoadLog* load_log); diff --git a/net/socket/ssl_client_socket_win.cc b/net/socket/ssl_client_socket_win.cc index 3d1841b..8ac4452 100644 --- a/net/socket/ssl_client_socket_win.cc +++ b/net/socket/ssl_client_socket_win.cc @@ -427,6 +427,12 @@ void SSLClientSocketWin::GetSSLCertRequestInfo( DCHECK(ok); } +SSLClientSocket::NextProtoStatus +SSLClientSocketWin::GetNextProtocol(std::string* proto) { + proto->clear(); + return kNextProtoUnsupported; +} + int SSLClientSocketWin::Connect(CompletionCallback* callback, LoadLog* load_log) { DCHECK(transport_.get()); diff --git a/net/socket/ssl_client_socket_win.h b/net/socket/ssl_client_socket_win.h index 2007844..8b3700b 100644 --- a/net/socket/ssl_client_socket_win.h +++ b/net/socket/ssl_client_socket_win.h @@ -39,6 +39,7 @@ class SSLClientSocketWin : public SSLClientSocket { // SSLClientSocket methods: virtual void GetSSLInfo(SSLInfo* ssl_info); virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); + virtual NextProtoStatus GetNextProtocol(std::string* proto); // ClientSocket methods: virtual int Connect(CompletionCallback* callback, LoadLog* load_log); |