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

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

Issue 2753143002: move X509Certificate::SupportsSSLClientAuth to client_cert_store_mac.cc (Closed)
Patch Set: . Created 3 years, 9 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 | « net/cert/x509_certificate_ios.cc ('k') | net/ssl/client_cert_store_mac.cc » ('j') | 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) 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 10
(...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 // Returns true if |purpose| is listed as allowed in |usage|. This
117 // function also considers the "Any" purpose. If the attribute is
118 // present and empty, we return false.
119 bool ExtendedKeyUsageAllows(const CE_ExtendedKeyUsage* usage,
120 const CSSM_OID* purpose) {
121 for (unsigned p = 0; p < usage->numPurposes; ++p) {
122 if (CSSMOIDEqual(&usage->purposes[p], purpose))
123 return true;
124 if (CSSMOIDEqual(&usage->purposes[p], &CSSMOID_ExtendedKeyUsageAny))
125 return true;
126 }
127 return false;
128 }
129
130 // Test that a given |cert_handle| is actually a valid X.509 certificate, and 116 // Test that a given |cert_handle| is actually a valid X.509 certificate, and
131 // return true if it is. 117 // return true if it is.
132 // 118 //
133 // On OS X, SecCertificateCreateFromData() does not return any errors if 119 // On OS X, SecCertificateCreateFromData() does not return any errors if
134 // called with invalid data, as long as data is present. The actual decoding 120 // called with invalid data, as long as data is present. The actual decoding
135 // of the certificate does not happen until an API that requires a CSSM 121 // of the certificate does not happen until an API that requires a CSSM
136 // handle is called. While SecCertificateGetCLHandle is the most likely 122 // handle is called. While SecCertificateGetCLHandle is the most likely
137 // candidate, as it performs the parsing, it does not check whether the 123 // candidate, as it performs the parsing, it does not check whether the
138 // parsing was actually successful. Instead, SecCertificateGetSubject is 124 // parsing was actually successful. Instead, SecCertificateGetSubject is
139 // used (supported since 10.3), as a means to check that the certificate 125 // used (supported since 10.3), as a means to check that the certificate
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 OSStatus status = SecCertificateGetData(intermediates[i], &cert_data); 377 OSStatus status = SecCertificateGetData(intermediates[i], &cert_data);
392 if (status) 378 if (status)
393 return sha256; 379 return sha256;
394 CC_SHA256_Update(&sha256_ctx, cert_data.Data, cert_data.Length); 380 CC_SHA256_Update(&sha256_ctx, cert_data.Data, cert_data.Length);
395 } 381 }
396 CC_SHA256_Final(sha256.data, &sha256_ctx); 382 CC_SHA256_Final(sha256.data, &sha256_ctx);
397 383
398 return sha256; 384 return sha256;
399 } 385 }
400 386
401 bool X509Certificate::SupportsSSLClientAuth() const {
402 x509_util::CSSMCachedCertificate cached_cert;
403 OSStatus status = cached_cert.Init(cert_handle_);
404 if (status)
405 return false;
406
407 // RFC5280 says to take the intersection of the two extensions.
408 //
409 // Our underlying crypto libraries don't expose
410 // ClientCertificateType, so for now we will not support fixed
411 // Diffie-Hellman mechanisms. For rsa_sign, we need the
412 // digitalSignature bit.
413 //
414 // In particular, if a key has the nonRepudiation bit and not the
415 // digitalSignature one, we will not offer it to the user.
416 x509_util::CSSMFieldValue key_usage;
417 status = cached_cert.GetField(&CSSMOID_KeyUsage, &key_usage);
418 if (status == CSSM_OK && key_usage.field()) {
419 const CSSM_X509_EXTENSION* ext = key_usage.GetAs<CSSM_X509_EXTENSION>();
420 const CE_KeyUsage* key_usage_value =
421 reinterpret_cast<const CE_KeyUsage*>(ext->value.parsedValue);
422 if (!((*key_usage_value) & CE_KU_DigitalSignature))
423 return false;
424 }
425
426 status = cached_cert.GetField(&CSSMOID_ExtendedKeyUsage, &key_usage);
427 if (status == CSSM_OK && key_usage.field()) {
428 const CSSM_X509_EXTENSION* ext = key_usage.GetAs<CSSM_X509_EXTENSION>();
429 const CE_ExtendedKeyUsage* ext_key_usage =
430 reinterpret_cast<const CE_ExtendedKeyUsage*>(ext->value.parsedValue);
431 if (!ExtendedKeyUsageAllows(ext_key_usage, &CSSMOID_ClientAuth))
432 return false;
433 }
434 return true;
435 }
436
437 CFMutableArrayRef X509Certificate::CreateOSCertChainForCert() const { 387 CFMutableArrayRef X509Certificate::CreateOSCertChainForCert() const {
438 CFMutableArrayRef cert_list = 388 CFMutableArrayRef cert_list =
439 CFArrayCreateMutable(kCFAllocatorDefault, 0, 389 CFArrayCreateMutable(kCFAllocatorDefault, 0,
440 &kCFTypeArrayCallBacks); 390 &kCFTypeArrayCallBacks);
441 if (!cert_list) 391 if (!cert_list)
442 return NULL; 392 return NULL;
443 393
444 CFArrayAppendValue(cert_list, os_cert_handle()); 394 CFArrayAppendValue(cert_list, os_cert_handle());
445 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) 395 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i)
446 CFArrayAppendValue(cert_list, intermediate_ca_certs_[i]); 396 CFArrayAppendValue(cert_list, intermediate_ca_certs_[i]);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 return false; 501 return false;
552 502
553 if (CSSM_CL_CertVerify(cl_handle, 0, &cert_data, &cert_data, NULL, 0)) 503 if (CSSM_CL_CertVerify(cl_handle, 0, &cert_data, &cert_data, NULL, 0))
554 return false; 504 return false;
555 return true; 505 return true;
556 } 506 }
557 507
558 #pragma clang diagnostic pop // "-Wdeprecated-declarations" 508 #pragma clang diagnostic pop // "-Wdeprecated-declarations"
559 509
560 } // namespace net 510 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/x509_certificate_ios.cc ('k') | net/ssl/client_cert_store_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698