Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |