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

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

Issue 2899005: Rewrite X509Certificate::SupportsSSLClientAuth to be more accurate (Closed)
Patch Set: Rearrange a few comments Created 10 years, 5 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 351
352 // Evaluate trust, which creates the cert chain. 352 // Evaluate trust, which creates the cert chain.
353 SecTrustResultType status; 353 SecTrustResultType status;
354 CSSM_TP_APPLE_EVIDENCE_INFO* status_chain; 354 CSSM_TP_APPLE_EVIDENCE_INFO* status_chain;
355 result = SecTrustEvaluate(trust, &status); 355 result = SecTrustEvaluate(trust, &status);
356 if (result) 356 if (result)
357 return result; 357 return result;
358 return SecTrustGetResult(trust, &status, out_cert_chain, &status_chain); 358 return SecTrustGetResult(trust, &status, out_cert_chain, &status_chain);
359 } 359 }
360 360
361 // Returns true if |purpose| is listed as allowed in |usage|. This
362 // function also considers the "Any" purpose. If the attribute is
363 // present and empty, we return false.
364 bool ExtendedKeyUsageAllows(const CE_ExtendedKeyUsage* usage,
365 const CSSM_OID* purpose) {
366 for (unsigned p = 0; p < usage->numPurposes; ++p) {
367 if (CSSMOIDEqual(&usage->purposes[p], purpose))
368 return true;
369 if (CSSMOIDEqual(&usage->purposes[p], &CSSMOID_ExtendedKeyUsageAny))
370 return true;
371 }
372 return false;
373 }
374
361 } // namespace 375 } // namespace
362 376
363 void X509Certificate::Initialize() { 377 void X509Certificate::Initialize() {
364 const CSSM_X509_NAME* name; 378 const CSSM_X509_NAME* name;
365 OSStatus status = SecCertificateGetSubject(cert_handle_, &name); 379 OSStatus status = SecCertificateGetSubject(cert_handle_, &name);
366 if (!status) { 380 if (!status) {
367 subject_.Parse(name); 381 subject_.Parse(name);
368 } 382 }
369 status = SecCertificateGetIssuer(cert_handle_, &name); 383 status = SecCertificateGetIssuer(cert_handle_, &name);
370 if (!status) { 384 if (!status) {
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 706
693 CC_SHA1(cert_data.Data, cert_data.Length, sha1.data); 707 CC_SHA1(cert_data.Data, cert_data.Length, sha1.data);
694 708
695 return sha1; 709 return sha1;
696 } 710 }
697 711
698 bool X509Certificate::SupportsSSLClientAuth() const { 712 bool X509Certificate::SupportsSSLClientAuth() const {
699 CSSMFields fields; 713 CSSMFields fields;
700 if (GetCertFields(cert_handle_, &fields) != noErr) 714 if (GetCertFields(cert_handle_, &fields) != noErr)
701 return false; 715 return false;
716
717 // Gather the extensions we care about. We do not support
718 // CSSMOID_NetscapeCertType on OS X.
719 const CE_ExtendedKeyUsage* ext_key_usage = NULL;
720 const CE_KeyUsage* key_usage = NULL;
702 for (unsigned f = 0; f < fields.num_of_fields; ++f) { 721 for (unsigned f = 0; f < fields.num_of_fields; ++f) {
703 const CSSM_FIELD& field = fields.fields[f]; 722 const CSSM_FIELD& field = fields.fields[f];
704 const CSSM_X509_EXTENSION* ext = 723 const CSSM_X509_EXTENSION* ext =
705 reinterpret_cast<const CSSM_X509_EXTENSION*>(field.FieldValue.Data); 724 reinterpret_cast<const CSSM_X509_EXTENSION*>(field.FieldValue.Data);
706 if (CSSMOIDEqual(&field.FieldOid, &CSSMOID_ExtendedKeyUsage)) { 725 if (CSSMOIDEqual(&field.FieldOid, &CSSMOID_KeyUsage)) {
707 const CE_ExtendedKeyUsage* usage = 726 key_usage = reinterpret_cast<const CE_KeyUsage*>(ext->value.parsedValue);
727 } else if (CSSMOIDEqual(&field.FieldOid, &CSSMOID_ExtendedKeyUsage)) {
728 ext_key_usage =
708 reinterpret_cast<const CE_ExtendedKeyUsage*>(ext->value.parsedValue); 729 reinterpret_cast<const CE_ExtendedKeyUsage*>(ext->value.parsedValue);
709 for (unsigned p = 0; p < usage->numPurposes; ++p) {
710 if (CSSMOIDEqual(&usage->purposes[p], &CSSMOID_ClientAuth))
711 return true;
712 }
713 } else if (CSSMOIDEqual(&field.FieldOid, &CSSMOID_NetscapeCertType)) {
714 uint16_t flags =
715 *reinterpret_cast<const uint16_t*>(ext->value.parsedValue);
716 if (flags & CE_NCT_SSL_Client)
717 return true;
718 } 730 }
719 } 731 }
720 return false; 732
733 // RFC5280 says to take the intersection of the two extensions.
734 //
735 // Our underlying crypto libraries don't expose
736 // ClientCertificateType, so for now we will not support fixed
737 // Diffie-Hellman mechanisms. For rsa_sign, we need the
738 // digitalSignature bit.
739 //
740 // In particular, if a key has the nonRepudiation bit and not the
741 // digitalSignature one, we will not offer it to the user.
742 if (key_usage && !((*key_usage) & CE_KU_DigitalSignature))
743 return false;
744 if (ext_key_usage && !ExtendedKeyUsageAllows(ext_key_usage,
745 &CSSMOID_ClientAuth))
746 return false;
747 return true;
721 } 748 }
722 749
723 bool X509Certificate::IsIssuedBy( 750 bool X509Certificate::IsIssuedBy(
724 const std::vector<CertPrincipal>& valid_issuers) { 751 const std::vector<CertPrincipal>& valid_issuers) {
725 // Get the cert's issuer chain. 752 // Get the cert's issuer chain.
726 CFArrayRef cert_chain = NULL; 753 CFArrayRef cert_chain = NULL;
727 OSStatus result; 754 OSStatus result;
728 result = CopyCertChain(os_cert_handle(), &cert_chain); 755 result = CopyCertChain(os_cert_handle(), &cert_chain);
729 if (result != noErr) 756 if (result != noErr)
730 return false; 757 return false;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 } 894 }
868 CFRelease(cert_chain); 895 CFRelease(cert_chain);
869 } 896 }
870 exit: 897 exit:
871 if (result) 898 if (result)
872 LOG(ERROR) << "CreateIdentityCertificateChain error " << result; 899 LOG(ERROR) << "CreateIdentityCertificateChain error " << result;
873 return chain.release(); 900 return chain.release();
874 } 901 }
875 902
876 } // namespace net 903 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698