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

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

Issue 2812064: Revert 52799 - Add support for parsing certificate formats other than raw, DE... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: 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
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"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/pickle.h" 13 #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
413 } // namespace 375 } // namespace
414 376
415 void X509Certificate::Initialize() { 377 void X509Certificate::Initialize() {
416 const CSSM_X509_NAME* name; 378 const CSSM_X509_NAME* name;
417 OSStatus status = SecCertificateGetSubject(cert_handle_, &name); 379 OSStatus status = SecCertificateGetSubject(cert_handle_, &name);
418 if (!status) { 380 if (!status) {
419 subject_.Parse(name); 381 subject_.Parse(name);
420 } 382 }
421 status = SecCertificateGetIssuer(cert_handle_, &name); 383 status = SecCertificateGetIssuer(cert_handle_, &name);
422 if (!status) { 384 if (!status) {
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 // static 662 // static
701 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( 663 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
702 const char* data, int length) { 664 const char* data, int length) {
703 CSSM_DATA cert_data; 665 CSSM_DATA cert_data;
704 cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data)); 666 cert_data.Data = const_cast<uint8*>(reinterpret_cast<const uint8*>(data));
705 cert_data.Length = length; 667 cert_data.Length = length;
706 668
707 OSCertHandle cert_handle = NULL; 669 OSCertHandle cert_handle = NULL;
708 OSStatus status = SecCertificateCreateFromData(&cert_data, 670 OSStatus status = SecCertificateCreateFromData(&cert_data,
709 CSSM_CERT_X_509v3, 671 CSSM_CERT_X_509v3,
710 CSSM_CERT_ENCODING_DER, 672 CSSM_CERT_ENCODING_BER,
711 &cert_handle); 673 &cert_handle);
712 if (status) 674 if (status)
713 return NULL; 675 return NULL;
714 676
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 // parsed 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
730 return cert_handle; 677 return cert_handle;
731 } 678 }
732 679
733 // static 680 // static
734 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
735 const char* data, int length, Format format) {
736 OSCertHandles results;
737
738 switch (format) {
739 case FORMAT_DER: {
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
757 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( 681 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
758 OSCertHandle handle) { 682 OSCertHandle handle) {
759 if (!handle) 683 if (!handle)
760 return NULL; 684 return NULL;
761 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle))); 685 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle)));
762 } 686 }
763 687
764 // static 688 // static
765 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { 689 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
766 CFRelease(cert_handle); 690 CFRelease(cert_handle);
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 } 893 }
970 CFRelease(cert_chain); 894 CFRelease(cert_chain);
971 } 895 }
972 exit: 896 exit:
973 if (result) 897 if (result)
974 LOG(ERROR) << "CreateIdentityCertificateChain error " << result; 898 LOG(ERROR) << "CreateIdentityCertificateChain error " << result;
975 return chain.release(); 899 return chain.release();
976 } 900 }
977 901
978 } // namespace net 902 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698