]> git.saurik.com Git - apple/security.git/blob - keychain/ckks/tests/CKKSTests+LockStateTracker.m
Security-59754.80.3.tar.gz
[apple/security.git] / keychain / ckks / tests / CKKSTests+LockStateTracker.m
1 #if OCTAGON
2
3 #import <XCTest/XCTest.h>
4 #import <OCMock/OCMock.h>
5
6 #import "keychain/ckks/CKKSLockStateTracker.h"
7 #import "tests/secdmockaks/mockaks.h"
8
9 @interface CKKSTests_LockStateTracker : XCTestCase
10 @property bool aksLockState;
11 @property (nullable) id mockLockStateTracker;
12 @property CKKSLockStateTracker* lockStateTracker;
13 @end
14
15 @implementation CKKSTests_LockStateTracker
16
17 @synthesize aksLockState = _aksLockState;
18
19 - (void)setUp {
20 [super setUp];
21
22 self.aksLockState = false; // Lie and say AKS is always unlocked
23 self.mockLockStateTracker = OCMClassMock([CKKSLockStateTracker class]);
24 OCMStub([self.mockLockStateTracker queryAKSLocked]).andCall(self, @selector(aksLockState));
25
26 self.lockStateTracker = [[CKKSLockStateTracker alloc] init];
27
28
29 [SecMockAKS reset];
30 }
31
32 - (void)tearDown {
33 [self.mockLockStateTracker stopMocking];
34 self.lockStateTracker = nil;
35 }
36
37 - (bool)aksLockState
38 {
39 return _aksLockState;
40 }
41
42 - (void)setAksLockState:(bool)aksLockState
43 {
44
45 if(aksLockState) {
46 [SecMockAKS lockClassA];
47 } else {
48 [SecMockAKS unlockAllClasses];
49 }
50 _aksLockState = aksLockState;
51 }
52
53 - (void)testLockedBehindOurBack {
54
55 /*
56 * check that we detect that lock errors force a recheck
57 */
58
59 NSError *lockError = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecInteractionNotAllowed userInfo:nil];
60 NSError *fileError = [NSError errorWithDomain:NSOSStatusErrorDomain code:ENOENT userInfo:nil];
61
62 XCTAssertFalse([self.lockStateTracker isLocked], "should start out unlocked");
63 XCTAssertTrue([self.lockStateTracker isLockedError:lockError], "errSecInteractionNotAllowed is a lock errors");
64 XCTAssertFalse([self.lockStateTracker isLocked], "should be unlocked after lock failure");
65
66 XCTAssertFalse([self.lockStateTracker isLockedError:fileError], "file errors are not lock errors");
67 XCTAssertFalse([self.lockStateTracker isLocked], "should be unlocked after lock failure");
68
69 self.aksLockState = true;
70 XCTAssertFalse([self.lockStateTracker isLocked], "should be reporting unlocked since we 'missed' the notification");
71
72 XCTAssertFalse([self.lockStateTracker isLockedError:fileError], "file errors are not lock errors");
73 XCTAssertFalse([self.lockStateTracker isLocked], "should be 'unlocked' after file errors");
74
75 XCTAssertTrue([self.lockStateTracker isLockedError:lockError], "errSecInteractionNotAllowed is a lock errors");
76 XCTAssertTrue([self.lockStateTracker isLocked], "should be locked after lock failure");
77
78 self.aksLockState = false;
79 [self.lockStateTracker recheck];
80
81 XCTAssertFalse([self.lockStateTracker isLocked], "should be unlocked");
82 }
83
84 - (void)testWaitForUnlock {
85
86 self.aksLockState = true;
87 [self.lockStateTracker recheck];
88
89 XCTestExpectation* expectation = [self expectationWithDescription: @"unlock occurs"];
90
91 NSBlockOperation *unlockEvent = [NSBlockOperation blockOperationWithBlock:^{
92 [expectation fulfill];
93 }];
94 [unlockEvent addDependency:[self.lockStateTracker unlockDependency]];
95 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
96
97 [queue addOperation:unlockEvent];
98
99 self.aksLockState = false;
100 [self.lockStateTracker recheck];
101
102 [self waitForExpectations:@[expectation] timeout:5];
103
104 }
105
106
107 @end
108
109 #endif /* OCTAGON */