]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/otr/otr-00-identity.c
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / otr / otr-00-identity.c
1 /*
2 * Copyright (c) 2011-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 <stdio.h>
26
27 #include "Security_regressions.h"
28
29 #include <CoreFoundation/CFData.h>
30 #include <Security/SecOTRSession.h>
31 #include <Security/SecInternal.h>
32 #include <Security/SecBasePriv.h>
33 #include <Security/SecKey.h>
34 #include <Security/SecItem.h>
35 #include <utilities/SecCFWrappers.h>
36 #include <Security/SecOTRIdentityPriv.h>
37
38 static void RegressionsLogError(CFErrorRef error) {
39 if (error == NULL) {
40 return;
41 }
42 CFDictionaryRef tempDictionary = CFErrorCopyUserInfo(error);
43 CFIndex errorCode = CFErrorGetCode(error);
44 CFStringRef errorDomain = CFErrorGetDomain(error);
45 CFStringRef errorString = CFDictionaryGetValue(tempDictionary, kCFErrorDescriptionKey);
46 CFErrorRef previousError = (CFErrorRef)CFDictionaryGetValue(tempDictionary, kCFErrorUnderlyingErrorKey);
47 if (previousError != NULL) {
48 RegressionsLogError(previousError);
49 }
50 char errorDomainStr[1024];
51 char errorStringStr[1024];
52
53 CFStringGetCString(errorDomain, errorDomainStr, 1024, kCFStringEncodingUTF8);
54 CFStringGetCString(errorString, errorStringStr, 1024, kCFStringEncodingUTF8);
55 printf("OTR: %s (%ld) -- %s\n", errorDomainStr, errorCode, errorStringStr);
56 CFReleaseSafe(tempDictionary);
57 }
58
59 static int kTestTestCount = 27;
60
61 static void otr_00_identity_MessageProtectionKeys()
62 {
63 // We create a MessageProtection-style key.
64 int32_t keysz32 = 256;
65 CFNumberRef ksizeNumber = CFNumberCreate(NULL, kCFNumberSInt32Type, &keysz32);
66 CFDictionaryRef dict = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
67 kSecAttrKeyType, kSecAttrKeyTypeECSECPrimeRandom,
68 kSecAttrKeyClass, kSecAttrKeyClassPrivate,
69 kSecAttrKeySizeInBits, ksizeNumber,
70 kSecAttrIsPermanent, kCFBooleanFalse, NULL);
71
72 CFErrorRef error = NULL;
73 SecKeyRef testIdentityKey = SecKeyCreateRandomKey(dict, &error);
74 ok(testIdentityKey != NULL, "Failed to create test key.");
75
76 CFReleaseSafe(ksizeNumber);
77 CFReleaseSafe(dict);
78
79 SecOTRFullIdentityRef identity1 = SecOTRFullIdentityCreateFromSecKeyRef(kCFAllocatorDefault, testIdentityKey, &error);
80 ok(identity1->isMessageProtectionKey, "Should be MessageProtection Key");
81 ok(identity1->privateKeyPersistentRef == NULL, "MessageProtection key shouldn't have a peristent ref.");
82
83 CFMutableDataRef serializeInto = CFDataCreateMutable(kCFAllocatorDefault, 100);
84 SecOTRFIAppendSerialization(identity1, serializeInto, &error);
85
86 SecOTRFullIdentityRef identity2 = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, serializeInto, &error);
87 ok(identity2->isMessageProtectionKey, "Should still be a MessageProtection Key");
88 ok(identity2->privateKeyPersistentRef == NULL, "MessageProtection key shouldn't have a peristent ref.");
89
90 CFDataRef serializedKey1 = SecKeyCopyExternalRepresentation(identity1->privateSigningKey, &error);
91 CFDataRef serializedKey2 = SecKeyCopyExternalRepresentation(identity2->privateSigningKey, &error);
92
93 ok(CFEqual(serializedKey1, serializedKey2));
94 ok(error == NULL, "Testing shouldn't cause any errors");
95
96 CFReleaseSafe(error);
97 CFReleaseSafe(serializedKey1);
98 CFReleaseSafe(serializedKey2);
99 CFReleaseSafe(identity1);
100 CFReleaseSafe(identity2);
101 CFReleaseSafe(testIdentityKey);
102 CFReleaseNull(serializeInto);
103 }
104
105 static void tests(void)
106 {
107 CFErrorRef testError = NULL;
108
109 SecOTRFullIdentityRef idToPurge = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError);
110 ok(idToPurge != NULL, "Make Identity: %@", testError);
111 ok(idToPurge->isMessageProtectionKey == false, "Keys shouldn't be defaulting to MessageProtection type");
112 RegressionsLogError(testError);
113 CFReleaseNull(testError);
114
115 CFMutableDataRef purgeExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
116
117 ok(SecOTRFIAppendSerialization(idToPurge, purgeExport, &testError), "First export: %@", testError);
118 RegressionsLogError(testError);
119 CFReleaseNull(testError);
120
121 SecOTRFullIdentityRef purgeIdInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError);
122 ok(purgeIdInflate != NULL, "Inflate Identity: %@", testError);
123 ok(idToPurge->isMessageProtectionKey == false, "Keys shouldn't be re-imported as MessageProtection types");
124 RegressionsLogError(testError);
125 CFReleaseNull(testError);
126
127 SecOTRFIPurgeFromKeychain(idToPurge, &testError);
128 RegressionsLogError(testError);
129 CFReleaseNull(testError);
130
131 SecOTRFullIdentityRef failIDInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError);
132 ok(failIDInflate == NULL, "Should fail: %@", testError);
133 RegressionsLogError(testError);
134 CFReleaseNull(testError);
135
136
137 CFReleaseSafe(idToPurge);
138
139
140 idToPurge = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError);
141 ok(idToPurge != NULL, "Make Identity again: %@", testError);
142 RegressionsLogError(testError);
143 CFReleaseNull(testError);
144
145 SecOTRFIPurgeAllFromKeychain(&testError);
146 RegressionsLogError(testError);
147 CFReleaseNull(testError);
148
149 SecOTRFullIdentityRef failIDInflate2 = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError);
150 ok(failIDInflate2 == NULL, "Should fail 2: %@", testError);
151 RegressionsLogError(testError);
152 CFReleaseNull(testError);
153
154 SecOTRFullIdentityRef id = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError);
155 ok(id != NULL, "Make Identity: %@", testError);
156 RegressionsLogError(testError);
157 CFReleaseNull(testError);
158
159 CFMutableDataRef firstExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
160
161 ok(SecOTRFIAppendSerialization(id, firstExport, &testError), "First export: %@", testError);
162 RegressionsLogError(testError);
163 CFReleaseNull(testError);
164
165 SecOTRFullIdentityRef idInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, firstExport, &testError);
166 ok(idInflate != NULL, "Inflate Identity: %@", testError);
167 RegressionsLogError(testError);
168 CFReleaseNull(testError);
169
170 CFMutableDataRef secondExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
171
172 ok(SecOTRFIAppendSerialization(idInflate, secondExport, &testError), "second export: %@", testError);
173 RegressionsLogError(testError);
174 CFReleaseNull(testError);
175
176 ok(CFDataGetLength(firstExport) == CFDataGetLength(secondExport)
177 && 0 == memcmp(CFDataGetBytePtr(firstExport), CFDataGetBytePtr(secondExport), (size_t)CFDataGetLength(firstExport)), "Different exports");
178
179 SecOTRPublicIdentityRef pubID = SecOTRPublicIdentityCopyFromPrivate(kCFAllocatorDefault, id, &testError);
180 ok(id != NULL, "Failed to copy public identity: %@", testError);
181 RegressionsLogError(testError);
182 CFReleaseNull(testError);
183
184 CFMutableDataRef firstPublicExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
185
186 ok(SecOTRPIAppendSerialization(pubID, firstPublicExport, &testError), "failed first public export: %@", testError);
187 RegressionsLogError(testError);
188 CFReleaseNull(testError);
189
190 SecOTRPublicIdentityRef pubIDInflate = SecOTRPublicIdentityCreateFromData(kCFAllocatorDefault, firstPublicExport, &testError);
191 ok(pubIDInflate != NULL, "Pub inflate failed: %@", testError);
192 RegressionsLogError(testError);
193 CFReleaseNull(testError);
194
195 CFMutableDataRef secondPublicExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
196
197 ok(SecOTRPIAppendSerialization(pubID, secondPublicExport, &testError), "failed second public export: %@", testError);
198 RegressionsLogError(testError);
199 CFReleaseNull(testError);
200
201 ok(CFDataGetLength(firstPublicExport) == CFDataGetLength(secondPublicExport)
202 && 0 == memcmp(CFDataGetBytePtr(firstPublicExport), CFDataGetBytePtr(secondPublicExport), (size_t)CFDataGetLength(firstPublicExport)), "Different public exports");
203
204 uint8_t sampleByteString[] = {
205 0x30, 0x81, 0xf6, 0x81, 0x43, 0x00, 0x41, 0x04, 0xc6, 0x8a, 0x2a, 0x5c, 0x29, 0xa4, 0xb7, 0x58,
206 0xe1, 0x3c, 0x07, 0x19, 0x20, 0xf3, 0x0b, 0xb8, 0xb3, 0x40, 0x41, 0x29, 0x4a, 0xa6, 0x7a, 0x56,
207 0x28, 0x6d, 0x10, 0x85, 0x2b, 0x14, 0x83, 0xaa, 0x1f, 0x6a, 0x47, 0xbc, 0x19, 0x26, 0x39, 0x1c,
208 0xd4, 0xbb, 0x8c, 0xd6, 0x94, 0x24, 0x79, 0x60, 0xfb, 0x8e, 0x4b, 0xf4, 0x0f, 0xbf, 0x38, 0x81,
209 0x78, 0xce, 0x1d, 0xd9, 0x03, 0xec, 0x65, 0xcd, 0x82, 0x81, 0xae, 0x00, 0xac, 0x30, 0x81, 0xa9,
210 0x02, 0x81, 0xa1, 0x00, 0xd2, 0xf4, 0x40, 0x8b, 0x2f, 0x09, 0x75, 0x2c, 0x68, 0x12, 0x76, 0xb9,
211 0xfb, 0x1b, 0x02, 0x91, 0x6d, 0xd7, 0x86, 0x49, 0xdc, 0xef, 0x38, 0xf3, 0x50, 0x58, 0xb5, 0xff,
212 0x5c, 0x02, 0x8a, 0xb0, 0xcd, 0xb3, 0x3d, 0x94, 0x71, 0x7d, 0x32, 0x53, 0xed, 0x43, 0xfb, 0xde,
213 0xbc, 0x20, 0x21, 0x33, 0xe3, 0xeb, 0x93, 0x48, 0xe8, 0xd1, 0x32, 0x2f, 0x40, 0x40, 0x47, 0x1f,
214 0xeb, 0x7e, 0xf6, 0x43, 0x81, 0x51, 0xd6, 0x4f, 0xe0, 0x57, 0xbf, 0x12, 0xeb, 0x18, 0x2e, 0x81,
215 0x0b, 0x3a, 0x04, 0xf1, 0xeb, 0x3c, 0xe1, 0xb9, 0xf4, 0x87, 0x37, 0x83, 0x5a, 0x2e, 0x09, 0xf8,
216 0xd5, 0xa0, 0x12, 0xfb, 0x35, 0xe4, 0xd4, 0x3f, 0xef, 0x24, 0x3e, 0x6c, 0xff, 0xb1, 0x35, 0x7e,
217 0x9f, 0xe7, 0x6d, 0x2f, 0xf8, 0x0d, 0xc6, 0xbc, 0x19, 0xe2, 0x78, 0xb3, 0x71, 0xe1, 0x35, 0xe7,
218 0xc7, 0x22, 0x6b, 0x4d, 0x92, 0xc4, 0x10, 0x75, 0x1a, 0x9b, 0x9f, 0x7f, 0xac, 0x2d, 0xfb, 0xc9,
219 0x64, 0x1e, 0x80, 0x11, 0x7f, 0x75, 0x8a, 0x86, 0x7e, 0x09, 0x44, 0xc4, 0x71, 0xbf, 0xd4, 0xfa,
220 0x8b, 0x6a, 0xb8, 0x9f, 0x02, 0x03, 0x01, 0x00,
221 0x01};
222
223 CFDataRef testInteropImport = CFDataCreate(kCFAllocatorDefault, sampleByteString, sizeof(sampleByteString));
224 SecOTRPublicIdentityRef interopIDInflate = SecOTRPublicIdentityCreateFromData(kCFAllocatorDefault, testInteropImport, &testError);
225 RegressionsLogError(testError);
226 CFReleaseNull(testError);
227 ok(interopIDInflate != NULL, "Interop inflate failed");
228
229 /* cleanup keychain */
230 ok(SecOTRFIPurgeAllFromKeychain(&testError),"cleanup keychain");
231 RegressionsLogError(testError);
232 CFReleaseNull(testError);
233
234 CFReleaseSafe(pubID);
235 CFReleaseSafe(pubIDInflate);
236 CFReleaseSafe(firstPublicExport);
237 CFReleaseSafe(secondPublicExport);
238 CFReleaseSafe(id);
239 CFReleaseSafe(idToPurge);
240 CFReleaseSafe(idInflate);
241 CFReleaseSafe(firstExport);
242 CFReleaseSafe(secondExport);
243 CFReleaseSafe(purgeExport);
244 CFReleaseSafe(purgeIdInflate);
245 CFReleaseSafe(failIDInflate);
246 CFReleaseSafe(failIDInflate2);
247 CFReleaseSafe(testInteropImport);
248 CFReleaseSafe(interopIDInflate);
249
250 otr_00_identity_MessageProtectionKeys();
251 }
252
253
254
255 int otr_00_identity(int argc, char *const *argv)
256 {
257 plan_tests(kTestTestCount);
258
259 tests();
260
261 return 0;
262 }