]> git.saurik.com Git - apple/security.git/blob - KeychainCircle/Tests/KCJoiningSessionTest.m
Security-58286.1.32.tar.gz
[apple/security.git] / KeychainCircle / Tests / KCJoiningSessionTest.m
1 //
2 // KCJoiningSessionTest.m
3 // Security
4 //
5 //
6
7 #import <XCTest/XCTest.h>
8
9 #import <Foundation/Foundation.h>
10
11 #import <KeychainCircle/KCJoiningSession.h>
12 #import <KeychainCircle/KCError.h>
13 #import <KeychainCircle/NSError+KCCreationHelpers.h>
14 #import <KeychainCircle/KCAESGCMDuplexSession.h>
15
16 #include <Security/SecBase.h>
17 #include <Security/SecureObjectSync/SOSFullPeerInfo.h>
18 #include <Security/SecureObjectSync/SOSPeerInfoInternal.h>
19
20 #include <CommonCrypto/CommonRandomSPI.h>
21
22
23 __unused static SOSFullPeerInfoRef SOSNSFullPeerInfoCreate(NSDictionary* gestalt,
24 NSData* backupKey, SecKeyRef signingKey, SecKeyRef octagonSigningKey,
25 NSError**error)
26 {
27 CFErrorRef errorRef = NULL;
28
29 SOSFullPeerInfoRef result = SOSFullPeerInfoCreate(NULL, (__bridge CFDictionaryRef) gestalt, (__bridge CFDataRef) backupKey, signingKey, octagonSigningKey, &errorRef);
30
31 if (errorRef && error) {
32 *error = (__bridge_transfer NSError*) errorRef;
33 errorRef = NULL;
34 }
35
36 return result;
37 }
38
39 static SecKeyRef GenerateFullECKey_internal(int keySize, NSError** error)
40 {
41 SecKeyRef full_key = NULL;
42
43 NSDictionary* keygen_parameters = @{ (__bridge NSString*)kSecAttrKeyType:(__bridge NSString*) kSecAttrKeyTypeEC,
44 (__bridge NSString*)kSecAttrKeySizeInBits: [NSNumber numberWithInt: keySize] };
45
46
47 (void) OSStatusError(SecKeyGeneratePair((__bridge CFDictionaryRef)keygen_parameters, NULL, &full_key), error, @"Generate Key failed");
48
49 return full_key;
50 }
51
52 static SecKeyRef GenerateFullECKey(int keySize, NSError** error) {
53 return GenerateFullECKey_internal(keySize, error);
54 }
55
56
57 __unused static SOSFullPeerInfoRef SOSCreateFullPeerInfoFromName(NSString* name, SecKeyRef* outSigningKey, SecKeyRef* outOctagonSigningKey, NSError** error)
58 {
59 if (outSigningKey == NULL || outOctagonSigningKey == NULL)
60 return NULL;
61
62 *outSigningKey = GenerateFullECKey(256, error);
63 if (*outSigningKey == NULL)
64 return NULL;
65
66 *outOctagonSigningKey = GenerateFullECKey(384, error);
67 if (*outOctagonSigningKey == NULL) {
68 return NULL;
69 }
70
71 return SOSNSFullPeerInfoCreate(@{(__bridge NSString*)kPIUserDefinedDeviceNameKey:name}, nil, *outSigningKey, *outOctagonSigningKey, error);
72 }
73
74
75 @interface KCJoiningRequestTestDelegate : NSObject <KCJoiningRequestSecretDelegate, KCJoiningRequestCircleDelegate>
76 @property (readwrite) NSString* sharedSecret;
77
78 @property (readonly) NSString* accountCode;
79 @property (readonly) NSData* circleJoinData;
80 @property (readwrite) SOSPeerInfoRef peerInfo;
81
82 @property (readwrite) NSString* incorrectSecret;
83 @property (readwrite) int incorrectTries;
84
85
86 + (id) requestDelegateWithSecret:(NSString*) secret;
87 - (id) init NS_UNAVAILABLE;
88 - (id) initWithSecret: (NSString*) secret
89 incorrectSecret: (NSString*) wrongSecret
90 incorrectTries: (int) retries NS_DESIGNATED_INITIALIZER;
91 - (NSString*) secret;
92 - (NSString*) verificationFailed: (bool) codeChanged;
93 - (SOSPeerInfoRef) copyPeerInfoError: (NSError**) error;
94 - (bool) processCircleJoinData: (NSData*) circleJoinData version:(PiggyBackProtocolVersion)version error: (NSError**)error ;
95 - (bool) processAccountCode: (NSString*) accountCode error: (NSError**)error;
96
97 @end
98
99 @implementation KCJoiningRequestTestDelegate
100
101 + (id) requestDelegateWithSecret:(NSString*) secret {
102 return [[KCJoiningRequestTestDelegate alloc] initWithSecret:secret
103 incorrectSecret:@""
104 incorrectTries:0];
105 }
106
107 + (id) requestDelegateWithSecret:(NSString*) secret
108 incorrectSecret:(NSString*) wrongSecret
109 incorrectTries:(int) retries {
110 return [[KCJoiningRequestTestDelegate alloc] initWithSecret:secret
111 incorrectSecret:wrongSecret
112 incorrectTries:retries];
113 }
114
115
116 - (id) initWithSecret: (NSString*) secret
117 incorrectSecret: (NSString*) incorrectSecret
118 incorrectTries: (int) retries {
119 self = [super init];
120
121 SecKeyRef signingKey = GenerateFullECKey(256, NULL);
122 SecKeyRef octagonSigningKey = GenerateFullECKey(384, NULL);
123
124 self.peerInfo = SOSPeerInfoCreate(NULL, (__bridge CFDictionaryRef) @{(__bridge NSString*)kPIUserDefinedDeviceNameKey:@"Fakey"}, NULL, signingKey, octagonSigningKey, NULL);
125
126 if (self.peerInfo == NULL)
127 return nil;
128
129 self.sharedSecret = secret;
130 self.incorrectSecret = incorrectSecret;
131 self.incorrectTries = retries;
132
133 return self;
134 }
135
136 - (NSString*) nextSecret {
137 if (self.incorrectTries > 0) {
138 self.incorrectTries -= 1;
139 return self.incorrectSecret;
140 }
141 return self.sharedSecret;
142 }
143
144 - (NSString*) secret {
145 return [self nextSecret];
146 }
147
148 - (NSString*) verificationFailed: (bool) codeChanged {
149 return [self nextSecret];
150 }
151
152 - (SOSPeerInfoRef) copyPeerInfoError: (NSError**) error {
153 return self.peerInfo;
154 }
155
156 - (bool) processCircleJoinData: (NSData*) circleJoinData version:(PiggyBackProtocolVersion)version error: (NSError**)error {
157 self->_circleJoinData = circleJoinData;
158 return true;
159 }
160
161 - (bool) processAccountCode: (NSString*) accountCode error: (NSError**)error {
162 self->_accountCode = accountCode;
163 return true;
164 }
165
166 @end
167
168 @interface KCJoiningAcceptTestDelegate : NSObject <KCJoiningAcceptSecretDelegate, KCJoiningAcceptCircleDelegate>
169 @property (readonly) NSArray<NSString*>* secrets;
170 @property (readwrite) NSUInteger currentSecret;
171 @property (readwrite) int retriesLeft;
172 @property (readwrite) int retriesPerSecret;
173
174 @property (readonly) NSString* codeToUse;
175 @property (readonly) NSData* circleJoinData;
176 @property (readonly) SOSPeerInfoRef peerInfo;
177
178 + (id) acceptDelegateWithSecret: (NSString*) secret code: (NSString*) code;
179 + (id) acceptDelegateWithSecrets: (NSArray<NSString*>*) secrets retries: (int) retries code: (NSString*) code;
180 - (id) initWithSecrets: (NSArray<NSString*>*) secrets retries: (int) retries code: (NSString*) code NS_DESIGNATED_INITIALIZER;
181
182
183 - (NSString*) secret;
184 - (NSString*) accountCode;
185
186 - (KCRetryOrNot) verificationFailed: (NSError**) error;
187 - (NSData*) circleJoinDataFor: (SOSPeerInfoRef) peer
188 error: (NSError**) error;
189
190 - (id) init NS_UNAVAILABLE;
191
192 @end
193
194 @implementation KCJoiningAcceptTestDelegate
195
196 + (id) acceptDelegateWithSecrets: (NSArray<NSString*>*) secrets retries: (int) retries code: (NSString*) code {
197 return [[KCJoiningAcceptTestDelegate alloc] initWithSecrets:secrets retries:retries code:code];
198
199 }
200
201 + (id) acceptDelegateWithSecret: (NSString*) secret code: (NSString*) code {
202 return [[KCJoiningAcceptTestDelegate alloc] initWithSecret:secret code:code];
203 }
204
205 - (id) initWithSecret: (NSString*) secret code: (NSString*) code {
206 return [self initWithSecrets:@[secret] retries:3 code:code];
207 }
208
209 - (id) initWithSecrets: (NSArray<NSString*>*) secrets retries: (int) retries code: (NSString*) code {
210 self = [super init];
211
212 self->_secrets = secrets;
213 self.currentSecret = 0;
214 self->_retriesPerSecret = retries;
215 self->_retriesLeft = self.retriesPerSecret;
216
217 self->_codeToUse = code;
218
219 uint8_t joinDataBuffer[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
220 self->_circleJoinData = [NSData dataWithBytes: joinDataBuffer length: sizeof(joinDataBuffer) ];
221
222 return self;
223 }
224
225 - (KCRetryOrNot) advanceSecret {
226 if (self.retriesLeft == 0) {
227 self.currentSecret += 1;
228 if (self.currentSecret >= [self.secrets count]) {
229 self.currentSecret = [self.secrets count] - 1;
230 }
231 self.retriesLeft = self.retriesPerSecret;
232 return kKCRetryWithNewChallenge;
233 } else {
234 self.retriesLeft -= 1;
235 return kKCRetryWithSameChallenge;
236 }
237 }
238
239 - (NSString*) secret {
240 return self.secrets[self.currentSecret];
241 }
242 - (NSString*) accountCode {
243 return self.codeToUse;
244 }
245
246 - (KCRetryOrNot) verificationFailed: (NSError**) error {
247 return [self advanceSecret];
248 }
249
250 - (NSData*) circleJoinDataFor: (SOSPeerInfoRef) peer
251 error: (NSError**) error {
252 uint8_t joinDataBuffer[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
253
254 self->_peerInfo = peer;
255 return [NSData dataWithBytes: joinDataBuffer length: sizeof(joinDataBuffer) ];
256 }
257
258 -(NSData*) circleGetInitialSyncViews: (NSError**) error{
259 return [NSData data];
260 }
261
262 @end
263
264
265 @interface KCJoiningSessionTest : XCTestCase
266
267 @end
268
269 @implementation KCJoiningSessionTest
270
271 - (void)setUp {
272 [super setUp];
273 // Put setup code here. This method is called before the invocation of each test method in the class.
274 }
275
276 - (void)tearDown {
277 // Put teardown code here. This method is called after the invocation of each test method in the class.
278 [super tearDown];
279 }
280
281 - (void)testJoiningSession {
282 NSError* error = nil;
283
284 NSString* secret = @"123456";
285 NSString* code = @"987654";
286
287 uint64_t dsid = 0x1234567887654321;
288
289 KCJoiningRequestTestDelegate* requestDelegate = [KCJoiningRequestTestDelegate requestDelegateWithSecret: secret];
290 KCJoiningRequestSecretSession *requestSession = [[KCJoiningRequestSecretSession alloc] initWithSecretDelegate:requestDelegate
291 dsid:dsid
292 rng:ccDRBGGetRngState()
293 error:&error];
294
295 NSData* initialMessage = [requestSession initialMessage: &error];
296
297 XCTAssertNotNil(initialMessage, @"No initial message");
298 XCTAssertNil(error, @"Got error %@", error);
299
300 KCJoiningAcceptTestDelegate* acceptDelegate = [KCJoiningAcceptTestDelegate acceptDelegateWithSecret:secret code:code];
301 KCJoiningAcceptSession* acceptSession = [[KCJoiningAcceptSession alloc] initWithSecretDelegate:acceptDelegate
302 circleDelegate:acceptDelegate
303 dsid:dsid
304 rng:ccDRBGGetRngState()
305 error:&error];
306
307 error = nil;
308 NSData* challenge = [acceptSession processMessage: initialMessage error: &error];
309
310 XCTAssertNotNil(challenge, @"No initial message");
311 XCTAssertNil(error, @"Got error %@", error);
312
313 error = nil;
314 NSData* response = [requestSession processMessage: challenge error: &error];
315
316 XCTAssertNotNil(response, @"No response message");
317 XCTAssertNil(error, @"Got error %@", error);
318
319 error = nil;
320 NSData* verification = [acceptSession processMessage: response error: &error];
321
322 XCTAssertNotNil(verification, @"No verification message");
323 XCTAssertNil(error, @"Got error %@", error);
324
325 error = nil;
326 NSData* doneMessage = [requestSession processMessage: verification error: &error];
327
328 XCTAssertNotNil(doneMessage, @"No response message");
329 XCTAssertNil(error, @"Got error %@", error);
330
331 XCTAssertTrue([requestSession isDone], @"SecretSession done");
332 XCTAssertFalse([acceptSession isDone], @"Unexpected accept session done");
333
334 KCAESGCMDuplexSession* aesSession = [requestSession session];
335 requestSession = nil;
336
337 KCJoiningRequestCircleSession* requestSecretSession = [KCJoiningRequestCircleSession sessionWithCircleDelegate:requestDelegate session:aesSession error:&error];
338
339 XCTAssertNotNil(requestSecretSession, @"No request secret session");
340 XCTAssertNil(error, @"Got error %@", error);
341
342 error = nil;
343 NSData* peerInfoMessage = [requestSecretSession initialMessage: &error];
344
345 XCTAssertNotNil(peerInfoMessage, @"No peerInfo message");
346 XCTAssertNil(error, @"Got error %@", error);
347
348 XCTAssertEqualObjects(requestDelegate.accountCode, acceptDelegate.codeToUse, @"Code made it");
349
350 error = nil;
351 NSData* blobMessage = [acceptSession processMessage:peerInfoMessage error: &error];
352
353 XCTAssertNotNil(blobMessage, @"No blob message");
354 XCTAssertNil(error, @"Got error %@", error);
355
356 // We have different peer_info types due to wierd linking of our tests.
357 // Compare the der representations:
358 NSData* rp_der = requestDelegate.peerInfo != nil ? (__bridge_transfer NSData*) SOSPeerInfoCopyEncodedData(requestDelegate.peerInfo, NULL, NULL) : nil;
359 NSData* ap_der = acceptDelegate.peerInfo != nil ? (__bridge_transfer NSData*) SOSPeerInfoCopyEncodedData(acceptDelegate.peerInfo, NULL, NULL) : nil;
360
361 XCTAssertEqualObjects(rp_der, ap_der, @"Peer infos match");
362
363 error = nil;
364 NSData* nothing = [requestSecretSession processMessage:blobMessage error: &error];
365
366 XCTAssertEqualObjects(requestDelegate.circleJoinData, acceptDelegate.circleJoinData);
367
368 XCTAssertNotNil(nothing, @"No initial message");
369 XCTAssertNil(error, @"Got error %@", error);
370
371 XCTAssertTrue([requestSecretSession isDone], @"requesor done");
372 XCTAssertTrue([acceptSession isDone], @"acceptor done");
373
374 }
375
376 - (void)testJoiningSessionRetry {
377 NSError* error = nil;
378
379 NSString* secret = @"123456";
380 NSString* code = @"987654";
381
382 uint64_t dsid = 0x1234567887654321;
383
384 KCJoiningRequestTestDelegate* requestDelegate = [KCJoiningRequestTestDelegate requestDelegateWithSecret: secret incorrectSecret:@"777888" incorrectTries:3];
385 KCJoiningRequestSecretSession *requestSession = [[KCJoiningRequestSecretSession alloc] initWithSecretDelegate:requestDelegate
386 dsid:dsid
387 rng:ccDRBGGetRngState()
388 error:&error];
389
390 NSData* initialMessage = [requestSession initialMessage: &error];
391
392 XCTAssertNotNil(initialMessage, @"No initial message");
393 XCTAssertNil(error, @"Got error %@", error);
394
395 KCJoiningAcceptTestDelegate* acceptDelegate = [KCJoiningAcceptTestDelegate acceptDelegateWithSecret:secret code:code];
396 KCJoiningAcceptSession* acceptSession = [[KCJoiningAcceptSession alloc] initWithSecretDelegate:acceptDelegate
397 circleDelegate:acceptDelegate
398 dsid:dsid
399 rng:ccDRBGGetRngState()
400 error:&error];
401
402 error = nil;
403 NSData* challenge = [acceptSession processMessage: initialMessage error: &error];
404
405 XCTAssertNotNil(challenge, @"No initial message");
406 XCTAssertNil(error, @"Got error %@", error);
407
408 NSData* response = nil;
409 NSData* verification = nil;
410
411 NSData* nextChallenge = challenge;
412 for (int tries = 0; tries < 4; ++tries) {
413 error = nil;
414 response = [requestSession processMessage: nextChallenge error: &error];
415
416 XCTAssertNotNil(response, @"No response message");
417 XCTAssertNil(error, @"Got error %@", error);
418
419 XCTAssertNotEqualObjects(requestDelegate.accountCode, acceptDelegate.codeToUse, @"Code should not make it");
420
421 error = nil;
422 verification = [acceptSession processMessage: response error: &error];
423
424 XCTAssertNotNil(verification, @"No verification message");
425 XCTAssertNil(error, @"Got error %@", error);
426
427 nextChallenge = verification;
428 }
429
430 error = nil;
431 NSData* doneMessage = [requestSession processMessage: verification error: &error];
432
433 XCTAssertNotNil(doneMessage, @"No response message");
434 XCTAssertNil(error, @"Got error %@", error);
435
436 XCTAssertTrue([requestSession isDone], @"SecretSession done");
437 XCTAssertFalse([acceptSession isDone], @"Unexpected accept session done");
438
439 KCAESGCMDuplexSession* aesSession = [requestSession session];
440 requestSession = nil;
441
442 error = nil;
443 KCJoiningRequestCircleSession* requestSecretSession = [KCJoiningRequestCircleSession sessionWithCircleDelegate:requestDelegate session:aesSession error:&error];
444
445 XCTAssertNotNil(requestSecretSession, @"No request secret session");
446 XCTAssertNil(error, @"Got error %@", error);
447
448 error = nil;
449 NSData* peerInfoMessage = [requestSecretSession initialMessage: &error];
450
451 XCTAssertNotNil(peerInfoMessage, @"No peerInfo message");
452 XCTAssertNil(error, @"Got error %@", error);
453
454 XCTAssertEqualObjects(requestDelegate.accountCode, acceptDelegate.codeToUse, @"Code made it");
455
456 error = nil;
457 NSData* blobMessage = [acceptSession processMessage:peerInfoMessage error: &error];
458
459 XCTAssertNotNil(blobMessage, @"No blob message");
460 XCTAssertNil(error, @"Got error %@", error);
461
462 // We have different peer_info types due to wierd linking of our tests.
463 // Compare the der representations:
464 NSData* rp_der = requestDelegate.peerInfo != nil ? (__bridge_transfer NSData*) SOSPeerInfoCopyEncodedData(requestDelegate.peerInfo, NULL, NULL) : nil;
465 NSData* ap_der = acceptDelegate.peerInfo != nil ? (__bridge_transfer NSData*) SOSPeerInfoCopyEncodedData(acceptDelegate.peerInfo, NULL, NULL) : nil;
466
467 XCTAssertEqualObjects(rp_der, ap_der, @"Peer infos match");
468
469 error = nil;
470 NSData* nothing = [requestSecretSession processMessage:blobMessage error: &error];
471
472 XCTAssertEqualObjects(requestDelegate.circleJoinData, acceptDelegate.circleJoinData);
473
474 XCTAssertNotNil(nothing, @"No initial message");
475 XCTAssertNil(error, @"Got error %@", error);
476
477 XCTAssertTrue([requestSecretSession isDone], @"requesor done");
478 XCTAssertTrue([acceptSession isDone], @"acceptor done");
479
480 }
481
482 - (void)testJoiningSessionCodeChange {
483 NSError* error = nil;
484
485 NSString* secret = @"123456";
486 NSString* code = @"987654";
487
488 uint64_t dsid = 0x1234567887654321;
489
490 KCJoiningRequestTestDelegate* requestDelegate = [KCJoiningRequestTestDelegate requestDelegateWithSecret: secret];
491 KCJoiningRequestSecretSession *requestSession = [[KCJoiningRequestSecretSession alloc] initWithSecretDelegate:requestDelegate
492 dsid:dsid
493 rng:ccDRBGGetRngState()
494 error:&error];
495
496 NSData* initialMessage = [requestSession initialMessage: &error];
497
498 XCTAssertNotNil(initialMessage, @"No initial message");
499 XCTAssertNil(error, @"Got error %@", error);
500
501 KCJoiningAcceptTestDelegate* acceptDelegate = [KCJoiningAcceptTestDelegate acceptDelegateWithSecrets:@[@"222222", @"3333333", secret] retries:1 code:code];
502 KCJoiningAcceptSession* acceptSession = [[KCJoiningAcceptSession alloc] initWithSecretDelegate:acceptDelegate
503 circleDelegate:acceptDelegate
504 dsid:dsid
505 rng:ccDRBGGetRngState()
506 error:&error];
507
508 error = nil;
509 NSData* challenge = [acceptSession processMessage: initialMessage error: &error];
510
511 XCTAssertNotNil(challenge, @"No initial message");
512 XCTAssertNil(error, @"Got error %@", error);
513
514 NSData* response = nil;
515 NSData* verification = nil;
516
517 NSData* nextChallenge = challenge;
518 for (int tries = 0; tries < 5; ++tries) {
519 error = nil;
520 response = [requestSession processMessage: nextChallenge error: &error];
521
522 XCTAssertNotNil(response, @"No response message");
523 XCTAssertNil(error, @"Got error %@", error);
524
525 XCTAssertNotEqualObjects(requestDelegate.accountCode, acceptDelegate.codeToUse, @"Code should not make it");
526
527 error = nil;
528 verification = [acceptSession processMessage: response error: &error];
529
530 XCTAssertNotNil(verification, @"No verification message");
531 XCTAssertNil(error, @"Got error %@", error);
532
533 nextChallenge = verification;
534 }
535
536 error = nil;
537 NSData* doneMessage = [requestSession processMessage: verification error: &error];
538
539 XCTAssertNotNil(doneMessage, @"No response message");
540 XCTAssertNil(error, @"Got error %@", error);
541
542 XCTAssertTrue([requestSession isDone], @"SecretSession done");
543 XCTAssertFalse([acceptSession isDone], @"Unexpected accept session done");
544
545 KCAESGCMDuplexSession* aesSession = [requestSession session];
546 requestSession = nil;
547
548 error = nil;
549 KCJoiningRequestCircleSession* requestSecretSession = [KCJoiningRequestCircleSession sessionWithCircleDelegate:requestDelegate session:aesSession error:&error];
550
551 XCTAssertNotNil(requestSecretSession, @"No request secret session");
552 XCTAssertNil(error, @"Got error %@", error);
553
554 error = nil;
555 NSData* peerInfoMessage = [requestSecretSession initialMessage: &error];
556
557 XCTAssertNotNil(peerInfoMessage, @"No peerInfo message");
558 XCTAssertNil(error, @"Got error %@", error);
559
560 XCTAssertEqualObjects(requestDelegate.accountCode, acceptDelegate.codeToUse, @"Code made it");
561
562 error = nil;
563 NSData* blobMessage = [acceptSession processMessage:peerInfoMessage error: &error];
564
565 XCTAssertNotNil(blobMessage, @"No blob message");
566 XCTAssertNil(error, @"Got error %@", error);
567
568 // We have different peer_info types due to wierd linking of our tests.
569 // Compare the der representations:
570 NSData* rp_der = requestDelegate.peerInfo != nil ? (__bridge_transfer NSData*) SOSPeerInfoCopyEncodedData(requestDelegate.peerInfo, NULL, NULL) : nil;
571 NSData* ap_der = acceptDelegate.peerInfo != nil ? (__bridge_transfer NSData*) SOSPeerInfoCopyEncodedData(acceptDelegate.peerInfo, NULL, NULL) : nil;
572
573 XCTAssertEqualObjects(rp_der, ap_der, @"Peer infos match");
574
575 error = nil;
576 NSData* nothing = [requestSecretSession processMessage:blobMessage error: &error];
577
578 XCTAssertEqualObjects(requestDelegate.circleJoinData, acceptDelegate.circleJoinData);
579
580 XCTAssertNotNil(nothing, @"No initial message");
581 XCTAssertNil(error, @"Got error %@", error);
582
583 XCTAssertTrue([requestSecretSession isDone], @"requesor done");
584 XCTAssertTrue([acceptSession isDone], @"acceptor done");
585
586 }
587
588 @end