diff options
Diffstat (limited to 'net/base')
-rw-r--r-- | net/base/net_error_list.h | 3 | ||||
-rw-r--r-- | net/base/socket_test_util.cc | 7 | ||||
-rw-r--r-- | net/base/ssl_cert_request_info.h | 37 | ||||
-rw-r--r-- | net/base/ssl_client_socket.h | 8 | ||||
-rw-r--r-- | net/base/ssl_client_socket_mac.cc | 8 | ||||
-rw-r--r-- | net/base/ssl_client_socket_mac.h | 3 | ||||
-rw-r--r-- | net/base/ssl_client_socket_nss.cc | 7 | ||||
-rw-r--r-- | net/base/ssl_client_socket_nss.h | 3 | ||||
-rw-r--r-- | net/base/ssl_client_socket_win.cc | 46 | ||||
-rw-r--r-- | net/base/ssl_client_socket_win.h | 6 | ||||
-rw-r--r-- | net/base/ssl_config_service.h | 12 |
11 files changed, 100 insertions, 40 deletions
diff --git a/net/base/net_error_list.h b/net/base/net_error_list.h index e22e11f..d0f91c4 100644 --- a/net/base/net_error_list.h +++ b/net/base/net_error_list.h @@ -106,6 +106,9 @@ NET_ERROR(PROXY_AUTH_REQUESTED, -115) // certificate error. NET_ERROR(CERT_ERROR_IN_SSL_RENEGOTIATION, -116) +// The SSL handshake failed because of a bad or missing client certificate. +NET_ERROR(BAD_SSL_CLIENT_AUTH_CERT, -117) + // Certificate error codes // // The values of certificate error codes must be consecutive. diff --git a/net/base/socket_test_util.cc b/net/base/socket_test_util.cc index fa7f63e..cd9bd77 100644 --- a/net/base/socket_test_util.cc +++ b/net/base/socket_test_util.cc @@ -24,6 +24,8 @@ class MockClientSocket : public net::SSLClientSocket { // SSLClientSocket methods: virtual void GetSSLInfo(net::SSLInfo* ssl_info); + virtual void GetSSLCertRequestInfo( + net::SSLCertRequestInfo* cert_request_info); virtual void Disconnect(); virtual bool IsConnected() const; virtual bool IsConnectedAndIdle() const; @@ -105,6 +107,11 @@ void MockClientSocket::GetSSLInfo(net::SSLInfo* ssl_info) { NOTREACHED(); } +void MockClientSocket::GetSSLCertRequestInfo( + net::SSLCertRequestInfo* cert_request_info) { + NOTREACHED(); +} + void MockClientSocket::Disconnect() { connected_ = false; callback_ = NULL; diff --git a/net/base/ssl_cert_request_info.h b/net/base/ssl_cert_request_info.h new file mode 100644 index 0000000..2529d87 --- /dev/null +++ b/net/base/ssl_cert_request_info.h @@ -0,0 +1,37 @@ +// Copyright (c) 2009 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. + +#ifndef NET_BASE_SSL_CERT_REQUEST_INFO_H_ +#define NET_BASE_SSL_CERT_REQUEST_INFO_H_ + +#include <string> +#include <vector> + +#include "base/ref_counted.h" + +namespace net { + +class X509Certificate; + +// The SSLCertRequestInfo class contains the info that allows a user to +// select a certificate to send to the SSL server for client authentication. +class SSLCertRequestInfo + : public base::RefCountedThreadSafe<SSLCertRequestInfo> { + public: + // The host and port of the SSL server that requested client authentication. + std::string host_and_port; + + // A list of client certificates that match the server's criteria in the + // SSL CertificateRequest message. In TLS 1.0, the CertificateRequest + // message is defined as: + // struct { + // ClientCertificateType certificate_types<1..2^8-1>; + // DistinguishedName certificate_authorities<3..2^16-1>; + // } CertificateRequest; + std::vector<scoped_refptr<X509Certificate> > client_certs; +}; + +} // namespace net + +#endif // NET_BASE_SSL_CERT_REQUEST_INFO_H_ diff --git a/net/base/ssl_client_socket.h b/net/base/ssl_client_socket.h index 8c9f05b..8b9cca6 100644 --- a/net/base/ssl_client_socket.h +++ b/net/base/ssl_client_socket.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -9,6 +9,7 @@ namespace net { +class SSLCertRequestInfo; class SSLInfo; // A client socket that uses SSL as the transport layer. @@ -21,6 +22,11 @@ class SSLClientSocket : public ClientSocket { public: // Gets the SSL connection information of the socket. virtual void GetSSLInfo(SSLInfo* ssl_info) = 0; + + // Gets the SSL CertificateRequest info of the socket after Connect failed + // with ERR_SSL_CLIENT_AUTH_CERT_NEEDED. + virtual void GetSSLCertRequestInfo( + SSLCertRequestInfo* cert_request_info) = 0; }; } // namespace net diff --git a/net/base/ssl_client_socket_mac.cc b/net/base/ssl_client_socket_mac.cc index 2148a2b..7528b13 100644 --- a/net/base/ssl_client_socket_mac.cc +++ b/net/base/ssl_client_socket_mac.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2008-2009 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. @@ -418,6 +418,11 @@ void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) { ssl_info->security_bits = KeySizeOfCipherSuite(suite); } +void SSLClientSocketMac::GetSSLCertRequestInfo( + SSLCertRequestInfo* cert_request_info) { + // TODO(wtc): implement this. +} + void SSLClientSocketMac::DoCallback(int rv) { DCHECK(rv != ERR_IO_PENDING); DCHECK(user_callback_); @@ -743,7 +748,6 @@ OSStatus SSLClientSocketMac::SSLWriteCallback(SSLConnectionRef connection, if (rv > 0) { us->send_buffer_.erase(us->send_buffer_.begin(), us->send_buffer_.begin() + rv); - } } while (rv > 0 && !us->send_buffer_.empty()); diff --git a/net/base/ssl_client_socket_mac.h b/net/base/ssl_client_socket_mac.h index 9d4dec0..6e088bb 100644 --- a/net/base/ssl_client_socket_mac.h +++ b/net/base/ssl_client_socket_mac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -31,6 +31,7 @@ class SSLClientSocketMac : public SSLClientSocket { // SSLClientSocket methods: virtual void GetSSLInfo(SSLInfo* ssl_info); + virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); // ClientSocket methods: virtual int Connect(CompletionCallback* callback); diff --git a/net/base/ssl_client_socket_nss.cc b/net/base/ssl_client_socket_nss.cc index 6c8aeca..d64d791 100644 --- a/net/base/ssl_client_socket_nss.cc +++ b/net/base/ssl_client_socket_nss.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -490,6 +490,11 @@ void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { LeaveFunction(""); } +void SSLClientSocketNSS::GetSSLCertRequestInfo( + SSLCertRequestInfo* cert_request_info) { + // TODO(wtc): implement this. +} + void SSLClientSocketNSS::DoCallback(int rv) { EnterFunction(rv); DCHECK(rv != ERR_IO_PENDING); diff --git a/net/base/ssl_client_socket_nss.h b/net/base/ssl_client_socket_nss.h index 71decf5..643051f 100644 --- a/net/base/ssl_client_socket_nss.h +++ b/net/base/ssl_client_socket_nss.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -40,6 +40,7 @@ class SSLClientSocketNSS : public SSLClientSocket { // SSLClientSocket methods: virtual void GetSSLInfo(SSLInfo* ssl_info); + virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); // ClientSocket methods: virtual int Connect(CompletionCallback* callback); diff --git a/net/base/ssl_client_socket_win.cc b/net/base/ssl_client_socket_win.cc index a839bb3..43641e3 100644 --- a/net/base/ssl_client_socket_win.cc +++ b/net/base/ssl_client_socket_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -232,7 +232,6 @@ SSLClientSocketWin::SSLClientSocketWin(ClientSocket* transport_socket, writing_first_token_(false), completed_handshake_(false), ignore_ok_result_(false), - no_client_cert_(false), renegotiating_(false) { memset(&stream_sizes_, 0, sizeof(stream_sizes_)); memset(in_buffers_, 0, sizeof(in_buffers_)); @@ -261,6 +260,11 @@ void SSLClientSocketWin::GetSSLInfo(SSLInfo* ssl_info) { } } +void SSLClientSocketWin::GetSSLCertRequestInfo( + SSLCertRequestInfo* cert_request_info) { + // TODO(wtc): implement this. +} + int SSLClientSocketWin::Connect(CompletionCallback* callback) { DCHECK(transport_.get()); DCHECK(next_state_ == STATE_NONE); @@ -544,14 +548,7 @@ int SSLClientSocketWin::DoHandshakeReadComplete(int result) { ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM; - // When InitializeSecurityContext returns SEC_I_INCOMPLETE_CREDENTIALS, - // John Banes (a Microsoft security developer) said we need to pass in the - // ISC_REQ_USE_SUPPLIED_CREDS flag if we skip finding a client certificate - // and just call InitializeSecurityContext again. (See - // (http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/2004-08/0187.html.) - // My testing on XP SP2 and Vista SP1 shows that it still works without - // passing in this flag, but I pass it in to be safe. - if (no_client_cert_) + if (ssl_config_.send_client_cert) flags |= ISC_REQ_USE_SUPPLIED_CREDS; SecBufferDesc in_buffer_desc, out_buffer_desc; @@ -623,28 +620,21 @@ int SSLClientSocketWin::DidCallInitializeSecurityContext() { int result = MapSecurityError(isc_status_); // We told Schannel to not verify the server certificate // (SCH_CRED_MANUAL_CRED_VALIDATION), so any certificate error returned by - // InitializeSecurityContext must be referring to the (missing) client - // certificate. + // InitializeSecurityContext must be referring to the bad or missing + // client certificate. if (IsCertificateError(result)) { - // TODO(wtc): When we support SSL client authentication, we will need to - // add new error codes for client certificate errors reported by the - // server using SSL/TLS alert messages. See http://crbug.com/318. See - // also the MSDN page "Schannel Error Codes for TLS and SSL Alerts", - // which maps TLS alert messages to Windows error codes: + // TODO(wtc): Add new error codes for client certificate errors reported + // by the server using SSL/TLS alert messages. See the MSDN page + // "Schannel Error Codes for TLS and SSL Alerts", which maps TLS alert + // messages to Windows error codes: // http://msdn.microsoft.com/en-us/library/dd721886%28VS.85%29.aspx - return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; + return ERR_BAD_SSL_CLIENT_AUTH_CERT; } return result; } - if (isc_status_ == SEC_I_INCOMPLETE_CREDENTIALS) { - // We don't support SSL client authentication yet. For now we just set - // no_client_cert_ to true and call InitializeSecurityContext again. - no_client_cert_ = true; - next_state_ = STATE_HANDSHAKE_READ_COMPLETE; - ignore_ok_result_ = true; // OK doesn't mean EOF. - return OK; - } + if (isc_status_ == SEC_I_INCOMPLETE_CREDENTIALS) + return ERR_SSL_CLIENT_AUTH_CERT_NEEDED; DCHECK(isc_status_ == SEC_I_CONTINUE_NEEDED); if (in_buffers_[1].BufferType == SECBUFFER_EXTRA) { @@ -989,7 +979,7 @@ int SSLClientSocketWin::DidCompleteHandshake() { SECURITY_STATUS status = QueryContextAttributes( &ctxt_, SECPKG_ATTR_STREAM_SIZES, &stream_sizes_); if (status != SEC_E_OK) { - DLOG(ERROR) << "QueryContextAttributes failed: " << status; + DLOG(ERROR) << "QueryContextAttributes (stream sizes) failed: " << status; return MapSecurityError(status); } DCHECK(!server_cert_ || renegotiating_); @@ -997,7 +987,7 @@ int SSLClientSocketWin::DidCompleteHandshake() { status = QueryContextAttributes( &ctxt_, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &server_cert_handle); if (status != SEC_E_OK) { - DLOG(ERROR) << "QueryContextAttributes failed: " << status; + DLOG(ERROR) << "QueryContextAttributes (remote cert) failed: " << status; return MapSecurityError(status); } if (renegotiating_ && diff --git a/net/base/ssl_client_socket_win.h b/net/base/ssl_client_socket_win.h index 35f1e9e..12bf18f 100644 --- a/net/base/ssl_client_socket_win.h +++ b/net/base/ssl_client_socket_win.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -36,6 +36,7 @@ class SSLClientSocketWin : public SSLClientSocket { // SSLClientSocket methods: virtual void GetSSLInfo(SSLInfo* ssl_info); + virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); // ClientSocket methods: virtual int Connect(CompletionCallback* callback); @@ -147,9 +148,6 @@ class SSLClientSocketWin : public SSLClientSocket { // to be interpreted as EOF. bool ignore_ok_result_; - // True if the user has no client certificate. - bool no_client_cert_; - // Renegotiation is in progress. bool renegotiating_; }; diff --git a/net/base/ssl_config_service.h b/net/base/ssl_config_service.h index dec6fdb..cf2c9bb 100644 --- a/net/base/ssl_config_service.h +++ b/net/base/ssl_config_service.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -18,7 +18,7 @@ struct SSLConfig { // Default to SSL 2.0 off, SSL 3.0 on, and TLS 1.0 on. SSLConfig() : rev_checking_enabled(false), ssl2_enabled(false), - ssl3_enabled(true), tls1_enabled(true) { + ssl3_enabled(true), tls1_enabled(true), send_client_cert(false) { } bool rev_checking_enabled; // True if server certificate revocation @@ -27,11 +27,19 @@ struct SSLConfig { bool ssl3_enabled; // True if SSL 3.0 is enabled. bool tls1_enabled; // True if TLS 1.0 is enabled. + // TODO(wtc): move the following members to a new SSLParams structure. They + // are not SSL configuration settings. + // Add any known-bad SSL certificates to allowed_bad_certs_ that should not // trigger an ERR_CERT_*_INVALID error when calling SSLClientSocket::Connect. // This would normally be done in response to the user explicitly accepting // the bad certificate. std::set<scoped_refptr<X509Certificate> > allowed_bad_certs_; + + // True if we should send client_cert to the server. + bool send_client_cert; + + scoped_refptr<X509Certificate> client_cert; }; // This class is responsible for getting and setting the SSL configuration. |