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 |