Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: net/cert/x509_certificate_mac.cc

Issue 13866049: Fix client certificate authentication on Mac and Linux introduced in r178732 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698