]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-05-add.c
Security-59306.41.2.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-05-add.c
1 /*
2 * Copyright (c) 2008-2010,2012-2014 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 #include <CoreFoundation/CoreFoundation.h>
26 #include <Security/SecCertificate.h>
27 #include <Security/SecItem.h>
28 #include <Security/SecItemPriv.h>
29 #include <Security/SecBase.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32
33 #include "Security_regressions.h"
34
35 #define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) { (CF) = NULL; CFRelease(_cf); } }
36
37 /*
38 subject= /O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign
39 issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
40 serial=254B8A853842CCE358F8C5DDAE226EA4
41 */
42 const uint8_t _myCert[] = {
43 0x30, 0x82, 0x03, 0x83, 0x30, 0x82, 0x02, 0xec,
44 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x25,
45 0x4b, 0x8a, 0x85, 0x38, 0x42, 0xcc, 0xe3, 0x58,
46 0xf8, 0xc5, 0xdd, 0xae, 0x22, 0x6e, 0xa4, 0x30,
47 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
48 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f,
49 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
50 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30,
51 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e,
52 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e,
53 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x37,
54 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
55 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33,
56 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20,
57 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20,
58 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
59 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
60 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30,
61 0x1e, 0x17, 0x0d, 0x39, 0x37, 0x30, 0x34, 0x31,
62 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
63 0x17, 0x0d, 0x31, 0x31, 0x31, 0x30, 0x32, 0x34,
64 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30,
65 0x81, 0xba, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03,
66 0x55, 0x04, 0x0a, 0x13, 0x16, 0x56, 0x65, 0x72,
67 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72,
68 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77,
69 0x6f, 0x72, 0x6b, 0x31, 0x17, 0x30, 0x15, 0x06,
70 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x56, 0x65,
71 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20,
72 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31,
73 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56,
74 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20,
75 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74,
76 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65,
77 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20,
78 0x2d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20,
79 0x33, 0x31, 0x49, 0x30, 0x47, 0x06, 0x03, 0x55,
80 0x04, 0x0b, 0x13, 0x40, 0x77, 0x77, 0x77, 0x2e,
81 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
82 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53,
83 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e,
84 0x62, 0x79, 0x20, 0x52, 0x65, 0x66, 0x2e, 0x20,
85 0x4c, 0x49, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54,
86 0x59, 0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63,
87 0x29, 0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69,
88 0x53, 0x69, 0x67, 0x6e, 0x30, 0x81, 0x9f, 0x30,
89 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
90 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81,
91 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81,
92 0x00, 0xd8, 0x82, 0x80, 0xe8, 0xd6, 0x19, 0x02,
93 0x7d, 0x1f, 0x85, 0x18, 0x39, 0x25, 0xa2, 0x65,
94 0x2b, 0xe1, 0xbf, 0xd4, 0x05, 0xd3, 0xbc, 0xe6,
95 0x36, 0x3b, 0xaa, 0xf0, 0x4c, 0x6c, 0x5b, 0xb6,
96 0xe7, 0xaa, 0x3c, 0x73, 0x45, 0x55, 0xb2, 0xf1,
97 0xbd, 0xea, 0x97, 0x42, 0xed, 0x9a, 0x34, 0x0a,
98 0x15, 0xd4, 0xa9, 0x5c, 0xf5, 0x40, 0x25, 0xdd,
99 0xd9, 0x07, 0xc1, 0x32, 0xb2, 0x75, 0x6c, 0xc4,
100 0xca, 0xbb, 0xa3, 0xfe, 0x56, 0x27, 0x71, 0x43,
101 0xaa, 0x63, 0xf5, 0x30, 0x3e, 0x93, 0x28, 0xe5,
102 0xfa, 0xf1, 0x09, 0x3b, 0xf3, 0xb7, 0x4d, 0x4e,
103 0x39, 0xf7, 0x5c, 0x49, 0x5a, 0xb8, 0xc1, 0x1d,
104 0xd3, 0xb2, 0x8a, 0xfe, 0x70, 0x30, 0x95, 0x42,
105 0xcb, 0xfe, 0x2b, 0x51, 0x8b, 0x5a, 0x3c, 0x3a,
106 0xf9, 0x22, 0x4f, 0x90, 0xb2, 0x02, 0xa7, 0x53,
107 0x9c, 0x4f, 0x34, 0xe7, 0xab, 0x04, 0xb2, 0x7b,
108 0x6f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81,
109 0xe3, 0x30, 0x81, 0xe0, 0x30, 0x0f, 0x06, 0x03,
110 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01,
111 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x44, 0x06,
112 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, 0x30, 0x3b,
113 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01,
114 0x86, 0xf8, 0x45, 0x01, 0x07, 0x01, 0x01, 0x30,
115 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01,
116 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68,
117 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77,
118 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73,
119 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
120 0x43, 0x50, 0x53, 0x30, 0x34, 0x06, 0x03, 0x55,
121 0x1d, 0x25, 0x04, 0x2d, 0x30, 0x2b, 0x06, 0x08,
122 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01,
123 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
124 0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
125 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60,
126 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08,
127 0x01, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f,
128 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x11,
129 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
130 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x01,
131 0x06, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f,
132 0x04, 0x2a, 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24,
133 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70,
134 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76,
135 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e,
136 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33,
137 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09,
138 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
139 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x08,
140 0x01, 0xec, 0xe4, 0x68, 0x94, 0x03, 0x42, 0xf1,
141 0x73, 0xf1, 0x23, 0xa2, 0x3a, 0xde, 0xe9, 0xf1,
142 0xda, 0xc6, 0x54, 0xc4, 0x23, 0x3e, 0x86, 0xea,
143 0xcf, 0x6a, 0x3a, 0x33, 0xab, 0xea, 0x9c, 0x04,
144 0x14, 0x07, 0x36, 0x06, 0x0b, 0xf9, 0x88, 0x6f,
145 0xd5, 0x13, 0xee, 0x29, 0x2b, 0xc3, 0xe4, 0x72,
146 0x8d, 0x44, 0xed, 0xd1, 0xac, 0x20, 0x09, 0x2d,
147 0xe1, 0xf6, 0xe1, 0x19, 0x05, 0x38, 0xb0, 0x3d,
148 0x0f, 0x9f, 0x7f, 0xf8, 0x9e, 0x02, 0xdc, 0x86,
149 0x02, 0x86, 0x61, 0x4e, 0x26, 0x5f, 0x5e, 0x9f,
150 0x92, 0x1e, 0x0c, 0x24, 0xa4, 0xf5, 0xd0, 0x70,
151 0x13, 0xcf, 0x26, 0xc3, 0x43, 0x3d, 0x49, 0x1d,
152 0x9e, 0x82, 0x2e, 0x52, 0x5f, 0xbc, 0x3e, 0xc6,
153 0x66, 0x29, 0x01, 0x8e, 0x4e, 0x92, 0x2c, 0xbc,
154 0x46, 0x75, 0x03, 0x82, 0xac, 0x73, 0xe9, 0xd9,
155 0x7e, 0x0b, 0x67, 0xef, 0x54, 0x52, 0x1a
156 };
157
158 static void persistentRefIs(CFDataRef pref, CFDataRef data) {
159 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
160 CFTypeRef result = NULL;
161 CFDictionaryAddValue(dict, kSecValuePersistentRef, pref);
162 CFDictionaryAddValue(dict, kSecReturnData, kCFBooleanTrue);
163 ok_status(SecItemCopyMatching(dict, &result), "lookup item data by persistent ref");
164 ok(CFEqual(data, result), "result %@ equals expected data %@", result, data);
165 CFReleaseNull(result);
166 CFReleaseNull(dict);
167 }
168
169 /* Test add api in all its variants. */
170 static void tests(void)
171 {
172 CFDataRef myCertData = NULL;
173 SecCertificateRef myCert = NULL;
174 CFTypeRef certHandle = NULL;
175
176 /* Create myCert and setup dict. */
177 myCertData = CFDataCreateWithBytesNoCopy(NULL, _myCert, sizeof(_myCert),
178 kCFAllocatorNull);
179 isnt(myCert = SecCertificateCreateWithData(NULL, myCertData),
180 NULL, "create myCert");
181 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
182 CFDictionaryAddValue(dict, kSecClass, kSecClassCertificate);
183 CFDictionaryAddValue(dict, kSecValueRef, myCert);
184
185 /* Case 1: add certificate with no return pointer. */
186 ok_status(SecItemAdd(dict, NULL),
187 "Case 1: add certificate NULL return pointer");
188
189 /* Case 1a: test add duplicate item */
190 is_status(SecItemAdd(dict, NULL), errSecDuplicateItem, "add certificate again");
191
192 ok_status(SecItemDelete(dict), "delete certificate");
193 /* Case 1b: add certificate ref should be returned implicitly. */
194 ok_status(SecItemAdd(dict, &certHandle),
195 "Case 1: add certificate dont ask for return type");
196 // See also: "<rdar://problem/7091317493> SecItemAdd unimplemented feature";
197 is(certHandle, NULL, "nothing returned");
198 CFReleaseNull(certHandle);
199 ok_status(SecItemDelete(dict), "delete certificate");
200
201 /* Case 2: add certificate ask for persistent ref. */
202 CFDictionaryAddValue(dict, kSecReturnPersistentRef, kCFBooleanTrue);
203 ok_status(SecItemAdd(dict, &certHandle),
204 "Case 2: add certificate ask for persistent ref");
205 is(CFGetTypeID(certHandle), CFDataGetTypeID(), "persistent ref returned");
206 /* Check if persistent ref yields cert data again when searched. */
207 persistentRefIs(certHandle, myCertData);
208 CFReleaseNull(certHandle);
209 CFDictionaryRemoveValue(dict, kSecReturnPersistentRef);
210 ok_status(SecItemDelete(dict), "delete certificate");
211
212 /* Case 3: add certificate ask for ref to be returned explicitly. */
213 CFDictionaryAddValue(dict, kSecReturnRef, kCFBooleanTrue);
214 ok_status(SecItemAdd(dict, &certHandle),
215 "Case 3: add certificate ask for ref to be returned explicitly");
216 ok(CFEqual(myCert, certHandle), "certificate ref matches");
217 CFReleaseNull(certHandle);
218 CFDictionaryRemoveValue(dict, kSecReturnRef);
219 ok_status(SecItemDelete(dict), "delete certificate");
220
221 /* Case 4: add certificate ask for data to be returned explicitly. */
222 CFDictionaryAddValue(dict, kSecReturnData, kCFBooleanTrue);
223 ok_status(SecItemAdd(dict, &certHandle),
224 "Case 4: add certificate ask for data to be returned explicitly");
225 ok(CFEqual(myCertData, certHandle), "certificate data matches");
226 CFReleaseNull(certHandle);
227 CFDictionaryRemoveValue(dict, kSecReturnData);
228 ok_status(SecItemDelete(dict), "delete certificate");
229
230 /* Case 5: add certificate ask for attributes to be returned explicitly. */
231 CFDictionaryAddValue(dict, kSecReturnAttributes, kCFBooleanTrue);
232 ok_status(SecItemAdd(dict, &certHandle),
233 "Case 5: add certificate ask for attributes to be returned explicitly");
234 is(CFGetTypeID(certHandle), CFDictionaryGetTypeID(), "result is a dict");
235 ok(!CFDictionaryContainsKey(certHandle, kSecValueData),
236 "result has no data");
237 ok(!CFDictionaryContainsKey(certHandle, kSecValueRef),
238 "result has no ref");
239 ok(!CFDictionaryContainsKey(certHandle, kSecValuePersistentRef),
240 "result has no persistent ref");
241 /* @@@ Check attribute values. Against this list:
242 kSecClassCertificate item attributes:
243 kSecAttrAccessGroup
244 kSecAttrCertificateType
245 kSecAttrCertificateEncoding
246 kSecAttrLabel
247 kSecAttrSubject
248 kSecAttrIssuer
249 kSecAttrSerialNumber
250 kSecAttrSubjectKeyID
251 kSecAttrPublicKeyHash
252 */
253 is(CFGetTypeID(CFDictionaryGetValue(certHandle, kSecAttrCertificateType)),
254 CFNumberGetTypeID(), "certificate type is a number");
255 is(CFGetTypeID(CFDictionaryGetValue(certHandle, kSecAttrCertificateEncoding)),
256 CFNumberGetTypeID(), "certificate encoding is a number");
257 CFReleaseNull(certHandle);
258 CFDictionaryRemoveValue(dict, kSecReturnAttributes);
259 ok_status(SecItemDelete(dict), "delete certificate");
260
261 /* Case 6: add certificate ask for attributes, data, ref and persistent ref
262 to be returned explicitly. */
263 CFDictionaryAddValue(dict, kSecReturnData, kCFBooleanTrue);
264 CFDictionaryAddValue(dict, kSecReturnAttributes, kCFBooleanTrue);
265 CFDictionaryAddValue(dict, kSecReturnRef, kCFBooleanTrue);
266 CFDictionaryAddValue(dict, kSecReturnPersistentRef, kCFBooleanTrue);
267 ok_status(SecItemAdd(dict, &certHandle),
268 "Case 6: add certificate ask for attributes, data, ref and persistent ref to be returned explicitly");
269 isnt(certHandle, NULL, "certificate handle returned");
270 is(CFGetTypeID(certHandle), CFDictionaryGetTypeID(), "result is a dict");
271 ok(CFEqual(myCertData, CFDictionaryGetValue(certHandle, kSecValueData)),
272 "certificate data in dict matches");
273 ok(CFEqual(myCert, CFDictionaryGetValue(certHandle, kSecValueRef)),
274 "certificate ref in dict matches");
275 /* Check if persistent ref yields cert data again when searched. */
276 persistentRefIs(CFDictionaryGetValue(certHandle, kSecValuePersistentRef),
277 myCertData);
278 ok(CFEqual(kSecClassCertificate,
279 CFDictionaryGetValue(certHandle, kSecClass)),
280 "certificate class in dict matches");
281 is(CFGetTypeID(CFDictionaryGetValue(certHandle, kSecAttrCertificateType)),
282 CFNumberGetTypeID(), "certificate type is a number");
283 is(CFGetTypeID(CFDictionaryGetValue(certHandle, kSecAttrCertificateEncoding)),
284 CFNumberGetTypeID(), "certificate encoding is a number");
285 CFReleaseNull(certHandle);
286 CFDictionaryRemoveValue(dict, kSecReturnData);
287 CFDictionaryRemoveValue(dict, kSecReturnAttributes);
288 CFDictionaryRemoveValue(dict, kSecReturnRef);
289 CFDictionaryRemoveValue(dict, kSecReturnPersistentRef);
290 ok_status(SecItemDelete(dict), "delete certificate");
291
292 /* Case 7: add certificate with bogus attribute. */
293 CFDataRef tagData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
294 (const UInt8 *)"funnytag", 8, kCFAllocatorNull);
295 CFDictionaryAddValue(dict, kSecAttrApplicationTag, tagData);
296 is_status(SecItemAdd(dict, &certHandle), errSecNoSuchAttr,
297 "Case 7: add certificate with bogus attribute returns errSecNoSuchAttr");
298 CFReleaseNull(certHandle);
299 is_status(SecItemDelete(dict), errSecNoSuchAttr,
300 "delete certificate with bogus attribute returns errSecNoSuchAttr");
301 CFDictionaryRemoveValue(dict, kSecAttrApplicationTag);
302 CFReleaseNull(tagData);
303
304 /* Case 8: add certificate with synchronizable attribute. */
305 CFDictionaryAddValue(dict, kSecAttrSynchronizable, kCFBooleanTrue);
306 ok_status(SecItemAdd(dict, &certHandle),
307 "Case 7: add certificate with synchronizable attribute works");
308 CFReleaseNull(certHandle);
309 ok_status(SecItemDelete(dict),
310 "delete certificate with synchronizable attribute works");
311 CFDictionaryRemoveValue(dict, kSecAttrSynchronizable);
312
313 /* Cleanup. */
314 CFReleaseNull(dict);
315 CFReleaseNull(myCert);
316 CFReleaseNull(myCertData);
317
318 }
319
320 int si_05_add(int argc, char *const *argv)
321 {
322 plan_tests(41);
323
324 tests();
325
326 return 0;
327 }