]> git.saurik.com Git - apple/security.git/blob - SecurityTests/regressions/kc/kc-50-iPhone-emulation.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / regressions / kc / kc-50-iPhone-emulation.c
1 #include <Security/Security.h>
2 #include <Security/SecKeyPriv.h>
3 #include <Security/SecItem.h>
4 #include <CoreFoundation/CoreFoundation.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7
8 #include "testmore.h"
9 #include "testenv.h"
10 #include "testcssm.h"
11 #include "testleaks.h"
12
13
14 void AddKeyCFTypePairToDictionary(CFMutableDictionaryRef mdr, CFTypeRef key, CFTypeRef value)
15 {
16 CFDictionaryAddValue(mdr, key, value);
17 }
18
19
20
21 void AddKeyNumberPairToDictionary(CFMutableDictionaryRef mdr, CFTypeRef key, uint32 value)
22 {
23 // make a CFNumber out of the value
24 CFNumberRef number = CFNumberCreate(NULL, kCFNumberSInt32Type, &value);
25 CFDictionaryAddValue(mdr, key, number);
26 CFRelease(number);
27 }
28
29
30
31 void AddKeyStringPairToDictionary(CFMutableDictionaryRef mdr, CFTypeRef key, const char* string)
32 {
33 // We add the string as a CFData
34 CFDataRef data = CFDataCreate(NULL, (const UInt8*) string, strlen(string));
35 CFDictionaryAddValue(mdr, key, data);
36 CFRelease(data);
37 }
38
39
40
41 int SignVerifyTest()
42 {
43 CFMutableDictionaryRef parameters;
44 SecKeyRef publicKey, privateKey;
45
46 // start out with an empty dictionary and see if it returns an error
47 parameters = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
48 OSStatus result = SecKeyGeneratePair(parameters, &publicKey, &privateKey);
49
50 ok(result != noErr, "result is noErr");
51
52 // add the algorithm type
53 AddKeyCFTypePairToDictionary(parameters, kSecAttrKeyType, kSecAttrKeyTypeRSA);
54
55 // see if we can get a 2048 bit keypair
56 AddKeyNumberPairToDictionary(parameters, kSecAttrKeySizeInBits, 2048);
57
58 // put an application tag on the key
59 AddKeyStringPairToDictionary(parameters, kSecAttrApplicationTag, "This is a test.");
60
61 // try again
62 result = SecKeyGeneratePair(parameters, &publicKey, &privateKey);
63 ok_status(result, "SecKeyGeneratePair");
64 if (result != noErr)
65 {
66 return 1;
67 }
68
69 // Make a chunk of data
70 char data[] = "This is a test of some data. Ain't it grand?";
71
72 SecPadding paddings[] = {kSecPaddingNone, kSecPaddingPKCS1, kSecPaddingPKCS1MD2, kSecPaddingPKCS1MD5, kSecPaddingPKCS1SHA1};
73 const int numberOfPaddings = sizeof(paddings) / sizeof (SecPadding);
74
75 // test each padding mode
76 int n;
77 for (n = 0; n < numberOfPaddings; ++n)
78 {
79 // sign that data with the private key
80 uint8 signature[512];
81 size_t signatureLength = sizeof(signature);
82
83 result = SecKeyRawSign(privateKey, paddings[n], (uint8_t*) data, strlen(data), signature, &signatureLength);
84 ok_status(result, "SecKeyRawSign");
85
86 // verify with the signature
87 result = SecKeyRawVerify(publicKey, paddings[n], (uint8_t*) data, strlen(data), signature, signatureLength);
88 ok_status(result, "SecKeyRawVerify");
89 }
90
91 // clean up
92 SecKeychainItemDelete((SecKeychainItemRef) publicKey);
93 SecKeychainItemDelete((SecKeychainItemRef) privateKey);
94
95 CFRelease(publicKey);
96 CFRelease(privateKey);
97 CFRelease(parameters);
98
99 return 0;
100 }
101
102 int SignVerifyWithAsyncTest()
103 {
104 CFMutableDictionaryRef parameters;
105 __block SecKeyRef publicKey, privateKey;
106
107 // start out with an empty dictionary and see if it returns an error
108 parameters = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
109 OSStatus result = SecKeyGeneratePair(parameters, &publicKey, &privateKey);
110 dispatch_group_t everyone_called = dispatch_group_create();
111
112 dispatch_group_enter(everyone_called);
113 SecKeyGeneratePairAsync(parameters, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(SecKeyRef publicKey, SecKeyRef privateKey, CFErrorRef error){
114 ok(publicKey == NULL && privateKey == NULL, "keys are NULL");
115 ok(error != NULL, "error set");
116 dispatch_group_leave(everyone_called);
117 });
118
119 // add the algorithm type
120 AddKeyCFTypePairToDictionary(parameters, kSecAttrKeyType, kSecAttrKeyTypeRSA);
121
122 // see if we can get a 2048 bit keypair
123 AddKeyNumberPairToDictionary(parameters, kSecAttrKeySizeInBits, 2048);
124
125 // put an application tag on the key
126 AddKeyStringPairToDictionary(parameters, kSecAttrApplicationTag, "This is a test.");
127
128 // throw some sort of access thingie on it too
129 SecAccessRef access = NULL;
130 SecTrustedApplicationRef myself = NULL;
131 ok_status(SecTrustedApplicationCreateFromPath(NULL, &myself), "create trusted app for self");
132 CFArrayRef trustedApplications = CFArrayCreate(NULL, (const void **)&myself, 1, &kCFTypeArrayCallBacks);
133 ok_status(SecAccessCreate(CFSTR("Trust self (test)"), trustedApplications, &access), "SecAccessCreate");
134 CFRelease(trustedApplications);
135 CFRelease(myself);
136 AddKeyCFTypePairToDictionary(parameters, kSecAttrAccess, access);
137
138 // try again
139 dispatch_group_enter(everyone_called);
140 SecKeyGeneratePairAsync(parameters, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(SecKeyRef pubKey, SecKeyRef privKey, CFErrorRef error){
141 ok(pubKey != NULL && privKey != NULL, "keys set");
142 ok(error == NULL, "no error");
143 publicKey = (SecKeyRef)CFRetain(pubKey);
144 privateKey = (SecKeyRef)CFRetain(privKey);
145 dispatch_group_leave(everyone_called);
146 });
147
148 dispatch_group_wait(everyone_called, DISPATCH_TIME_FOREVER);
149 if (NULL == publicKey || NULL == privateKey)
150 {
151 return 1;
152 }
153
154 // Make a chunk of data
155 char data[] = "This is a test of some data. Ain't it grand?";
156
157 SecPadding paddings[] = {kSecPaddingNone, kSecPaddingPKCS1, kSecPaddingPKCS1MD2, kSecPaddingPKCS1MD5, kSecPaddingPKCS1SHA1};
158 const int numberOfPaddings = sizeof(paddings) / sizeof (SecPadding);
159
160 // test each padding mode
161 int n;
162 for (n = 0; n < numberOfPaddings; ++n)
163 {
164 // sign that data with the private key
165 uint8 signature[512];
166 size_t signatureLength = sizeof(signature);
167
168 result = SecKeyRawSign(privateKey, paddings[n], (uint8_t*) data, strlen(data), signature, &signatureLength);
169 ok_status(result, "SecKeyRawSign");
170
171 // verify with the signature
172 result = SecKeyRawVerify(publicKey, paddings[n], (uint8_t*) data, strlen(data), signature, signatureLength);
173 ok_status(result, "SecKeyRawVerify");
174 }
175
176 // clean up
177 SecKeychainItemDelete((SecKeychainItemRef) publicKey);
178 SecKeychainItemDelete((SecKeychainItemRef) privateKey);
179
180 CFRelease(publicKey);
181 CFRelease(privateKey);
182 CFRelease(parameters);
183
184 return 0;
185 }
186
187
188
189 int EncryptDecryptTest()
190 {
191 CFMutableDictionaryRef parameters;
192 SecKeyRef encryptionKey, decryptionKey;
193
194 // start out with an empty dictionary and see if it returns an error
195 parameters = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
196
197 // add the algorithm type
198 AddKeyCFTypePairToDictionary(parameters, kSecAttrKeyType, kSecAttrKeyTypeRSA);
199
200 // see if we can get a 2048 bit keypair
201 AddKeyNumberPairToDictionary(parameters, kSecAttrKeySizeInBits, 2048);
202
203 // put an application tag on the key
204 AddKeyStringPairToDictionary(parameters, kSecAttrApplicationTag, "This is a test.");
205
206 OSStatus result = SecKeyGeneratePair(parameters, &encryptionKey, &decryptionKey);
207 ok_status(result, "EncryptDecryptTest");
208
209 // Make a chunk of data
210 char data[] = "I want to keep this data secure.";
211
212 SecPadding paddings[] = {kSecPaddingPKCS1};
213 const int numberOfPaddings = sizeof(paddings) / sizeof (SecPadding);
214
215 // test each padding mode
216 int n;
217 for (n = 0; n < numberOfPaddings; ++n)
218 {
219 // encrypt that data with the public key
220 uint8 encryptedData[2048];
221 size_t encryptedDataLength = sizeof(encryptedData);
222 memset(encryptedData, 0xFF, encryptedDataLength);
223
224 result = SecKeyEncrypt(encryptionKey, paddings[n], (uint8_t*) data, sizeof(data), encryptedData, &encryptedDataLength);
225 if (result != noErr)
226 {
227 fprintf(stderr, "Error in encryption.\n");
228 cssmPerror(NULL, result);
229 return 1;
230 }
231
232 uint8 decryptedData[2048];
233 size_t decryptedDataLength = sizeof(decryptedData);
234
235 // decrypt with the private key
236 result = SecKeyDecrypt(decryptionKey, paddings[n], encryptedData, encryptedDataLength, decryptedData, &decryptedDataLength);
237 ok_status(result, "SecKeyDecrypt");
238
239 // what we got back had better equal what we put in
240 if (memcmp(data, decryptedData, sizeof(data)) != 0)
241 {
242 fprintf(stderr, "Decrypted text != original plain text.\n");
243 return 1;
244 }
245 }
246
247 // clean up
248 SecKeychainItemDelete((SecKeychainItemRef) encryptionKey);
249 SecKeychainItemDelete((SecKeychainItemRef) decryptionKey);
250
251 CFRelease(encryptionKey);
252 CFRelease(decryptionKey);
253 CFRelease(parameters);
254
255 return 0;
256 }
257
258
259
260 #define TEST_ITEM_ACCOUNT CFSTR("SecItemTest_Account")
261 #define TEST_ITEM_SERVICE CFSTR("SecItemTest_Service")
262
263 int SecItemTest()
264 {
265 // create a dictionary to hold the item
266 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
267
268 // create our item -- we are only testing generic passwords, since that is the scope of the bug
269 CFDictionaryAddValue(dict, kSecClass, kSecClassGenericPassword);
270 CFDictionaryAddValue(dict, kSecAttrAccount, TEST_ITEM_ACCOUNT);
271 CFDictionaryAddValue(dict, kSecAttrService, TEST_ITEM_SERVICE);
272
273 const char* data = "Shh! It's a secret!!!";
274 CFDataRef dataRef = CFDataCreateWithBytesNoCopy(NULL, (const UInt8*) data, strlen(data), NULL);
275 CFDictionaryAddValue(dict, kSecValueData, dataRef);
276
277 CFTypeRef itemRef;
278 OSStatus result = SecItemAdd(dict, &itemRef);
279 ok_status(result, "SecItemAdd");
280
281 // cleanup
282 CFRelease(dict);
283
284 // search for the item
285 dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
286
287 // create our item -- we are only testing generic passwords, since that is the scope of the bug
288 CFDictionaryAddValue(dict, kSecClass, kSecClassGenericPassword);
289 CFDictionaryAddValue(dict, kSecAttrAccount, TEST_ITEM_ACCOUNT);
290 CFDictionaryAddValue(dict, kSecAttrService, TEST_ITEM_SERVICE);
291 CFDictionaryAddValue(dict, kSecReturnAttributes, kCFBooleanTrue);
292
293 result = SecItemCopyMatching(dict, &itemRef);
294 ok_status(result, "SecItemCopyMatching");
295
296 return 0;
297 }
298
299
300
301 void tests()
302 {
303 SecKeychainRef keychain = NULL;
304 ok_status(SecKeychainSetUserInteractionAllowed(FALSE), "SecKeychainSetUserInteractionAllowed(FALSE)");
305 ok_status(SecKeychainCreate("test", 4, "test", FALSE, NULL, &keychain), "SecKeychainCreate");
306
307 SignVerifyWithAsyncTest();
308 SignVerifyTest();
309 SecItemTest();
310
311 if (keychain) CFRelease(keychain);
312 }
313
314
315
316 int main(int argc, char * const *argv)
317 {
318 plan_tests(34);
319 if (!tests_begin(argc, argv))
320 BAIL_OUT("tests_begin failed");
321 tests();
322 ok(tests_end(1), "cleanup");
323 ok_leaks("no leaks");
324 return 0;
325 }