Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(509)

Side by Side Diff: net/socket/ssl_client_socket_nss.cc

Issue 13866049: Fix client certificate authentication on Mac and Linux introduced in r178732 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived
6 // from AuthCertificateCallback() in 6 // from AuthCertificateCallback() in
7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp.
8 8
9 /* ***** BEGIN LICENSE BLOCK ***** 9 /* ***** BEGIN LICENSE BLOCK *****
10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 #include "net/ssl/ssl_connection_status_flags.h" 105 #include "net/ssl/ssl_connection_status_flags.h"
106 #include "net/ssl/ssl_info.h" 106 #include "net/ssl/ssl_info.h"
107 107
108 #if defined(OS_WIN) 108 #if defined(OS_WIN)
109 #include <windows.h> 109 #include <windows.h>
110 #include <wincrypt.h> 110 #include <wincrypt.h>
111 #elif defined(OS_MACOSX) 111 #elif defined(OS_MACOSX)
112 #include <Security/SecBase.h> 112 #include <Security/SecBase.h>
113 #include <Security/SecCertificate.h> 113 #include <Security/SecCertificate.h>
114 #include <Security/SecIdentity.h> 114 #include <Security/SecIdentity.h>
115
115 #include "base/mac/mac_logging.h" 116 #include "base/mac/mac_logging.h"
117 #include "base/synchronization/lock.h"
118 #include "crypto/mac_security_services_lock.h"
116 #elif defined(USE_NSS) 119 #elif defined(USE_NSS)
117 #include <dlfcn.h> 120 #include <dlfcn.h>
118 #endif 121 #endif
119 122
120 namespace net { 123 namespace net {
121 124
122 // State machines are easier to debug if you log state transitions. 125 // State machines are easier to debug if you log state transitions.
123 // Enable these if you want to see what's going on. 126 // Enable these if you want to see what's going on.
124 #if 1 127 #if 1
125 #define EnterFunction(x) 128 #define EnterFunction(x)
(...skipping 1264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 1393
1391 // Tell NSS to suspend the client authentication. We will then abort the 1394 // Tell NSS to suspend the client authentication. We will then abort the
1392 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED. 1395 // handshake by returning ERR_SSL_CLIENT_AUTH_CERT_NEEDED.
1393 return SECWouldBlock; 1396 return SECWouldBlock;
1394 #elif defined(OS_MACOSX) 1397 #elif defined(OS_MACOSX)
1395 if (core->ssl_config_.send_client_cert) { 1398 if (core->ssl_config_.send_client_cert) {
1396 if (core->ssl_config_.client_cert) { 1399 if (core->ssl_config_.client_cert) {
1397 OSStatus os_error = noErr; 1400 OSStatus os_error = noErr;
1398 SecIdentityRef identity = NULL; 1401 SecIdentityRef identity = NULL;
1399 SecKeyRef private_key = NULL; 1402 SecKeyRef private_key = NULL;
1400 CFArrayRef chain = 1403 X509Certificate::OSCertHandles chain;
1401 core->ssl_config_.client_cert->CreateClientCertificateChain(); 1404 {
1402 if (chain) { 1405 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
1403 identity = reinterpret_cast<SecIdentityRef>( 1406 os_error = SecIdentityCreateWithCertificate(
1404 const_cast<void*>(CFArrayGetValueAtIndex(chain, 0))); 1407 NULL, core->ssl_config_.client_cert->os_cert_handle(), &identity);
1405 } 1408 }
1406 if (identity) 1409 if (os_error == noErr) {
1407 os_error = SecIdentityCopyPrivateKey(identity, &private_key); 1410 os_error = SecIdentityCopyPrivateKey(identity, &private_key);
wtc 2013/04/16 18:50:32 Just wanted to make sure that we don't need to get
Ryan Sleevi 2013/04/16 19:00:26 Right. Neither of these call into the CSSM/CDSA bi
1411 CFRelease(identity);
1412 }
1408 1413
1409 if (chain && identity && os_error == noErr) { 1414 if (os_error == noErr) {
1410 // TODO(rsleevi): Error checking for NSS allocation errors. 1415 // TODO(rsleevi): Error checking for NSS allocation errors.
1411 *result_certs = CERT_NewCertList(); 1416 *result_certs = CERT_NewCertList();
1412 *result_private_key = private_key; 1417 *result_private_key = private_key;
1413 1418
1414 for (CFIndex i = 0; i < CFArrayGetCount(chain); ++i) { 1419 chain.push_back(core->ssl_config_.client_cert->os_cert_handle());
1420 const X509Certificate::OSCertHandles& intermediates =
1421 core->ssl_config_.client_cert->GetIntermediateCertificates();
1422 if (!intermediates.empty())
1423 chain.insert(chain.end(), intermediates.begin(), intermediates.end());
1424
1425 for (size_t i = 0, chain_count = chain.size(); i < chain_count; ++i) {
1415 CSSM_DATA cert_data; 1426 CSSM_DATA cert_data;
1416 SecCertificateRef cert_ref; 1427 SecCertificateRef cert_ref = chain[i];
1417 if (i == 0) {
1418 cert_ref = core->ssl_config_.client_cert->os_cert_handle();
1419 } else {
1420 cert_ref = reinterpret_cast<SecCertificateRef>(
1421 const_cast<void*>(CFArrayGetValueAtIndex(chain, i)));
1422 }
1423 os_error = SecCertificateGetData(cert_ref, &cert_data); 1428 os_error = SecCertificateGetData(cert_ref, &cert_data);
1424 if (os_error != noErr) 1429 if (os_error != noErr)
1425 break; 1430 break;
1426 1431
1427 SECItem der_cert; 1432 SECItem der_cert;
1428 der_cert.type = siDERCertBuffer; 1433 der_cert.type = siDERCertBuffer;
1429 der_cert.data = cert_data.Data; 1434 der_cert.data = cert_data.Data;
1430 der_cert.len = cert_data.Length; 1435 der_cert.len = cert_data.Length;
1431 CERTCertificate* nss_cert = CERT_NewTempCertificate( 1436 CERTCertificate* nss_cert = CERT_NewTempCertificate(
1432 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE); 1437 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE);
1433 if (!nss_cert) { 1438 if (!nss_cert) {
1434 // In the event of an NSS error we make up an OS error and reuse 1439 // In the event of an NSS error, make up an OS error and reuse
1435 // the error handling, below. 1440 // the error handling below.
1436 os_error = errSecCreateChainFailed; 1441 os_error = errSecCreateChainFailed;
1437 break; 1442 break;
1438 } 1443 }
1439 CERT_AddCertToListTail(*result_certs, nss_cert); 1444 CERT_AddCertToListTail(*result_certs, nss_cert);
1440 } 1445 }
1441 } 1446 }
1447
1442 if (os_error == noErr) { 1448 if (os_error == noErr) {
1443 int cert_count = 0; 1449 core->AddCertProvidedEvent(chain.size());
1444 if (chain) {
1445 cert_count = CFArrayGetCount(chain);
1446 CFRelease(chain);
1447 }
1448 core->AddCertProvidedEvent(cert_count);
1449 return SECSuccess; 1450 return SECSuccess;
1450 } 1451 }
1452
1451 OSSTATUS_LOG(WARNING, os_error) 1453 OSSTATUS_LOG(WARNING, os_error)
1452 << "Client cert found, but could not be used"; 1454 << "Client cert found, but could not be used";
1453 if (*result_certs) { 1455 if (*result_certs) {
1454 CERT_DestroyCertList(*result_certs); 1456 CERT_DestroyCertList(*result_certs);
1455 *result_certs = NULL; 1457 *result_certs = NULL;
1456 } 1458 }
1457 if (*result_private_key) 1459 if (*result_private_key)
1458 *result_private_key = NULL; 1460 *result_private_key = NULL;
1459 if (private_key) 1461 if (private_key)
1460 CFRelease(private_key); 1462 CFRelease(private_key);
1461 if (chain)
1462 CFRelease(chain);
1463 } 1463 }
1464 1464
1465 // Send no client certificate. 1465 // Send no client certificate.
1466 core->AddCertProvidedEvent(0); 1466 core->AddCertProvidedEvent(0);
1467 return SECFailure; 1467 return SECFailure;
1468 } 1468 }
1469 1469
1470 core->nss_handshake_state_.cert_authorities.clear(); 1470 core->nss_handshake_state_.cert_authorities.clear();
1471 1471
1472 // Retrieve the cert issuers accepted by the server. 1472 // Retrieve the cert issuers accepted by the server.
(...skipping 2049 matching lines...) Expand 10 before | Expand all | Expand 10 after
3522 EnsureThreadIdAssigned(); 3522 EnsureThreadIdAssigned();
3523 base::AutoLock auto_lock(lock_); 3523 base::AutoLock auto_lock(lock_);
3524 return valid_thread_id_ == base::PlatformThread::CurrentId(); 3524 return valid_thread_id_ == base::PlatformThread::CurrentId();
3525 } 3525 }
3526 3526
3527 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { 3527 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const {
3528 return server_bound_cert_service_; 3528 return server_bound_cert_service_;
3529 } 3529 }
3530 3530
3531 } // namespace net 3531 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698