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

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

Issue 2819018: Add support for parsing certificate formats other than raw, DER-encoded cert... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Fixup some variables/comments per wtc 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 | Annotate | Revision Log
« no previous file with comments | « net/base/x509_certificate.cc ('k') | net/base/x509_certificate_nss.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) 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
11 #include "base/scoped_cftyperef.h"
12 #include "base/logging.h" 11 #include "base/logging.h"
13 #include "base/pickle.h" 12 #include "base/pickle.h"
13 #include "base/scoped_cftyperef.h"
14 #include "base/sys_string_conversions.h" 14 #include "base/sys_string_conversions.h"
15 #include "net/base/cert_status_flags.h" 15 #include "net/base/cert_status_flags.h"
16 #include "net/base/cert_verify_result.h" 16 #include "net/base/cert_verify_result.h"
17 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
18 18
19 using base::Time; 19 using base::Time;
20 20
21 namespace net { 21 namespace net {
22 22
23 class MacTrustedCertificates { 23 class MacTrustedCertificates {
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 const CSSM_OID* purpose) { 365 const CSSM_OID* purpose) {
366 for (unsigned p = 0; p < usage->numPurposes; ++p) { 366 for (unsigned p = 0; p < usage->numPurposes; ++p) {
367 if (CSSMOIDEqual(&usage->purposes[p], purpose)) 367 if (CSSMOIDEqual(&usage->purposes[p], purpose))
368 return true; 368 return true;
369 if (CSSMOIDEqual(&usage->purposes[p], &CSSMOID_ExtendedKeyUsageAny)) 369 if (CSSMOIDEqual(&usage->purposes[p], &CSSMOID_ExtendedKeyUsageAny))
370 return true; 370 return true;
371 } 371 }
372 return false; 372 return false;
373 } 373 }
374 374
375 // Parses |data| of length |length|, attempting to decode it as the specified
376 // |format|. If |data| is in the specified format, any certificates contained
377 // within are stored into |output|.
378 void AddCertificatesFromBytes(const char* data, size_t length,
379 SecExternalFormat format,
380 X509Certificate::OSCertHandles* output) {
381 SecExternalFormat input_format = format;
382 scoped_cftyperef<CFDataRef> local_data(CFDataCreateWithBytesNoCopy(
383 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data),
384 length, kCFAllocatorNull));
385
386 CFArrayRef items = NULL;
387 OSStatus status = SecKeychainItemImport(local_data, NULL, &input_format,
388 NULL, 0, NULL, NULL, &items);
389 if (status) {
390 DLOG(WARNING) << status << " Unable to import items from data of length "
391 << length;
392 return;
393 }
394
395 scoped_cftyperef<CFArrayRef> scoped_items(items);
396 CFTypeID cert_type_id = SecCertificateGetTypeID();
397
398 for (CFIndex i = 0; i < CFArrayGetCount(items); ++i) {
399 SecKeychainItemRef item = reinterpret_cast<SecKeychainItemRef>(
400 const_cast<void*>(CFArrayGetValueAtIndex(items, i)));
401
402 // While inputFormat implies only certificates will be imported, if/when
403 // other formats (eg: PKCS#12) are supported, this may also include
404 // private keys or other items types, so filter appropriately.
405 if (CFGetTypeID(item) == cert_type_id) {
406 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(item);
407 CFRetain(cert);
408 output->push_back(cert);
409 }
410 }
411 }
412
375 } // namespace 413 } // namespace
376 414
377 void X509Certificate::Initialize() { 415 void X509Certificate::Initialize() {
378 const CSSM_X509_NAME* name; 416 const CSSM_X509_NAME* name;
379 OSStatus status = SecCertificateGetSubject(cert_handle_, &name); 417 OSStatus status = SecCertificateGetSubject(cert_handle_, &name);
380 if (!status) { 418 if (!status) {
381 subject_.Parse(name); 419 subject_.Parse(name);
382 } 420 }
383 status = SecCertificateGetIssuer(cert_handle_, &name); 421 status = SecCertificateGetIssuer(cert_handle_, &name);
384 if (!status) { 422 if (!status) {
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 // static 700 // static
663 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( 701 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
664 const char* data, int length) { 702 const char* data, int length) {
665 CSSM_DATA cert_data; 703 CSSM_DATA cert_data;
666 cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data)); 704 cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data));
667 cert_data.Length = length; 705 cert_data.Length = length;
668 706
669 OSCertHandle cert_handle = NULL; 707 OSCertHandle cert_handle = NULL;
670 OSStatus status = SecCertificateCreateFromData(&cert_data, 708 OSStatus status = SecCertificateCreateFromData(&cert_data,
671 CSSM_CERT_X_509v3, 709 CSSM_CERT_X_509v3,
672 CSSM_CERT_ENCODING_BER, 710 CSSM_CERT_ENCODING_DER,
673 &cert_handle); 711 &cert_handle);
674 if (status) 712 if (status)
675 return NULL; 713 return NULL;
676 714
715 // SecCertificateCreateFromData() unfortunately will not return any
716 // errors, as long as simply all pointers are present. The actual decoding
717 // of the certificate does not happen until an API that requires a CDSA
718 // handle is called. While SecCertificateGetCLHandle is the most likely
719 // candidate, as it initializes the parsing, it does not check whether the
720 // parsing was successful. Instead, SecCertificateGetSubject is used
721 // (supported since 10.3), as a means to double-check that the parsed
722 // certificate is valid.
723 const CSSM_X509_NAME* sanity_check = NULL;
724 status = SecCertificateGetSubject(cert_handle, &sanity_check);
725 if (status || !sanity_check) {
726 CFRelease(cert_handle);
727 return NULL;
728 }
729
677 return cert_handle; 730 return cert_handle;
678 } 731 }
679 732
680 // static 733 // static
734 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
735 const char* data, int length, Format format) {
736 OSCertHandles results;
737
738 switch (format) {
739 case FORMAT_SINGLE_CERTIFICATE: {
740 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length);
741 if (handle)
742 results.push_back(handle);
743 break;
744 }
745 case FORMAT_PKCS7:
746 AddCertificatesFromBytes(data, length, kSecFormatPKCS7, &results);
747 break;
748 default:
749 NOTREACHED() << "Certificate format " << format << " unimplemented";
750 break;
751 }
752
753 return results;
754 }
755
756 // static
681 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( 757 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
682 OSCertHandle handle) { 758 OSCertHandle handle) {
683 if (!handle) 759 if (!handle)
684 return NULL; 760 return NULL;
685 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle))); 761 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle)));
686 } 762 }
687 763
688 // static 764 // static
689 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { 765 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
690 CFRelease(cert_handle); 766 CFRelease(cert_handle);
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 } 969 }
894 CFRelease(cert_chain); 970 CFRelease(cert_chain);
895 } 971 }
896 exit: 972 exit:
897 if (result) 973 if (result)
898 LOG(ERROR) << "CreateIdentityCertificateChain error " << result; 974 LOG(ERROR) << "CreateIdentityCertificateChain error " << result;
899 return chain.release(); 975 return chain.release();
900 } 976 }
901 977
902 } // namespace net 978 } // namespace net
OLDNEW
« no previous file with comments | « net/base/x509_certificate.cc ('k') | net/base/x509_certificate_nss.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698