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 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
283 status = X509Certificate::CreateRevocationPolicies( | 283 status = X509Certificate::CreateRevocationPolicies( |
284 (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED), | 284 (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED), |
285 local_policies); | 285 local_policies); |
286 if (status) | 286 if (status) |
287 return status; | 287 return status; |
288 | 288 |
289 policies->reset(local_policies.release()); | 289 policies->reset(local_policies.release()); |
290 return noErr; | 290 return noErr; |
291 } | 291 } |
292 | 292 |
293 // Saves some information about the certificate chain |cert_chain| in | |
294 // |*verify_result|. The caller MUST initialize |*verify_result| before | |
295 // calling this function. | |
296 void GetCertChainInfo(CFArrayRef cert_chain, | |
297 CertVerifyResult* verify_result) { | |
298 SecCertificateRef verified_cert = NULL; | |
299 std::vector<SecCertificateRef> verified_chain; | |
300 for (CFIndex i = 0, count = CFArrayGetCount(cert_chain); | |
301 i < count; ++i) { | |
wtc
2011/10/25 18:24:44
Does this not fit on the previous line?
| |
302 SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>( | |
303 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); | |
304 if (i == 0) { | |
305 verified_cert = chain_cert; | |
306 } else { | |
307 verified_chain.push_back(chain_cert); | |
308 } | |
309 | |
310 CSSMFields fields; | |
311 OSStatus status = GetCertFields(chain_cert, &fields); | |
312 if (status) | |
313 continue; | |
314 for (size_t field = 0; field < fields.num_of_fields; ++field) { | |
315 if (!CSSMOIDEqual(&fields.fields[field].FieldOid, | |
palmer
2011/10/25 19:53:50
"fields fields field field oid" is baffling. Are t
| |
316 &CSSMOID_X509V1SignatureAlgorithm)) { | |
317 continue; | |
318 } | |
319 | |
320 CSSM_X509_ALGORITHM_IDENTIFIER* signature_algorithm = | |
321 reinterpret_cast<CSSM_X509_ALGORITHM_IDENTIFIER*>( | |
322 fields.fields[field].FieldValue.Data); | |
323 if (!signature_algorithm || (fields.fields[field].FieldValue.Length != | |
324 sizeof(CSSM_X509_ALGORITHM_IDENTIFIER))) { | |
325 break; | |
wtc
2011/10/25 18:24:44
If we get here, it means the Mac OS X certificate
| |
326 } | |
327 CSSM_OID_PTR alg_oid = &signature_algorithm->algorithm; | |
328 if (CSSMOIDEqual(alg_oid, &CSSMOID_MD2WithRSA)) { | |
329 verify_result->has_md2 = true; | |
330 if (i != 0) | |
331 verify_result->has_md2_ca = true; | |
332 } else if (CSSMOIDEqual(alg_oid, &CSSMOID_MD4WithRSA)) { | |
333 verify_result->has_md4 = true; | |
334 } else if (CSSMOIDEqual(alg_oid, &CSSMOID_MD5WithRSA)) { | |
palmer
2011/10/25 19:53:50
As in the other CL, we should keep track of MD4 CA
| |
335 verify_result->has_md5 = true; | |
336 if (i != 0) | |
337 verify_result->has_md5_ca = true; | |
338 } | |
339 break; | |
340 } | |
341 } | |
342 if (!verified_cert) | |
343 return; | |
344 | |
345 verify_result->verified_cert = | |
346 X509Certificate::CreateFromHandle(verified_cert, verified_chain); | |
347 } | |
348 | |
293 // Gets the issuer for a given cert, starting with the cert itself and | 349 // Gets the issuer for a given cert, starting with the cert itself and |
294 // including the intermediate and finally root certificates (if any). | 350 // including the intermediate and finally root certificates (if any). |
295 // This function calls SecTrust but doesn't actually pay attention to the trust | 351 // This function calls SecTrust but doesn't actually pay attention to the trust |
296 // result: it shouldn't be used to determine trust, just to traverse the chain. | 352 // result: it shouldn't be used to determine trust, just to traverse the chain. |
297 // Caller is responsible for releasing the value stored into *out_cert_chain. | 353 // Caller is responsible for releasing the value stored into *out_cert_chain. |
298 OSStatus CopyCertChain(SecCertificateRef cert_handle, | 354 OSStatus CopyCertChain(SecCertificateRef cert_handle, |
299 CFArrayRef* out_cert_chain) { | 355 CFArrayRef* out_cert_chain) { |
300 DCHECK(cert_handle); | 356 DCHECK(cert_handle); |
301 DCHECK(out_cert_chain); | 357 DCHECK(out_cert_chain); |
302 // Create an SSL policy ref configured for client cert evaluation. | 358 // Create an SSL policy ref configured for client cert evaluation. |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
832 if (status) | 888 if (status) |
833 return NetErrorFromOSStatus(status); | 889 return NetErrorFromOSStatus(status); |
834 CFArrayRef completed_chain = NULL; | 890 CFArrayRef completed_chain = NULL; |
835 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info; | 891 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info; |
836 status = SecTrustGetResult(trust_ref, &trust_result, &completed_chain, | 892 status = SecTrustGetResult(trust_ref, &trust_result, &completed_chain, |
837 &chain_info); | 893 &chain_info); |
838 if (status) | 894 if (status) |
839 return NetErrorFromOSStatus(status); | 895 return NetErrorFromOSStatus(status); |
840 ScopedCFTypeRef<CFArrayRef> scoped_completed_chain(completed_chain); | 896 ScopedCFTypeRef<CFArrayRef> scoped_completed_chain(completed_chain); |
841 | 897 |
842 SecCertificateRef verified_cert = NULL; | 898 GetCertChainInfo(scoped_completed_chain.get(), verify_result); |
843 std::vector<SecCertificateRef> verified_chain; | |
844 for (CFIndex i = 0, count = CFArrayGetCount(completed_chain); | |
845 i < count; ++i) { | |
846 SecCertificateRef chain_cert = reinterpret_cast<SecCertificateRef>( | |
847 const_cast<void*>(CFArrayGetValueAtIndex(completed_chain, i))); | |
848 if (i == 0) { | |
849 verified_cert = chain_cert; | |
850 } else { | |
851 verified_chain.push_back(chain_cert); | |
852 } | |
853 } | |
854 if (verified_cert) { | |
855 verify_result->verified_cert = CreateFromHandle(verified_cert, | |
856 verified_chain); | |
857 } | |
858 | 899 |
859 // Evaluate the results | 900 // Evaluate the results |
860 OSStatus cssm_result; | 901 OSStatus cssm_result; |
861 switch (trust_result) { | 902 switch (trust_result) { |
862 case kSecTrustResultUnspecified: | 903 case kSecTrustResultUnspecified: |
863 case kSecTrustResultProceed: | 904 case kSecTrustResultProceed: |
864 // Certificate chain is valid and trusted ("unspecified" indicates that | 905 // Certificate chain is valid and trusted ("unspecified" indicates that |
865 // the user has not explicitly set a trust setting) | 906 // the user has not explicitly set a trust setting) |
866 break; | 907 break; |
867 | 908 |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1339 CSSM_DATA cert_data; | 1380 CSSM_DATA cert_data; |
1340 OSStatus status = SecCertificateGetData(cert_handle, &cert_data); | 1381 OSStatus status = SecCertificateGetData(cert_handle, &cert_data); |
1341 if (status) | 1382 if (status) |
1342 return false; | 1383 return false; |
1343 | 1384 |
1344 return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), | 1385 return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), |
1345 cert_data.Length); | 1386 cert_data.Length); |
1346 } | 1387 } |
1347 | 1388 |
1348 } // namespace net | 1389 } // namespace net |
OLD | NEW |