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 |