1/*
2 *  mp-00-identity.c
3 *  regressions
4 *
5 *  Created by Mitch Adler on 2/3/11.
6 *  Copyright 2011 Apple Inc. All rights reserved.
7 *
8 */
9
10#include <stdio.h>
11
12#include "Security_regressions.h"
13
14#include <CoreFoundation/CFData.h>
15#include <Security/SecOTRSession.h>
16#include <Security/SecInternal.h>
17#include <Security/SecBasePriv.h>
18
19static void RegressionsLogError(CFErrorRef error) {
20    if (error == NULL) {
21        return;
22    }
23    CFDictionaryRef tempDictionary = CFErrorCopyUserInfo(error);
24    CFIndex errorCode = CFErrorGetCode(error);
25    CFStringRef errorDomain = CFErrorGetDomain(error);
26    CFStringRef errorString = CFDictionaryGetValue(tempDictionary, kCFErrorDescriptionKey);
27    CFErrorRef previousError = (CFErrorRef)CFDictionaryGetValue(tempDictionary, kCFErrorUnderlyingErrorKey);
28    if (previousError != NULL) {
29        RegressionsLogError(previousError);
30    }
31    char errorDomainStr[1024];
32    char errorStringStr[1024];
33
34    CFStringGetCString(errorDomain, errorDomainStr, 1024, kCFStringEncodingUTF8);
35    CFStringGetCString(errorString, errorStringStr, 1024, kCFStringEncodingUTF8);
36    printf("OTR: %s (%ld) -- %s\n", errorDomainStr, errorCode, errorStringStr);
37    CFReleaseSafe(tempDictionary);
38}
39
40static int kTestTestCount = 18;
41static void tests(void)
42{
43    CFErrorRef testError = NULL;
44
45    SecOTRFullIdentityRef idToPurge = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError);
46    RegressionsLogError(testError);
47    CFReleaseNull(testError);
48
49    ok(idToPurge != NULL, "Make Identity");
50
51    CFMutableDataRef purgeExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
52
53    ok(SecOTRFIAppendSerialization(idToPurge, purgeExport, &testError), "First export");
54    RegressionsLogError(testError);
55    CFReleaseNull(testError);
56
57    SecOTRFullIdentityRef purgeIdInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError);
58    RegressionsLogError(testError);
59    CFReleaseNull(testError);
60
61    ok(purgeIdInflate != NULL, "Inflate Identity");
62
63    SecOTRFIPurgeFromKeychain(idToPurge, &testError);
64    RegressionsLogError(testError);
65    CFReleaseNull(testError);
66
67    SecOTRFullIdentityRef failIDInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError);
68    RegressionsLogError(testError);
69    CFReleaseNull(testError);
70
71    ok(failIDInflate == NULL, "Should fail");
72
73    CFReleaseSafe(idToPurge);
74
75
76    idToPurge = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError);
77    RegressionsLogError(testError);
78    CFReleaseNull(testError);
79
80    ok(idToPurge != NULL, "Make Identity again");
81
82    SecOTRFIPurgeAllFromKeychain(&testError);
83    RegressionsLogError(testError);
84    CFReleaseNull(testError);
85
86    SecOTRFullIdentityRef failIDInflate2 = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, purgeExport, &testError);
87    RegressionsLogError(testError);
88    CFReleaseNull(testError);
89
90    ok(failIDInflate2 == NULL, "Should fail 2");
91
92    SecOTRFullIdentityRef id = SecOTRFullIdentityCreate(kCFAllocatorDefault, &testError);
93    RegressionsLogError(testError);
94    CFReleaseNull(testError);
95
96    ok(id != NULL, "Make Identity");
97
98    CFMutableDataRef firstExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
99
100    ok(SecOTRFIAppendSerialization(id, firstExport, &testError), "First export");
101    RegressionsLogError(testError);
102    CFReleaseNull(testError);
103
104    SecOTRFullIdentityRef idInflate = SecOTRFullIdentityCreateFromData(kCFAllocatorDefault, firstExport, &testError);
105    RegressionsLogError(testError);
106    CFReleaseNull(testError);
107
108    ok(idInflate != NULL, "Inflate Identity");
109
110
111    CFMutableDataRef secondExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
112
113    ok(SecOTRFIAppendSerialization(idInflate, secondExport, &testError), "second export");
114    RegressionsLogError(testError);
115    CFReleaseNull(testError);
116
117    ok(CFDataGetLength(firstExport) == CFDataGetLength(secondExport)
118       && 0 == memcmp(CFDataGetBytePtr(firstExport), CFDataGetBytePtr(secondExport), (size_t)CFDataGetLength(firstExport)), "Different exports");
119
120    SecOTRPublicIdentityRef pubID = SecOTRPublicIdentityCopyFromPrivate(kCFAllocatorDefault, id, &testError);
121    RegressionsLogError(testError);
122    CFReleaseNull(testError);
123
124    ok(id != NULL, "Failed to copy public identity");
125
126    CFMutableDataRef firstPublicExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
127
128    ok(SecOTRPIAppendSerialization(pubID, firstPublicExport, &testError), "failed first public export");
129    RegressionsLogError(testError);
130    CFReleaseNull(testError);
131
132    SecOTRPublicIdentityRef pubIDInflate = SecOTRPublicIdentityCreateFromData(kCFAllocatorDefault, firstPublicExport, &testError);
133    RegressionsLogError(testError);
134    CFReleaseNull(testError);
135
136    ok(pubIDInflate != NULL, "Pub inflate failed");
137
138    CFMutableDataRef secondPublicExport = CFDataCreateMutable(kCFAllocatorDefault, 0);
139
140    ok(SecOTRPIAppendSerialization(pubID, secondPublicExport, &testError), "failed second public export");
141    RegressionsLogError(testError);
142    CFReleaseNull(testError);
143
144    ok(CFDataGetLength(firstPublicExport) == CFDataGetLength(secondPublicExport)
145       && 0 == memcmp(CFDataGetBytePtr(firstPublicExport), CFDataGetBytePtr(secondPublicExport), (size_t)CFDataGetLength(firstPublicExport)), "Different public exports");
146
147    uint8_t sampleByteString[] = {
148        0x30, 0x81, 0xf6, 0x81, 0x43, 0x00, 0x41, 0x04, 0xc6, 0x8a, 0x2a, 0x5c, 0x29, 0xa4, 0xb7, 0x58,
149        0xe1, 0x3c, 0x07, 0x19, 0x20, 0xf3, 0x0b, 0xb8, 0xb3, 0x40, 0x41, 0x29, 0x4a, 0xa6, 0x7a, 0x56,
150        0x28, 0x6d, 0x10, 0x85, 0x2b, 0x14, 0x83, 0xaa, 0x1f, 0x6a, 0x47, 0xbc, 0x19, 0x26, 0x39, 0x1c,
151        0xd4, 0xbb, 0x8c, 0xd6, 0x94, 0x24, 0x79, 0x60, 0xfb, 0x8e, 0x4b, 0xf4, 0x0f, 0xbf, 0x38, 0x81,
152        0x78, 0xce, 0x1d, 0xd9, 0x03, 0xec, 0x65, 0xcd, 0x82, 0x81, 0xae, 0x00, 0xac, 0x30, 0x81, 0xa9,
153        0x02, 0x81, 0xa1, 0x00, 0xd2, 0xf4, 0x40, 0x8b, 0x2f, 0x09, 0x75, 0x2c, 0x68, 0x12, 0x76, 0xb9,
154        0xfb, 0x1b, 0x02, 0x91, 0x6d, 0xd7, 0x86, 0x49, 0xdc, 0xef, 0x38, 0xf3, 0x50, 0x58, 0xb5, 0xff,
155        0x5c, 0x02, 0x8a, 0xb0, 0xcd, 0xb3, 0x3d, 0x94, 0x71, 0x7d, 0x32, 0x53, 0xed, 0x43, 0xfb, 0xde,
156        0xbc, 0x20, 0x21, 0x33, 0xe3, 0xeb, 0x93, 0x48, 0xe8, 0xd1, 0x32, 0x2f, 0x40, 0x40, 0x47, 0x1f,
157        0xeb, 0x7e, 0xf6, 0x43, 0x81, 0x51, 0xd6, 0x4f, 0xe0, 0x57, 0xbf, 0x12, 0xeb, 0x18, 0x2e, 0x81,
158        0x0b, 0x3a, 0x04, 0xf1, 0xeb, 0x3c, 0xe1, 0xb9, 0xf4, 0x87, 0x37, 0x83, 0x5a, 0x2e, 0x09, 0xf8,
159        0xd5, 0xa0, 0x12, 0xfb, 0x35, 0xe4, 0xd4, 0x3f, 0xef, 0x24, 0x3e, 0x6c, 0xff, 0xb1, 0x35, 0x7e,
160        0x9f, 0xe7, 0x6d, 0x2f, 0xf8, 0x0d, 0xc6, 0xbc, 0x19, 0xe2, 0x78, 0xb3, 0x71, 0xe1, 0x35, 0xe7,
161        0xc7, 0x22, 0x6b, 0x4d, 0x92, 0xc4, 0x10, 0x75, 0x1a, 0x9b, 0x9f, 0x7f, 0xac, 0x2d, 0xfb, 0xc9,
162        0x64, 0x1e, 0x80, 0x11, 0x7f, 0x75, 0x8a, 0x86, 0x7e, 0x09, 0x44, 0xc4, 0x71, 0xbf, 0xd4, 0xfa,
163        0x8b, 0x6a, 0xb8, 0x9f, 0x02, 0x03, 0x01, 0x00,
164        0x01};
165
166    CFDataRef testInteropImport = CFDataCreate(kCFAllocatorDefault, sampleByteString, sizeof(sampleByteString));
167    SecOTRPublicIdentityRef interopIDInflate = SecOTRPublicIdentityCreateFromData(kCFAllocatorDefault, testInteropImport, &testError);
168    RegressionsLogError(testError);
169    CFReleaseNull(testError);
170    ok(interopIDInflate != NULL, "Interop inflate failed");
171
172    /* cleanup keychain */
173    ok(SecOTRFIPurgeAllFromKeychain(&testError),"cleanup keychain");
174    RegressionsLogError(testError);
175    CFReleaseNull(testError);
176
177    CFReleaseSafe(pubID);
178    CFReleaseSafe(pubIDInflate);
179    CFReleaseSafe(firstPublicExport);
180    CFReleaseSafe(secondPublicExport);
181    CFReleaseSafe(id);
182    CFReleaseSafe(idToPurge);
183    CFReleaseSafe(idInflate);
184    CFReleaseSafe(firstExport);
185    CFReleaseSafe(secondExport);
186    CFReleaseSafe(purgeExport);
187    CFReleaseSafe(purgeIdInflate);
188    CFReleaseSafe(failIDInflate);
189    CFReleaseSafe(failIDInflate2);
190    CFReleaseSafe(testInteropImport);
191    CFReleaseSafe(interopIDInflate);
192
193}
194
195int otr_00_identity(int argc, char *const *argv)
196{
197    plan_tests(kTestTestCount);
198
199	tests();
200
201	return 0;
202}
203