]> git.saurik.com Git - apple/security.git/blob - keychain/escrowrequest/Framework/SecEscrowRequest.m
Security-59306.101.1.tar.gz
[apple/security.git] / keychain / escrowrequest / Framework / SecEscrowRequest.m
1
2 #import "keychain/escrowrequest/Framework/SecEscrowRequest.h"
3
4 #import "keychain/escrowrequest/EscrowRequestXPCProtocol.h"
5 #import "keychain/escrowrequest/EscrowRequestXPCServer.h"
6
7 #import "utilities/debugging.h"
8
9 NSString* const SecEscrowRequestHavePrecord = @"have_prerecord";
10 NSString* const SecEscrowRequestPendingPasscode = @"pending_passcode";
11 NSString* const SecEscrowRequestPendingCertificate = @"pending_certificate";
12
13 @interface SecEscrowRequest ()
14 @property NSXPCConnection *connection;
15 @end
16
17 @implementation SecEscrowRequest
18
19 + (SecEscrowRequest* _Nullable)request:(NSError* _Nullable *)error
20 {
21 NSXPCConnection* connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydEscrowRequestServiceName) options:0];
22
23 if (connection == nil) {
24 if(error) {
25 *error = [NSError errorWithDomain:@"securityd" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Couldn't create connection (no reason given)"}];
26 }
27 return nil;
28 }
29
30 NSXPCInterface *interface = SecEscrowRequestSetupControlProtocol([NSXPCInterface interfaceWithProtocol:@protocol(EscrowRequestXPCProtocol)]);
31 connection.remoteObjectInterface = interface;
32 [connection resume];
33
34 SecEscrowRequest* c = [[SecEscrowRequest alloc] initWithConnection:connection];
35 return c;
36 }
37
38 - (instancetype)initWithConnection:(NSXPCConnection*)connection {
39 if(self = [super init]) {
40 _connection = connection;
41 }
42 return self;
43 }
44
45 - (void)dealloc
46 {
47 [self.connection invalidate];
48 }
49
50 // Actual implementation
51
52 - (BOOL)triggerEscrowUpdate:(NSString*)reason error:(NSError**)error
53 {
54 __block NSError* localError = nil;
55
56 NSXPCConnection<EscrowRequestXPCProtocol>* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) {
57 localError = xpcError;
58 secnotice("escrow", "triggerEscrowUpdate: Failed to get XPC connection: %@", xpcError);
59 }];
60
61 [c triggerEscrowUpdate:reason
62 reply:^(NSError * _Nullable xpcError) {
63 localError = xpcError;
64
65 secnotice("escrow", "Triggered escrow update for '%@': %@", reason, xpcError);
66 }];
67
68 if(error && localError) {
69 *error = localError;
70 }
71
72 return localError == nil;
73 }
74
75 - (BOOL)cachePrerecord:(NSString*)uuid
76 serializedPrerecord:(NSData*)prerecord
77 error:(NSError**)error
78 {
79 __block NSError* localError = nil;
80
81 NSXPCConnection<EscrowRequestXPCProtocol>* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) {
82 localError = xpcError;
83 secnotice("escrow", "cachePrerecord: Failed to get XPC connection: %@", xpcError);
84 }];
85
86 [c cachePrerecord:uuid
87 serializedPrerecord:prerecord
88 reply:^(NSError * _Nullable xpcError) {
89 localError = xpcError;
90
91 secnotice("escrow", "Cached prerecord for %@: %@", uuid, xpcError);
92 }];
93
94 if(error && localError) {
95 *error = localError;
96 }
97
98 return localError == nil;
99 }
100
101 - (NSData* _Nullable)fetchPrerecord:(NSString*)prerecordUUID
102 error:(NSError**)error
103 {
104 __block NSError* localError = nil;
105
106 NSXPCConnection<EscrowRequestXPCProtocol>* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) {
107 localError = xpcError;
108 secnotice("escrow", "fetchprerecord: Failed to get XPC connection: %@", xpcError);
109 }];
110
111 __block NSData* prerecord = nil;
112 [c fetchPrerecord:prerecordUUID reply:^(NSData * _Nullable requestContents, NSError * _Nullable xpcError) {
113 prerecord = requestContents;
114 localError = xpcError;
115
116 secnotice("escrow", "Received prerecord for %@: %@", prerecordUUID, xpcError);
117 }];
118
119 if(error && localError) {
120 *error = localError;
121 }
122
123 return prerecord;
124 }
125
126 - (NSString* _Nullable)fetchRequestWaitingOnPasscode:(NSError**)error
127 {
128 __block NSError* localError = nil;
129
130 NSXPCConnection<EscrowRequestXPCProtocol>* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) {
131 localError = xpcError;
132 secnotice("escrow", "fetchRequestWaitingOnPasscode: Failed to get XPC connection: %@", xpcError);
133 }];
134
135 __block NSString* uuid = nil;
136 [c fetchRequestWaitingOnPasscode:^(NSString * _Nullable requestUUID, NSError * _Nullable xpcError) {
137 uuid = requestUUID;
138 localError = xpcError;
139
140 secnotice("escrow", "Received request waiting on passcode: %@ %@", requestUUID, xpcError);
141 }];
142
143 if(error && localError) {
144 *error = localError;
145 }
146
147 return uuid;
148 }
149
150 - (NSDictionary * _Nullable)fetchStatuses:(NSError**)error
151 {
152 __block NSError* localError = nil;
153 __block NSDictionary<NSString*, NSString*>* statuses = nil;
154
155 NSXPCConnection<EscrowRequestXPCProtocol>* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) {
156 localError = xpcError;
157 secnotice("escrow", "requestStatuses: Failed to get XPC connection: %@", xpcError);
158 }];
159
160 [c fetchRequestStatuses:^(NSDictionary<NSString*,NSString*> * _Nullable fetchedStatuses, NSError * _Nullable xpcError) {
161 statuses = fetchedStatuses;
162 localError = xpcError;
163
164 secnotice("escrow", "Received statuses: %@ %@", statuses, xpcError);
165 }];
166
167 if(error && localError) {
168 *error = localError;
169 }
170
171 return statuses;
172 }
173
174 - (BOOL)resetAllRequests:(NSError**)error
175 {
176 __block NSError* localError = nil;
177
178 NSXPCConnection<EscrowRequestXPCProtocol>* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) {
179 localError = xpcError;
180 secnotice("escrow", "resetAllRequests: Failed to get XPC connection: %@", xpcError);
181 }];
182
183 [c resetAllRequests:^(NSError * _Nullable xpcError) {
184 localError = xpcError;
185
186 secnotice("escrow", "resetAllRequests: %@", xpcError);
187 }];
188
189 if(error && localError) {
190 *error = localError;
191 }
192
193 return localError == nil;
194 }
195
196 - (uint64_t)storePrerecordsInEscrow:(NSError**)error
197 {
198 __block NSError* localError = nil;
199
200 NSXPCConnection<EscrowRequestXPCProtocol>* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) {
201 localError = xpcError;
202 secnotice("escrow", "fetchRequestWaitingOnPasscode: Failed to get XPC connection: %@", xpcError);
203 }];
204
205 __block uint64_t count = 0;
206 [c storePrerecordsInEscrow:^(uint64_t requestCount, NSError * _Nullable xpcError) {
207 count = requestCount;
208 localError = xpcError;
209
210 secnotice("escrow", "Stored %d records: %@", (int)requestCount, xpcError);
211 }];
212
213 if(error && localError) {
214 *error = localError;
215 }
216
217 return count;
218 }
219
220 - (bool)pendingEscrowUpload:(NSError**)error
221 {
222 NSError* localError = nil;
223
224 NSDictionary<NSString*, NSString*>* result = [self fetchStatuses:&localError];
225 if(localError) {
226 secnotice("escrow", "failed to fetch escrow statuses: %@", localError);
227 if(error) {
228 *error = localError;
229 }
230 return NO;
231 }
232 if(result == nil || (result && [result count] == 0)) {
233 return NO;
234 }
235
236 BOOL inProgress = NO;
237 for(NSString* status in result.allValues) {
238 if([status isEqualToString:SecEscrowRequestHavePrecord] ||
239 [status isEqualToString:SecEscrowRequestPendingPasscode] ||
240 [status isEqualToString:SecEscrowRequestPendingCertificate]) {
241 inProgress = YES;
242 }
243 }
244
245 return inProgress;
246 }
247
248 @end