OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "net/base/x509_certificate.h" | 5 #include "net/base/x509_certificate.h" |
6 | 6 |
7 #include <CommonCrypto/CommonDigest.h> | 7 #include <CommonCrypto/CommonDigest.h> |
8 #include <CoreServices/CoreServices.h> | 8 #include <CoreServices/CoreServices.h> |
9 #include <Security/Security.h> | 9 #include <Security/Security.h> |
10 #include <time.h> | 10 #include <time.h> |
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 ScopedCFTypeRef<CFArrayRef> trust_policies; | 740 ScopedCFTypeRef<CFArrayRef> trust_policies; |
741 OSStatus status = CreateTrustPolicies(hostname, flags, &trust_policies); | 741 OSStatus status = CreateTrustPolicies(hostname, flags, &trust_policies); |
742 if (status) | 742 if (status) |
743 return NetErrorFromOSStatus(status); | 743 return NetErrorFromOSStatus(status); |
744 | 744 |
745 // Create and configure a SecTrustRef, which takes our certificate(s) | 745 // Create and configure a SecTrustRef, which takes our certificate(s) |
746 // and our SSL SecPolicyRef. SecTrustCreateWithCertificates() takes an | 746 // and our SSL SecPolicyRef. SecTrustCreateWithCertificates() takes an |
747 // array of certificates, the first of which is the certificate we're | 747 // array of certificates, the first of which is the certificate we're |
748 // verifying, and the subsequent (optional) certificates are used for | 748 // verifying, and the subsequent (optional) certificates are used for |
749 // chain building. | 749 // chain building. |
750 CFMutableArrayRef cert_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, | 750 ScopedCFTypeRef<CFArrayRef> cert_array(CreateOSCertChainForCert()); |
751 &kCFTypeArrayCallBacks); | |
752 if (!cert_array) | |
753 return ERR_OUT_OF_MEMORY; | |
754 ScopedCFTypeRef<CFArrayRef> scoped_cert_array(cert_array); | |
755 CFArrayAppendValue(cert_array, cert_handle_); | |
756 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) | |
757 CFArrayAppendValue(cert_array, intermediate_ca_certs_[i]); | |
758 | 751 |
759 // From here on, only one thread can be active at a time. We have had a number | 752 // From here on, only one thread can be active at a time. We have had a number |
760 // of sporadic crashes in the SecTrustEvaluate call below, way down inside | 753 // of sporadic crashes in the SecTrustEvaluate call below, way down inside |
761 // Apple's cert code, which we suspect are caused by a thread-safety issue. | 754 // Apple's cert code, which we suspect are caused by a thread-safety issue. |
762 // So as a speculative fix allow only one thread to use SecTrust on this cert. | 755 // So as a speculative fix allow only one thread to use SecTrust on this cert. |
763 base::AutoLock lock(verification_lock_); | 756 base::AutoLock lock(verification_lock_); |
764 | 757 |
765 SecTrustRef trust_ref = NULL; | 758 SecTrustRef trust_ref = NULL; |
766 status = SecTrustCreateWithCertificates(cert_array, trust_policies, | 759 status = SecTrustCreateWithCertificates(cert_array, trust_policies, |
767 &trust_ref); | 760 &trust_ref); |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1336 if (chain_count > 1) { | 1329 if (chain_count > 1) { |
1337 CFArrayAppendArray(chain, | 1330 CFArrayAppendArray(chain, |
1338 cert_chain, | 1331 cert_chain, |
1339 CFRangeMake(1, chain_count - 1)); | 1332 CFRangeMake(1, chain_count - 1)); |
1340 } | 1333 } |
1341 } | 1334 } |
1342 | 1335 |
1343 return chain.release(); | 1336 return chain.release(); |
1344 } | 1337 } |
1345 | 1338 |
| 1339 CFArrayRef X509Certificate::CreateOSCertChainForCert() const { |
| 1340 CFMutableArrayRef cert_list = |
| 1341 CFArrayCreateMutable(kCFAllocatorDefault, 0, |
| 1342 &kCFTypeArrayCallBacks); |
| 1343 if (!cert_list) |
| 1344 return NULL; |
| 1345 |
| 1346 CFArrayAppendValue(cert_list, os_cert_handle()); |
| 1347 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) |
| 1348 CFArrayAppendValue(cert_list, intermediate_ca_certs_[i]); |
| 1349 |
| 1350 return cert_list; |
| 1351 } |
| 1352 |
1346 // static | 1353 // static |
1347 X509Certificate::OSCertHandle | 1354 X509Certificate::OSCertHandle |
1348 X509Certificate::ReadOSCertHandleFromPickle(const Pickle& pickle, | 1355 X509Certificate::ReadOSCertHandleFromPickle(const Pickle& pickle, |
1349 void** pickle_iter) { | 1356 void** pickle_iter) { |
1350 const char* data; | 1357 const char* data; |
1351 int length; | 1358 int length; |
1352 if (!pickle.ReadData(pickle_iter, &data, &length)) | 1359 if (!pickle.ReadData(pickle_iter, &data, &length)) |
1353 return NULL; | 1360 return NULL; |
1354 | 1361 |
1355 return CreateOSCertHandleFromBytes(data, length); | 1362 return CreateOSCertHandleFromBytes(data, length); |
1356 } | 1363 } |
1357 | 1364 |
1358 // static | 1365 // static |
1359 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, | 1366 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, |
1360 Pickle* pickle) { | 1367 Pickle* pickle) { |
1361 CSSM_DATA cert_data; | 1368 CSSM_DATA cert_data; |
1362 OSStatus status = SecCertificateGetData(cert_handle, &cert_data); | 1369 OSStatus status = SecCertificateGetData(cert_handle, &cert_data); |
1363 if (status) | 1370 if (status) |
1364 return false; | 1371 return false; |
1365 | 1372 |
1366 return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), | 1373 return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), |
1367 cert_data.Length); | 1374 cert_data.Length); |
1368 } | 1375 } |
1369 | 1376 |
1370 } // namespace net | 1377 } // namespace net |
OLD | NEW |