/ OSX / sec / Security / SecIdentity.c
SecIdentity.c
  1  /*
  2   * Copyright (c) 2002-2004,2007-2008,2010,2012-2017 Apple Inc. All Rights Reserved.
  3   *
  4   * @APPLE_LICENSE_HEADER_START@
  5   *
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. Please obtain a copy of the License at
 10   * http://www.opensource.apple.com/apsl/ and read it before using this
 11   * file.
 12   *
 13   * The Original Code and all software distributed under the License are
 14   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 15   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 16   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 18   * Please see the License for the specific language governing rights and
 19   * limitations under the License.
 20   *
 21   * @APPLE_LICENSE_HEADER_END@
 22   */
 23  
 24  /*
 25   *  SecIdentity.c - CoreFoundation based object containing a
 26   *  private key, certificate tuple.
 27   */
 28  
 29  
 30  #include <Security/SecIdentity.h>
 31  
 32  #include <CoreFoundation/CFRuntime.h>
 33  #include <CoreFoundation/CFString.h>
 34  #include <Security/SecCertificate.h>
 35  #include <Security/SecKey.h>
 36  #include <pthread.h>
 37  #include <Security/SecIdentityPriv.h>
 38  #include <Security/SecInternal.h>
 39  #include <utilities/SecCFWrappers.h>
 40  
 41  struct __SecIdentity {
 42      CFRuntimeBase		_base;
 43  	SecCertificateRef	_certificate;
 44  	SecKeyRef			_privateKey;
 45  };
 46  
 47  CFGiblisWithHashFor(SecIdentity)
 48  
 49  /* Static functions. */
 50  static CFStringRef SecIdentityCopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
 51      SecIdentityRef identity = (SecIdentityRef)cf;
 52      return CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
 53          CFSTR("<SecIdentityRef: %p>"), identity);
 54  }
 55  
 56  static void SecIdentityDestroy(CFTypeRef cf) {
 57      SecIdentityRef identity = (SecIdentityRef)cf;
 58  	CFReleaseNull(identity->_certificate);
 59  	CFReleaseNull(identity->_privateKey);
 60  }
 61  
 62  static Boolean SecIdentityCompare(CFTypeRef cf1, CFTypeRef cf2) {
 63      SecIdentityRef identity1 = (SecIdentityRef)cf1;
 64      SecIdentityRef identity2 = (SecIdentityRef)cf2;
 65      if (identity1 == identity2)
 66          return true;
 67      if (!identity2)
 68          return false;
 69      return CFEqual(identity1->_certificate, identity2->_certificate) &&
 70  		CFEqual(identity1->_privateKey, identity2->_privateKey);
 71  }
 72  
 73  /* Hash of identity is hash of certificate plus hash of key. */
 74  static CFHashCode SecIdentityHash(CFTypeRef cf) {
 75      SecIdentityRef identity = (SecIdentityRef)cf;
 76  	return CFHash(identity->_certificate) + CFHash(identity->_privateKey);
 77  }
 78  
 79  OSStatus SecIdentityCopyCertificate(SecIdentityRef identity,
 80  	SecCertificateRef *certificateRef) {
 81  	*certificateRef = identity->_certificate;
 82  	CFRetain(*certificateRef);
 83  	return 0;
 84  }
 85  
 86  OSStatus SecIdentityCopyPrivateKey(SecIdentityRef identity,
 87  	SecKeyRef *privateKeyRef) {
 88  	*privateKeyRef = identity->_privateKey;
 89  	CFRetain(*privateKeyRef);
 90  	return 0;
 91  }
 92  
 93  SecIdentityRef SecIdentityCreate(CFAllocatorRef allocator,
 94  	SecCertificateRef certificate, SecKeyRef privateKey) {
 95      if (!certificate || CFGetTypeID(certificate) != SecCertificateGetTypeID() ||
 96          !privateKey || CFGetTypeID(privateKey) != SecKeyGetTypeID()) {
 97          return NULL;
 98      }
 99      CFIndex size = sizeof(struct __SecIdentity);
100      SecIdentityRef result = (SecIdentityRef)_CFRuntimeCreateInstance(
101  		allocator, SecIdentityGetTypeID(), size - sizeof(CFRuntimeBase), 0);
102  	if (result) {
103  		CFRetain(certificate);
104  		CFRetain(privateKey);
105  		result->_certificate = certificate;
106  		result->_privateKey = privateKey;
107      }
108      return result;
109  }
110