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