2 * Copyright (c) 2002-2004,2007-2008,2010 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * SecIdentity.c - CoreFoundation based object containing a
26 * private key, certificate tuple.
30 #include <Security/SecIdentity.h>
32 #include <CoreFoundation/CFRuntime.h>
33 #include <CoreFoundation/CFString.h>
34 #include <Security/SecCertificate.h>
35 #include <Security/SecKey.h>
37 #include "SecIdentityPriv.h"
38 #include <Security/SecInternal.h>
40 struct __SecIdentity
{
43 SecCertificateRef _certificate
;
44 SecKeyRef _privateKey
;
48 /* CFRuntime regsitration data. */
49 static pthread_once_t kSecIdentityRegisterClass
= PTHREAD_ONCE_INIT
;
50 static CFTypeID kSecIdentityTypeID
= _kCFRuntimeNotATypeID
;
52 /* Forward declartions of static functions. */
53 static CFStringRef
SecIdentityCopyDescription(CFTypeRef cf
);
54 static void SecIdentityDestroy(CFTypeRef cf
);
56 /* Static functions. */
57 static CFStringRef
SecIdentityCopyDescription(CFTypeRef cf
) {
58 SecIdentityRef identity
= (SecIdentityRef
)cf
;
59 return CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
,
60 CFSTR("<SecIdentityRef: %p>"), identity
);
63 static void SecIdentityDestroy(CFTypeRef cf
) {
64 SecIdentityRef identity
= (SecIdentityRef
)cf
;
65 CFReleaseSafe(identity
->_certificate
);
66 CFReleaseSafe(identity
->_privateKey
);
69 static Boolean
SecIdentityEqual(CFTypeRef cf1
, CFTypeRef cf2
) {
70 SecIdentityRef identity1
= (SecIdentityRef
)cf1
;
71 SecIdentityRef identity2
= (SecIdentityRef
)cf2
;
72 if (identity1
== identity2
)
76 return CFEqual(identity1
->_certificate
, identity2
->_certificate
) &&
77 CFEqual(identity1
->_privateKey
, identity2
->_privateKey
);
80 /* Hash of identity is hash of certificate plus hash of key. */
81 static CFHashCode
SecIdentityHash(CFTypeRef cf
) {
82 SecIdentityRef identity
= (SecIdentityRef
)cf
;
83 return CFHash(identity
->_certificate
) + CFHash(identity
->_privateKey
);
86 static void SecIdentityRegisterClass(void) {
87 static const CFRuntimeClass kSecIdentityClass
= {
89 "SecIdentity", /* class name */
92 SecIdentityDestroy
, /* dealloc */
93 SecIdentityEqual
, /* equal */
94 SecIdentityHash
, /* hash */
95 NULL
, /* copyFormattingDesc */
96 SecIdentityCopyDescription
/* copyDebugDesc */
99 kSecIdentityTypeID
= _CFRuntimeRegisterClass(&kSecIdentityClass
);
103 /* Public API functions. */
104 CFTypeID
SecIdentityGetTypeID(void) {
105 pthread_once(&kSecIdentityRegisterClass
, SecIdentityRegisterClass
);
106 return kSecIdentityTypeID
;
109 OSStatus
SecIdentityCopyCertificate(SecIdentityRef identity
,
110 SecCertificateRef
*certificateRef
) {
111 *certificateRef
= identity
->_certificate
;
112 CFRetain(*certificateRef
);
116 OSStatus
SecIdentityCopyPrivateKey(SecIdentityRef identity
,
117 SecKeyRef
*privateKeyRef
) {
118 *privateKeyRef
= identity
->_privateKey
;
119 CFRetain(*privateKeyRef
);
123 SecIdentityRef
SecIdentityCreate(CFAllocatorRef allocator
,
124 SecCertificateRef certificate
, SecKeyRef privateKey
) {
125 CFIndex size
= sizeof(struct __SecIdentity
);
126 SecIdentityRef result
= (SecIdentityRef
)_CFRuntimeCreateInstance(
127 allocator
, SecIdentityGetTypeID(), size
- sizeof(CFRuntimeBase
), 0);
129 CFRetain(certificate
);
130 CFRetain(privateKey
);
131 result
->_certificate
= certificate
;
132 result
->_privateKey
= privateKey
;