]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 A |
1 | /* |
2 | * Copyright (c) 2002-2004,2007-2008,2010 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 "SecIdentityPriv.h" | |
38 | #include <Security/SecInternal.h> | |
39 | ||
40 | struct __SecIdentity { | |
41 | CFRuntimeBase _base; | |
42 | ||
43 | SecCertificateRef _certificate; | |
44 | SecKeyRef _privateKey; | |
45 | }; | |
46 | ||
47 | ||
48 | /* CFRuntime regsitration data. */ | |
49 | static pthread_once_t kSecIdentityRegisterClass = PTHREAD_ONCE_INIT; | |
50 | static CFTypeID kSecIdentityTypeID = _kCFRuntimeNotATypeID; | |
51 | ||
52 | /* Forward declartions of static functions. */ | |
427c49bc | 53 | static CFStringRef SecIdentityCopyDescription(CFTypeRef cf); |
b1ab9ed8 A |
54 | static void SecIdentityDestroy(CFTypeRef cf); |
55 | ||
56 | /* Static functions. */ | |
427c49bc | 57 | static CFStringRef SecIdentityCopyDescription(CFTypeRef cf) { |
b1ab9ed8 A |
58 | SecIdentityRef identity = (SecIdentityRef)cf; |
59 | return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, | |
60 | CFSTR("<SecIdentityRef: %p>"), identity); | |
61 | } | |
62 | ||
63 | static void SecIdentityDestroy(CFTypeRef cf) { | |
64 | SecIdentityRef identity = (SecIdentityRef)cf; | |
65 | CFReleaseSafe(identity->_certificate); | |
66 | CFReleaseSafe(identity->_privateKey); | |
67 | } | |
68 | ||
69 | static Boolean SecIdentityEqual(CFTypeRef cf1, CFTypeRef cf2) { | |
70 | SecIdentityRef identity1 = (SecIdentityRef)cf1; | |
71 | SecIdentityRef identity2 = (SecIdentityRef)cf2; | |
72 | if (identity1 == identity2) | |
73 | return true; | |
74 | if (!identity2) | |
75 | return false; | |
76 | return CFEqual(identity1->_certificate, identity2->_certificate) && | |
77 | CFEqual(identity1->_privateKey, identity2->_privateKey); | |
78 | } | |
79 | ||
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); | |
84 | } | |
85 | ||
86 | static void SecIdentityRegisterClass(void) { | |
87 | static const CFRuntimeClass kSecIdentityClass = { | |
88 | 0, /* version */ | |
89 | "SecIdentity", /* class name */ | |
90 | NULL, /* init */ | |
91 | NULL, /* copy */ | |
92 | SecIdentityDestroy, /* dealloc */ | |
93 | SecIdentityEqual, /* equal */ | |
94 | SecIdentityHash, /* hash */ | |
95 | NULL, /* copyFormattingDesc */ | |
427c49bc | 96 | SecIdentityCopyDescription /* copyDebugDesc */ |
b1ab9ed8 A |
97 | }; |
98 | ||
99 | kSecIdentityTypeID = _CFRuntimeRegisterClass(&kSecIdentityClass); | |
100 | } | |
101 | ||
102 | ||
103 | /* Public API functions. */ | |
104 | CFTypeID SecIdentityGetTypeID(void) { | |
105 | pthread_once(&kSecIdentityRegisterClass, SecIdentityRegisterClass); | |
106 | return kSecIdentityTypeID; | |
107 | } | |
108 | ||
109 | OSStatus SecIdentityCopyCertificate(SecIdentityRef identity, | |
110 | SecCertificateRef *certificateRef) { | |
111 | *certificateRef = identity->_certificate; | |
112 | CFRetain(*certificateRef); | |
113 | return 0; | |
114 | } | |
115 | ||
116 | OSStatus SecIdentityCopyPrivateKey(SecIdentityRef identity, | |
117 | SecKeyRef *privateKeyRef) { | |
118 | *privateKeyRef = identity->_privateKey; | |
119 | CFRetain(*privateKeyRef); | |
120 | return 0; | |
121 | } | |
122 | ||
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); | |
128 | if (result) { | |
129 | CFRetain(certificate); | |
130 | CFRetain(privateKey); | |
131 | result->_certificate = certificate; | |
132 | result->_privateKey = privateKey; | |
133 | } | |
134 | return result; | |
135 | } | |
136 |