summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsnej@chromium.org <snej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 19:14:11 +0000
committersnej@chromium.org <snej@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 19:14:11 +0000
commit74c8c01e419157845cd53938f661e5437589d296 (patch)
treea3666cb07ffe3c70630a751bdf08441cd72976f5
parent4087b4152b3525bffa7b8cb22a04a81827d7e88d (diff)
downloadchromium_src-74c8c01e419157845cd53938f661e5437589d296.zip
chromium_src-74c8c01e419157845cd53938f661e5437589d296.tar.gz
chromium_src-74c8c01e419157845cd53938f661e5437589d296.tar.bz2
Mac: Work around SSL renegotiation problems with client certs.
I've gotten several sites (startcom and foaf.me) to work by aborting the connection on renegotiation, telling the caller to ask for a client cert, and then when a client cert is provided not enabling break-on-auth. BUG=36207 TEST=none Review URL: http://codereview.chromium.org/669110 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40762 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/base/x509_certificate_mac.cc1
-rw-r--r--net/socket/ssl_client_socket_mac.cc25
2 files changed, 15 insertions, 11 deletions
diff --git a/net/base/x509_certificate_mac.cc b/net/base/x509_certificate_mac.cc
index 36fc65a..64098f4 100644
--- a/net/base/x509_certificate_mac.cc
+++ b/net/base/x509_certificate_mac.cc
@@ -770,7 +770,6 @@ bool X509Certificate::GetSSLClientCertificates (
SecIdentitySearchRef search = nil;
OSStatus err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_SIGN, &search);
- fprintf(stderr,"====Created SecIdentitySearch %p\n",search);//TEMP
scoped_cftyperef<SecIdentitySearchRef> scoped_search(search);
while (!err) {
SecIdentityRef identity = NULL;
diff --git a/net/socket/ssl_client_socket_mac.cc b/net/socket/ssl_client_socket_mac.cc
index 0720a40..7b01409 100644
--- a/net/socket/ssl_client_socket_mac.cc
+++ b/net/socket/ssl_client_socket_mac.cc
@@ -189,6 +189,7 @@ int NetErrorFromOSStatus(OSStatus status) {
case errSSLPeerInsufficientSecurity...errSSLPeerUnknownCA:
// (Note that all errSSLPeer* codes indicate errors reported by the
// peer, so the cert-related ones refer to my _client_ cert.)
+ LOG(WARNING) << "Server rejected client cert (OSStatus=" << status << ")";
return ERR_BAD_SSL_CLIENT_AUTH_CERT;
case errSSLBadRecordMac:
@@ -734,7 +735,7 @@ int SSLClientSocketMac::InitializeSSLContext() {
static SSLSetSessionOptionFuncPtr ssl_set_session_options =
LookupFunction<SSLSetSessionOptionFuncPtr>(CFSTR("com.apple.security"),
CFSTR("SSLSetSessionOption"));
- if (ssl_set_session_options) {
+ if (ssl_set_session_options && !ssl_config_.send_client_cert) {
status = ssl_set_session_options(ssl_context_,
kSSLSessionOptionBreakOnServerAuth,
true);
@@ -773,7 +774,8 @@ int SSLClientSocketMac::InitializeSSLContext() {
if (status)
return NetErrorFromOSStatus(status);
} else {
- // If I can't break on cert-requested, then set the cert up-front:
+ // If I have a cert, set it up-front, otherwise the server may try to get
+ // it later by renegotiating, which SecureTransport doesn't support well.
status = SetClientCert();
if (status)
return NetErrorFromOSStatus(status);
@@ -1009,12 +1011,14 @@ int SSLClientSocketMac::DoHandshakeFinish() {
case errSSLClosedAbort:
case errSSLPeerHandshakeFail: {
// See if the server aborted due to client cert checking.
- SSLClientCertificateState clientState;
- if (SSLGetClientCertificateState(ssl_context_, &clientState) == noErr &&
- clientState > kSSLClientCertNone) {
- if (clientState == kSSLClientCertRequested &&
+ SSLClientCertificateState client_state;
+ if (SSLGetClientCertificateState(ssl_context_, &client_state) == noErr &&
+ client_state > kSSLClientCertNone) {
+ if (client_state == kSSLClientCertRequested &&
!ssl_config_.send_client_cert)
return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
+ LOG(WARNING) << "Server aborted SSL handshake; client_state=" <<
+ client_state;
return ERR_BAD_SSL_CLIENT_AUTH_CERT;
}
break;
@@ -1055,10 +1059,11 @@ int SSLClientSocketMac::DoPayloadRead() {
case errSSLServerAuthCompleted:
case errSSLClientCertRequested:
- // Server wants to renegotiate, probably to ask for a client cert.
- // We don't support this yet, so abort.
- // TODO(snej): Work around the SecureTransport issues.
- return ERR_BAD_SSL_CLIENT_AUTH_CERT;
+ // Server wants to renegotiate, probably to ask for a client cert,
+ // but SecureTransport doesn't support renegotiation so we have to close.
+ // Tell my caller the server wants a client cert so it can reconnect.
+ LOG(INFO) << "Server renegotiating for client cert; restarting...";
+ return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
default:
return NetErrorFromOSStatus(status);