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