summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-10 21:52:27 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-10 21:52:27 +0000
commitb28f19d7901a742c41987c707168f9f71dc3ea0e (patch)
treef0b8d142fa83c8b161ffac4f1b472e38c7811af5
parente1b19760199e7a1004684840c1641f934029f27a (diff)
downloadchromium_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.h18
-rw-r--r--net/socket/socket_test_util.cc7
-rw-r--r--net/socket/socket_test_util.h1
-rw-r--r--net/socket/ssl_client_socket.h19
-rw-r--r--net/socket/ssl_client_socket_mac.cc6
-rw-r--r--net/socket/ssl_client_socket_mac.h1
-rw-r--r--net/socket/ssl_client_socket_nss.cc70
-rw-r--r--net/socket/ssl_client_socket_nss.h1
-rw-r--r--net/socket/ssl_client_socket_win.cc6
-rw-r--r--net/socket/ssl_client_socket_win.h1
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);