| Index: net/socket/ssl_client_socket_mac.cc
|
| ===================================================================
|
| --- net/socket/ssl_client_socket_mac.cc (revision 58298)
|
| +++ net/socket/ssl_client_socket_mac.cc (working copy)
|
| @@ -802,17 +802,21 @@
|
| if (status)
|
| return NetErrorFromOSStatus(status);
|
|
|
| + // It is tricky to handle client cert request over renegotiation due to bugs
|
| + // in Secure Transport. From Ken McLeod on apple-cdsa:
|
| + // http://lists.apple.com/archives/apple-cdsa/2010/Feb/msg00058.html
|
| + // A possible workaround would be to set the
|
| + // kSSLSessionOptionBreakOnCertRequested option initially, then if you get
|
| + // that status, ask for a client cert, abort the connection yourself and
|
| + // retry it (this time calling SSLSetCertificate before the handshake
|
| + // starts, and *not* setting the kSSLSessionOptionBreakOnCertRequested
|
| + // option.)
|
| if (ssl_config_.send_client_cert) {
|
| - // Provide the client cert up-front if we have one, even though we'll get
|
| - // notified later when the server requests it, and set it again; this is
|
| - // seemingly redundant but works around a problem with SecureTransport
|
| - // and provides correct behavior on both 10.5 and 10.6:
|
| - // http://lists.apple.com/archives/apple-cdsa/2010/Feb/msg00058.html
|
| - // http://code.google.com/p/chromium/issues/detail?id=38905
|
| SSL_LOG << "Setting client cert in advance because send_client_cert is set";
|
| status = SetClientCert();
|
| if (status)
|
| return NetErrorFromOSStatus(status);
|
| + return OK;
|
| }
|
|
|
| status = EnableBreakOnAuth(true);
|
| @@ -1109,11 +1113,8 @@
|
| break;
|
| case errSSLClientCertRequested:
|
| SSL_LOG << "Server requested client cert (DoHandshakeFinish)";
|
| - if (!ssl_config_.send_client_cert)
|
| - return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
|
| - // (We already called SetClientCert during InitializeSSLContext.)
|
| - status = noErr;
|
| - next_handshake_state_ = STATE_HANDSHAKE_FINISH;
|
| + DCHECK(!ssl_config_.send_client_cert);
|
| + return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
|
| break;
|
| case errSSLClosedGraceful:
|
| return ERR_SSL_PROTOCOL_ERROR;
|
| @@ -1148,16 +1149,7 @@
|
| }
|
|
|
| void SSLClientSocketMac::HandshakeFinished() {
|
| - // After the handshake's finished, disable breaking on server or client
|
| - // auth. Otherwise it might be triggered during a subsequent renegotiation,
|
| - // and SecureTransport doesn't handle that very well (there's usually no way
|
| - // to proceed without aborting the connection, at least not on 10.5.)
|
| SSL_LOG << "HandshakeFinished()";
|
| - OSStatus status = EnableBreakOnAuth(false);
|
| - if (status != noErr)
|
| - SSL_LOG << "EnableBreakOnAuth failed: " << status;
|
| - // Note- this will actually always return an error, up through OS 10.6.3,
|
| - // because the option can't be changed after the context opens.
|
| }
|
|
|
| int SSLClientSocketMac::DoPayloadRead() {
|
| @@ -1187,14 +1179,7 @@
|
| case errSSLClientCertRequested:
|
| // Server wants to renegotiate, probably to ask for a client cert,
|
| // but SecureTransport doesn't support renegotiation so we have to close.
|
| - if (ssl_config_.send_client_cert) {
|
| - // We already gave SecureTransport a client cert. At this point there's
|
| - // nothing we can do; the renegotiation will fail regardless, due to
|
| - // bugs in Apple's SecureTransport library.
|
| - SSL_LOG << "Server renegotiating (status=" << status
|
| - << "), but I've already set a client cert. Fatal error.";
|
| - return ERR_SSL_PROTOCOL_ERROR;
|
| - }
|
| + DCHECK(!ssl_config_.send_client_cert);
|
| // Tell my caller the server wants a client cert so it can reconnect.
|
| SSL_LOG << "Server renegotiating; assuming it wants a client cert...";
|
| return ERR_SSL_CLIENT_AUTH_CERT_NEEDED;
|
|
|