2 // sc-75-circle-engine.c
5 // Created by Michael Brouwer on 9/24/12.
6 // Copyright 2012 Apple Inc. All rights reserved.
9 #include <SecureObjectSync/SOSEngine.h>
10 #include <SecureObjectSync/SOSPeer.h>
12 #include "SOSCircle_regressions.h"
14 #include <corecrypto/ccsha2.h>
16 #include <utilities/SecCFWrappers.h>
20 #include <AssertMacros.h>
25 #include <CoreFoundation/CFDate.h>
27 #include <utilities/SecCFWrappers.h>
29 #include <Security/SecKey.h>
31 #include <SecureObjectSync/SOSPeerInfo.h>
32 #include <SecureObjectSync/SOSCircle.h>
33 #include <SecureObjectSync/SOSCloudCircle.h>
34 #include <SecureObjectSync/SOSInternal.h>
35 #include <SecureObjectSync/SOSUserKeygen.h>
37 #include "SOSCircle_regressions.h"
38 #include "SOSRegressionUtilities.h"
39 #include "SOSTestDataSource.h"
41 #ifndef SEC_CONST_DECL
42 #define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
45 #include <securityd/SOSCloudCircleServer.h>
48 // MARK: ----- Constants -----
50 static CFStringRef circleKey
= CFSTR("Circle");
52 static int kTestTestCount
= 22;
56 CFErrorRef error
= NULL
;
58 CFStringRef aliceID
= CFSTR("Alice");
59 CFStringRef bobID
= CFSTR("Bob"); // not really remote, just another client on same machine
61 SecKeyRef alice_key
= NULL
;
62 SecKeyRef bob_key
= NULL
;
64 CFDataRef cfpassword
= CFDataCreate(NULL
, (uint8_t *) "FooFooFoo", 10);
66 CFDataRef parameters
= SOSUserKeyCreateGenerateParameters(&error
);
67 ok(parameters
, "No parameters!");
68 ok(error
== NULL
, "Error: (%@)", error
);
71 SecKeyRef user_privkey
= SOSUserKeygen(cfpassword
, parameters
, &error
);
72 CFReleaseNull(parameters
);
73 CFReleaseSafe(cfpassword
);
75 CFStringRef circleName
= CFSTR("Woot Circle");
77 SOSFullPeerInfoRef alice_full_peer_info
= SOSCreateFullPeerInfoFromName(aliceID
, &alice_key
, &error
);
78 SOSPeerInfoRef alice_peer_info
= SOSFullPeerInfoGetPeerInfo(alice_full_peer_info
);
80 SOSFullPeerInfoRef bob_full_peer_info
= SOSCreateFullPeerInfoFromName(bobID
, &bob_key
, &error
);
81 SOSPeerInfoRef bob_peer_info
= SOSFullPeerInfoGetPeerInfo(bob_full_peer_info
);
83 SOSCircleRef aliceCircle
= SOSCircleCreate(kCFAllocatorDefault
, circleName
, &error
);
85 ok(SOSCircleRequestAdmission(aliceCircle
, user_privkey
, alice_full_peer_info
, &error
));
86 ok(SOSCircleAcceptRequests(aliceCircle
, user_privkey
, alice_full_peer_info
, NULL
));
87 ok(SOSCircleRequestAdmission(aliceCircle
, user_privkey
, bob_full_peer_info
, &error
), "requested admission");
88 ok(SOSCircleAcceptRequests(aliceCircle
, user_privkey
, bob_full_peer_info
, &error
), "accepted them all!");
90 alice_peer_info
= SOSFullPeerInfoGetPeerInfo(alice_full_peer_info
);
91 bob_peer_info
= SOSFullPeerInfoGetPeerInfo(bob_full_peer_info
);
93 CFDataRef aliceCircleEncoded
;
94 ok(aliceCircleEncoded
= SOSCircleCopyEncodedData(aliceCircle
, kCFAllocatorDefault
, &error
), "encode alice circle: %@", error
);
96 SOSCircleRef bobCircle
;
97 ok(bobCircle
= SOSCircleCreateFromData(0, aliceCircleEncoded
, &error
), "decode bobCircle: %@", error
);
98 CFReleaseNull(aliceCircleEncoded
);
102 __block CFDataRef queued_message
= NULL
;
104 SOSPeerSendBlock enqueueMessage
= ^bool (CFDataRef message
, CFErrorRef
*error
) {
106 fail("We already had an unproccessed message");
108 queued_message
= (CFDataRef
) CFRetain(message
);
112 CFDataRef (^dequeueMessage
)() = ^CFDataRef () {
113 CFDataRef result
= queued_message
;
114 queued_message
= NULL
;
120 SOSDataSourceRef aliceDs
= SOSTestDataSourceCreate();
121 SOSDataSourceRef bobDs
= SOSTestDataSourceCreate();
123 SOSDataSourceFactoryRef aliceDsf
= SOSTestDataSourceFactoryCreate();
124 SOSTestDataSourceFactoryAddDataSource(aliceDsf
, circleName
, aliceDs
);
126 SOSDataSourceFactoryRef bobDsf
= SOSTestDataSourceFactoryCreate();
127 SOSTestDataSourceFactoryAddDataSource(bobDsf
, circleName
, bobDs
);
129 /* Test passing peer messages to the engine. */
132 CFStringRef bob_peer_id
= SOSPeerInfoGetPeerID(bob_peer_info
);
134 /* Hand an empty message to the engine for handeling. */
135 message
= CFDataCreate(NULL
, NULL
, 0);
136 is(SOSCircleHandlePeerMessage(aliceCircle
, alice_full_peer_info
, aliceDsf
, enqueueMessage
, bob_peer_id
, message
, &error
), false,
137 "empty message rejected, %@", error
);
139 CFReleaseNull(error
);
140 CFReleaseNull(message
);
142 ok(SOSCircleSyncWithPeer(alice_full_peer_info
, aliceCircle
, aliceDsf
, enqueueMessage
, bob_peer_id
, &error
), "Start sync [error %@]", error
);
143 CFReleaseNull(error
);
145 ok(message
= dequeueMessage(), "Alice sent message");
146 CFStringRef alice_peer_id
= SOSPeerInfoGetPeerID(alice_peer_info
);
147 is(SOSCircleHandlePeerMessage(bobCircle
, bob_full_peer_info
, bobDsf
, enqueueMessage
, alice_peer_id
, message
, &error
), true,
148 "Bob accepted message: %@", error
);
149 CFReleaseNull(message
);
152 CFStringRef desc
= NULL
;
153 ok(message
= dequeueMessage(), "we got a message from Bob %@", desc
= SOSMessageCopyDescription(message
));
154 ok(SOSCircleHandlePeerMessage(aliceCircle
, alice_full_peer_info
, aliceDsf
, enqueueMessage
, bob_peer_id
, message
, &error
),
155 "Alice accepted message: %@", error
);
156 CFReleaseNull(message
);
159 ok(message
= dequeueMessage(), "we got a reply from Alice %@", desc
= SOSMessageCopyDescription(message
));
160 ok(SOSCircleHandlePeerMessage(bobCircle
, bob_full_peer_info
, bobDsf
, enqueueMessage
, alice_peer_id
, message
, &error
),
161 "Bob accepted message: %@", error
);
162 CFReleaseNull(message
);
167 message
= dequeueMessage();
168 ok(NULL
== message
, "we got no message from Bob %@", desc
= SOSMessageCopyDescription(message
));
170 SOSObjectRef object
= SOSDataSourceCreateGenericItem(aliceDs
, CFSTR("75_circle_engine_account"), CFSTR("test service"));
171 ok(SOSTestDataSourceAddObject(aliceDs
, object
, &error
), "add empty object to datasource: %@", error
);
172 CFReleaseNull(error
);
173 CFReleaseNull(object
);
175 ok(SOSCircleSyncWithPeer(alice_full_peer_info
, aliceCircle
, aliceDsf
, enqueueMessage
, bob_peer_id
, &error
), "Restart sync [error %@]", error
);
176 CFReleaseNull(error
);
178 ok(message
= dequeueMessage(), "Alice started again %@", desc
= SOSMessageCopyDescription(message
));
179 is(SOSCircleHandlePeerMessage(bobCircle
, bob_full_peer_info
, bobDsf
, enqueueMessage
, alice_peer_id
, message
, &error
), true,
180 "bob accepted %@: %@", SOSMessageCopyDescription(message
), error
);
181 CFReleaseNull(error
);
182 CFReleaseNull(message
);
188 while (max_loops
-- && NULL
!= (message
= dequeueMessage())) {
190 ok(SOSCircleHandlePeerMessage(aliceCircle
, alice_full_peer_info
, aliceDsf
, enqueueMessage
, bob_peer_id
, message
, &error
),
191 "alice accepted %@: %@", desc
= SOSMessageCopyDescription(message
), error
);
193 ok(SOSCircleHandlePeerMessage(bobCircle
, bob_full_peer_info
, bobDsf
, enqueueMessage
, alice_peer_id
, message
, &error
),
194 "bob accepted %@: %@", desc
= SOSMessageCopyDescription(message
), error
);
202 CFReleaseNull(aliceCircle
);
203 CFReleaseNull(bobCircle
);
205 CFReleaseNull(alice_peer_info
);
206 CFReleaseNull(bob_peer_info
);
208 CFReleaseNull(alice_key
);
209 CFReleaseNull(bob_key
);
210 aliceDsf
->release(aliceDsf
);
211 bobDsf
->release(bobDsf
);
214 // MARK: ----- start of all tests -----
216 int sc_75_circle_engine(int argc
, char *const *argv
)
218 plan_tests(kTestTestCount
);