| 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 #include "net/cert/x509_certificate.h" | 5 #include "net/cert/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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 OSStatus status = cached_cert.GetField(&CSSMOID_X509V1SerialNumber, | 106 OSStatus status = cached_cert.GetField(&CSSMOID_X509V1SerialNumber, |
| 107 &serial_number); | 107 &serial_number); |
| 108 if (status || !serial_number.field()) | 108 if (status || !serial_number.field()) |
| 109 return std::string(); | 109 return std::string(); |
| 110 | 110 |
| 111 return std::string( | 111 return std::string( |
| 112 reinterpret_cast<const char*>(serial_number.field()->Data), | 112 reinterpret_cast<const char*>(serial_number.field()->Data), |
| 113 serial_number.field()->Length); | 113 serial_number.field()->Length); |
| 114 } | 114 } |
| 115 | 115 |
| 116 // Gets the issuer for a given cert, starting with the cert itself and | |
| 117 // including the intermediate and finally root certificates (if any). | |
| 118 // This function calls SecTrust but doesn't actually pay attention to the trust | |
| 119 // result: it shouldn't be used to determine trust, just to traverse the chain. | |
| 120 // Caller is responsible for releasing the value stored into *out_cert_chain. | |
| 121 OSStatus CopyCertChain(SecCertificateRef cert_handle, | |
| 122 CFArrayRef* out_cert_chain) { | |
| 123 DCHECK(cert_handle); | |
| 124 DCHECK(out_cert_chain); | |
| 125 | |
| 126 // Create an SSL policy ref configured for client cert evaluation. | |
| 127 SecPolicyRef ssl_policy; | |
| 128 OSStatus result = x509_util::CreateSSLClientPolicy(&ssl_policy); | |
| 129 if (result) | |
| 130 return result; | |
| 131 ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy); | |
| 132 | |
| 133 // Create a SecTrustRef. | |
| 134 ScopedCFTypeRef<CFArrayRef> input_certs(CFArrayCreate( | |
| 135 NULL, const_cast<const void**>(reinterpret_cast<void**>(&cert_handle)), | |
| 136 1, &kCFTypeArrayCallBacks)); | |
| 137 SecTrustRef trust_ref = NULL; | |
| 138 { | |
| 139 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); | |
| 140 result = SecTrustCreateWithCertificates(input_certs, ssl_policy, | |
| 141 &trust_ref); | |
| 142 } | |
| 143 if (result) | |
| 144 return result; | |
| 145 ScopedCFTypeRef<SecTrustRef> trust(trust_ref); | |
| 146 | |
| 147 // Evaluate trust, which creates the cert chain. | |
| 148 SecTrustResultType status; | |
| 149 CSSM_TP_APPLE_EVIDENCE_INFO* status_chain; | |
| 150 { | |
| 151 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); | |
| 152 result = SecTrustEvaluate(trust, &status); | |
| 153 } | |
| 154 if (result) | |
| 155 return result; | |
| 156 { | |
| 157 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); | |
| 158 result = SecTrustGetResult(trust, &status, out_cert_chain, &status_chain); | |
| 159 } | |
| 160 return result; | |
| 161 } | |
| 162 | |
| 163 // Returns true if |purpose| is listed as allowed in |usage|. This | 116 // Returns true if |purpose| is listed as allowed in |usage|. This |
| 164 // function also considers the "Any" purpose. If the attribute is | 117 // function also considers the "Any" purpose. If the attribute is |
| 165 // present and empty, we return false. | 118 // present and empty, we return false. |
| 166 bool ExtendedKeyUsageAllows(const CE_ExtendedKeyUsage* usage, | 119 bool ExtendedKeyUsageAllows(const CE_ExtendedKeyUsage* usage, |
| 167 const CSSM_OID* purpose) { | 120 const CSSM_OID* purpose) { |
| 168 for (unsigned p = 0; p < usage->numPurposes; ++p) { | 121 for (unsigned p = 0; p < usage->numPurposes; ++p) { |
| 169 if (CSSMOIDEqual(&usage->purposes[p], purpose)) | 122 if (CSSMOIDEqual(&usage->purposes[p], purpose)) |
| 170 return true; | 123 return true; |
| 171 if (CSSMOIDEqual(&usage->purposes[p], &CSSMOID_ExtendedKeyUsageAny)) | 124 if (CSSMOIDEqual(&usage->purposes[p], &CSSMOID_ExtendedKeyUsageAny)) |
| 172 return true; | 125 return true; |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 if (status == CSSM_OK && key_usage.field()) { | 658 if (status == CSSM_OK && key_usage.field()) { |
| 706 const CSSM_X509_EXTENSION* ext = key_usage.GetAs<CSSM_X509_EXTENSION>(); | 659 const CSSM_X509_EXTENSION* ext = key_usage.GetAs<CSSM_X509_EXTENSION>(); |
| 707 const CE_ExtendedKeyUsage* ext_key_usage = | 660 const CE_ExtendedKeyUsage* ext_key_usage = |
| 708 reinterpret_cast<const CE_ExtendedKeyUsage*>(ext->value.parsedValue); | 661 reinterpret_cast<const CE_ExtendedKeyUsage*>(ext->value.parsedValue); |
| 709 if (!ExtendedKeyUsageAllows(ext_key_usage, &CSSMOID_ClientAuth)) | 662 if (!ExtendedKeyUsageAllows(ext_key_usage, &CSSMOID_ClientAuth)) |
| 710 return false; | 663 return false; |
| 711 } | 664 } |
| 712 return true; | 665 return true; |
| 713 } | 666 } |
| 714 | 667 |
| 715 CFArrayRef X509Certificate::CreateClientCertificateChain() const { | |
| 716 // Initialize the result array with just the IdentityRef of the receiver: | |
| 717 SecIdentityRef identity; | |
| 718 OSStatus result; | |
| 719 { | |
| 720 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); | |
| 721 result = SecIdentityCreateWithCertificate(NULL, cert_handle_, &identity); | |
| 722 } | |
| 723 if (result) { | |
| 724 OSSTATUS_LOG(ERROR, result) << "SecIdentityCreateWithCertificate error"; | |
| 725 return NULL; | |
| 726 } | |
| 727 ScopedCFTypeRef<CFMutableArrayRef> chain( | |
| 728 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)); | |
| 729 CFArrayAppendValue(chain, identity); | |
| 730 | |
| 731 CFArrayRef cert_chain = NULL; | |
| 732 result = CopyCertChain(cert_handle_, &cert_chain); | |
| 733 ScopedCFTypeRef<CFArrayRef> scoped_cert_chain(cert_chain); | |
| 734 if (result) { | |
| 735 OSSTATUS_LOG(ERROR, result) << "CreateIdentityCertificateChain error"; | |
| 736 return chain.release(); | |
| 737 } | |
| 738 | |
| 739 // Append the intermediate certs from SecTrust to the result array: | |
| 740 if (cert_chain) { | |
| 741 int chain_count = CFArrayGetCount(cert_chain); | |
| 742 if (chain_count > 1) { | |
| 743 CFArrayAppendArray(chain, | |
| 744 cert_chain, | |
| 745 CFRangeMake(1, chain_count - 1)); | |
| 746 } | |
| 747 } | |
| 748 | |
| 749 return chain.release(); | |
| 750 } | |
| 751 | |
| 752 CFArrayRef X509Certificate::CreateOSCertChainForCert() const { | 668 CFArrayRef X509Certificate::CreateOSCertChainForCert() const { |
| 753 CFMutableArrayRef cert_list = | 669 CFMutableArrayRef cert_list = |
| 754 CFArrayCreateMutable(kCFAllocatorDefault, 0, | 670 CFArrayCreateMutable(kCFAllocatorDefault, 0, |
| 755 &kCFTypeArrayCallBacks); | 671 &kCFTypeArrayCallBacks); |
| 756 if (!cert_list) | 672 if (!cert_list) |
| 757 return NULL; | 673 return NULL; |
| 758 | 674 |
| 759 CFArrayAppendValue(cert_list, os_cert_handle()); | 675 CFArrayAppendValue(cert_list, os_cert_handle()); |
| 760 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) | 676 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) |
| 761 CFArrayAppendValue(cert_list, intermediate_ca_certs_[i]); | 677 CFArrayAppendValue(cert_list, intermediate_ca_certs_[i]); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 *type = kPublicKeyTypeDH; | 741 *type = kPublicKeyTypeDH; |
| 826 break; | 742 break; |
| 827 default: | 743 default: |
| 828 *type = kPublicKeyTypeUnknown; | 744 *type = kPublicKeyTypeUnknown; |
| 829 *size_bits = 0; | 745 *size_bits = 0; |
| 830 break; | 746 break; |
| 831 } | 747 } |
| 832 } | 748 } |
| 833 | 749 |
| 834 } // namespace net | 750 } // namespace net |
| OLD | NEW |