Chromium Code Reviews| 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 <Security/Security.h> | 8 #include <Security/Security.h> |
| 9 #include <time.h> | 9 #include <time.h> |
| 10 | 10 |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/crypto/cssm_init.h" | 13 #include "base/crypto/cssm_init.h" |
| 14 #include "base/crypto/rsa_private_key.h" | 14 #include "base/crypto/rsa_private_key.h" |
| 15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/mac/scoped_cftyperef.h" | |
| 17 #include "base/memory/singleton.h" | 18 #include "base/memory/singleton.h" |
| 18 #include "base/nss_util.h" | 19 #include "base/nss_util.h" |
| 19 #include "base/pickle.h" | 20 #include "base/pickle.h" |
| 20 #include "base/mac/scoped_cftyperef.h" | 21 #include "base/sha1.h" |
| 21 #include "base/sys_string_conversions.h" | 22 #include "base/sys_string_conversions.h" |
| 22 #include "net/base/cert_status_flags.h" | 23 #include "net/base/cert_status_flags.h" |
| 23 #include "net/base/cert_verify_result.h" | 24 #include "net/base/cert_verify_result.h" |
| 24 #include "net/base/net_errors.h" | 25 #include "net/base/net_errors.h" |
| 25 #include "net/base/test_root_certs.h" | 26 #include "net/base/test_root_certs.h" |
| 27 #include "net/base/x509_certificate_mac_known_hashes.h" | |
| 26 #include "third_party/nss/mozilla/security/nss/lib/certdb/cert.h" | 28 #include "third_party/nss/mozilla/security/nss/lib/certdb/cert.h" |
| 27 | 29 |
| 28 using base::mac::ScopedCFTypeRef; | 30 using base::mac::ScopedCFTypeRef; |
| 29 using base::Time; | 31 using base::Time; |
| 30 | 32 |
| 31 namespace net { | 33 namespace net { |
| 32 | 34 |
| 33 namespace { | 35 namespace { |
| 34 | 36 |
| 35 typedef OSStatus (*SecTrustCopyExtendedResultFuncPtr)(SecTrustRef, | 37 typedef OSStatus (*SecTrustCopyExtendedResultFuncPtr)(SecTrustRef, |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 507 | 509 |
| 508 GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotBefore, | 510 GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotBefore, |
| 509 &valid_start_); | 511 &valid_start_); |
| 510 GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotAfter, | 512 GetCertDateForOID(cert_handle_, CSSMOID_X509V1ValidityNotAfter, |
| 511 &valid_expiry_); | 513 &valid_expiry_); |
| 512 | 514 |
| 513 fingerprint_ = CalculateFingerprint(cert_handle_); | 515 fingerprint_ = CalculateFingerprint(cert_handle_); |
| 514 serial_number_ = GetCertSerialNumber(cert_handle_); | 516 serial_number_ = GetCertSerialNumber(cert_handle_); |
| 515 } | 517 } |
| 516 | 518 |
| 519 // IsIssuedByKnownRoot returns true if the given chain is rooted at a root CA | |
| 520 // that we recognise as a standard root. | |
| 521 bool X509Certificate::IsIssuedByKnownRoot(CFArrayRef chain) { | |
| 522 int n = CFArrayGetCount(chain); | |
| 523 if (n < 1) | |
| 524 return true; | |
| 525 SecCertificateRef root_ref = reinterpret_cast<SecCertificateRef>( | |
| 526 const_cast<void*>(CFArrayGetValueAtIndex(chain, n - 1))); | |
| 527 SHA1Fingerprint hash = X509Certificate::CalculateFingerprint(root_ref); | |
| 528 return X509Certificate::IsSHA1HashInSortedArray( | |
|
wtc
2011/04/07 05:01:54
Can we omit X509Certificate:: in this method?
agl
2011/04/07 15:02:49
Done.
| |
| 529 hash, &kKnownRootCertSHA1Hashes[0][0], sizeof(kKnownRootCertSHA1Hashes)); | |
| 530 } | |
| 531 | |
| 517 // static | 532 // static |
| 518 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, | 533 X509Certificate* X509Certificate::CreateFromPickle(const Pickle& pickle, |
| 519 void** pickle_iter) { | 534 void** pickle_iter) { |
| 520 const char* data; | 535 const char* data; |
| 521 int length; | 536 int length; |
| 522 if (!pickle.ReadData(pickle_iter, &data, &length)) | 537 if (!pickle.ReadData(pickle_iter, &data, &length)) |
| 523 return NULL; | 538 return NULL; |
| 524 | 539 |
| 525 return CreateFromBytes(data, length); | 540 return CreateFromBytes(data, length); |
| 526 } | 541 } |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 782 if (status) | 797 if (status) |
| 783 return NetErrorFromOSStatus(status); | 798 return NetErrorFromOSStatus(status); |
| 784 CFArrayRef completed_chain = NULL; | 799 CFArrayRef completed_chain = NULL; |
| 785 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info; | 800 CSSM_TP_APPLE_EVIDENCE_INFO* chain_info; |
| 786 status = SecTrustGetResult(trust_ref, &trust_result, &completed_chain, | 801 status = SecTrustGetResult(trust_ref, &trust_result, &completed_chain, |
| 787 &chain_info); | 802 &chain_info); |
| 788 if (status) | 803 if (status) |
| 789 return NetErrorFromOSStatus(status); | 804 return NetErrorFromOSStatus(status); |
| 790 ScopedCFTypeRef<CFArrayRef> scoped_completed_chain(completed_chain); | 805 ScopedCFTypeRef<CFArrayRef> scoped_completed_chain(completed_chain); |
| 791 | 806 |
| 807 verify_result->is_issued_by_known_root = IsIssuedByKnownRoot(completed_chain); | |
| 808 | |
| 792 // Evaluate the results | 809 // Evaluate the results |
| 793 OSStatus cssm_result; | 810 OSStatus cssm_result; |
| 794 bool got_certificate_error = false; | 811 bool got_certificate_error = false; |
| 795 switch (trust_result) { | 812 switch (trust_result) { |
| 796 case kSecTrustResultUnspecified: | 813 case kSecTrustResultUnspecified: |
| 797 case kSecTrustResultProceed: | 814 case kSecTrustResultProceed: |
| 798 // Certificate chain is valid and trusted ("unspecified" indicates that | 815 // Certificate chain is valid and trusted ("unspecified" indicates that |
| 799 // the user has not explicitly set a trust setting) | 816 // the user has not explicitly set a trust setting) |
| 800 break; | 817 break; |
| 801 | 818 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 900 // server certificate, which we don't need at this point (and we | 917 // server certificate, which we don't need at this point (and we |
| 901 // have other ways to access, anyway). All we care is that | 918 // have other ways to access, anyway). All we care is that |
| 902 // SecTrustCopyExtendedResult() returned noErr and a non-NULL | 919 // SecTrustCopyExtendedResult() returned noErr and a non-NULL |
| 903 // dictionary. | 920 // dictionary. |
| 904 CFRelease(ev_dict); | 921 CFRelease(ev_dict); |
| 905 verify_result->cert_status |= CERT_STATUS_IS_EV; | 922 verify_result->cert_status |= CERT_STATUS_IS_EV; |
| 906 } | 923 } |
| 907 } | 924 } |
| 908 } | 925 } |
| 909 } | 926 } |
| 910 | 927 |
|
wtc
2011/04/07 05:01:54
It seems better to set verify_result->is_issued_by
| |
| 911 return OK; | 928 return OK; |
| 912 } | 929 } |
| 913 | 930 |
| 914 bool X509Certificate::GetDEREncoded(std::string* encoded) { | 931 bool X509Certificate::GetDEREncoded(std::string* encoded) { |
| 915 encoded->clear(); | 932 encoded->clear(); |
| 916 CSSM_DATA der_data; | 933 CSSM_DATA der_data; |
| 917 if(SecCertificateGetData(cert_handle_, &der_data) == noErr) { | 934 if(SecCertificateGetData(cert_handle_, &der_data) == noErr) { |
| 918 encoded->append(reinterpret_cast<char*>(der_data.Data), | 935 encoded->append(reinterpret_cast<char*>(der_data.Data), |
| 919 der_data.Length); | 936 der_data.Length); |
| 920 return true; | 937 return true; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1207 CFArrayAppendArray(chain, | 1224 CFArrayAppendArray(chain, |
| 1208 cert_chain, | 1225 cert_chain, |
| 1209 CFRangeMake(1, chain_count - 1)); | 1226 CFRangeMake(1, chain_count - 1)); |
| 1210 } | 1227 } |
| 1211 } | 1228 } |
| 1212 | 1229 |
| 1213 return chain.release(); | 1230 return chain.release(); |
| 1214 } | 1231 } |
| 1215 | 1232 |
| 1216 } // namespace net | 1233 } // namespace net |
| OLD | NEW |