2 * Copyright (c) 2016 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
27 #include <ipc/securityd_client.h>
28 #include <utilities/SecDb.h>
29 #include <utilities/SecCFWrappers.h>
30 #include <dispatch/dispatch.h>
34 #import <Foundation/Foundation.h>
36 typedef NS_ENUM(NSUInteger
, SecCKKSItemEncryptionVersion
) {
37 CKKSItemEncryptionVersionNone
= 0, // No encryption present
38 CKKSItemEncryptionVersion1
= 1, // Current version, AES-SIV 512, not all fields authenticated
39 CKKSItemEncryptionVersion2
= 2, // Seed3 version, AES-SIV 512, all fields (including unknown fields) authenticated
42 extern const SecCKKSItemEncryptionVersion currentCKKSItemEncryptionVersion
;
45 extern NSString
* const SecCKKSActionAdd
;
46 extern NSString
* const SecCKKSActionDelete
;
47 extern NSString
* const SecCKKSActionModify
;
50 @protocol SecCKKSItemState
52 typedef NSString
<SecCKKSItemState
> CKKSItemState
;
53 extern CKKSItemState
* const SecCKKSStateNew
;
54 extern CKKSItemState
* const SecCKKSStateUnauthenticated
;
55 extern CKKSItemState
* const SecCKKSStateInFlight
;
56 extern CKKSItemState
* const SecCKKSStateReencrypt
;
57 extern CKKSItemState
* const SecCKKSStateError
;
58 extern CKKSItemState
* const SecCKKSStateDeleted
; // meta-state: please delete this item!
60 /* Processed States */
61 @protocol SecCKKSProcessedState
63 typedef NSString
<SecCKKSProcessedState
> CKKSProcessedState
;
64 extern CKKSProcessedState
* const SecCKKSProcessedStateLocal
;
65 extern CKKSProcessedState
* const SecCKKSProcessedStateRemote
;
68 @protocol SecCKKSKeyClass
70 typedef NSString
<SecCKKSKeyClass
> CKKSKeyClass
;
71 extern CKKSKeyClass
* const SecCKKSKeyClassTLK
;
72 extern CKKSKeyClass
* const SecCKKSKeyClassA
;
73 extern CKKSKeyClass
* const SecCKKSKeyClassC
;
75 /* Useful CloudKit configuration */
76 extern NSString
* const SecCKKSContainerName
;
77 extern bool SecCKKSContainerUsePCS
;
78 extern NSString
* const SecCKKSSubscriptionID
;
79 extern NSString
* const SecCKKSAPSNamedPort
;
82 extern NSString
* const SecCKRecordItemType
;
83 extern NSString
* const SecCKRecordVersionKey
;
84 extern NSString
* const SecCKRecordEncryptionVersionKey
;
85 extern NSString
* const SecCKRecordParentKeyRefKey
;
86 extern NSString
* const SecCKRecordDataKey
;
87 extern NSString
* const SecCKRecordWrappedKeyKey
;
88 extern NSString
* const SecCKRecordGenerationCountKey
;
89 extern NSString
* const SecCKRecordPCSServiceIdentifier
;
90 extern NSString
* const SecCKRecordPCSPublicKey
;
91 extern NSString
* const SecCKRecordPCSPublicIdentity
;
92 extern NSString
* const SecCKRecordServerWasCurrent
;
94 /* Intermediate Key CKRecord Keys */
95 extern NSString
* const SecCKRecordIntermediateKeyType
;
96 extern NSString
* const SecCKRecordKeyClassKey
;
97 //extern NSString* const SecCKRecordWrappedKeyKey;
98 //extern NSString* const SecCKRecordParentKeyRefKey;
100 /* Current Key CKRecord Keys */
101 extern NSString
* const SecCKRecordCurrentKeyType
;
102 // The key class will be the record name.
103 //extern NSString* const SecCKRecordParentKeyRefKey; <-- represent the current key for this key class
105 /* Current Item CKRecord Keys */
106 extern NSString
* const SecCKRecordCurrentItemType
;
107 extern NSString
* const SecCKRecordItemRefKey
;
108 //extern NSString* const SecCKRecordVersionKey; <-- the OS version which last updated the record
110 /* Device State CKRexord Keys */
111 extern NSString
* const SecCKRecordDeviceStateType
;
112 extern NSString
* const SecCKRecordCirclePeerID
;
113 extern NSString
* const SecCKRecordCircleStatus
;
114 extern NSString
* const SecCKRecordKeyState
;
115 extern NSString
* const SecCKRecordCurrentTLK
;
116 extern NSString
* const SecCKRecordCurrentClassA
;
117 extern NSString
* const SecCKRecordCurrentClassC
;
119 /* Manifest master CKRecord Keys */
120 extern NSString
* const SecCKRecordManifestType
;
121 extern NSString
* const SecCKRecordManifestDigestValueKey
;
122 extern NSString
* const SecCKRecordManifestGenerationCountKey
;
123 extern NSString
* const SecCKRecordManifestLeafRecordIDsKey
;
124 extern NSString
* const SecCKRecordManifestPeerManifestRecordIDsKey
;
125 extern NSString
* const SecCKRecordManifestCurrentItemsKey
;
126 extern NSString
* const SecCKRecordManifestSignaturesKey
;
127 extern NSString
* const SecCKRecordManifestSignerIDKey
;
128 extern NSString
* const SecCKRecordManifestSchemaKey
;
130 /* Manifest leaf CKRecord Keys */
131 extern NSString
* const SecCKRecordManifestLeafType
;
132 extern NSString
* const SecCKRecordManifestLeafDERKey
;
133 extern NSString
* const SecCKRecordManifestLeafDigestKey
;
135 /* Zone Key Hierarchy States */
136 @protocol SecCKKSZoneKeyState
138 typedef NSString
<SecCKKSZoneKeyState
> CKKSZoneKeyState
;
140 // Class has just been created.
141 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateInitializing
;
142 // CKKSZone has just informed us that its setup is done (and completed successfully).
143 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateInitialized
;
144 // Everything is ready and waiting for input.
145 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateReady
;
146 // A Fetch has just been completed which includes some new keys to process
147 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateFetchComplete
;
148 // We'd really like a full refetch.
149 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateNeedFullRefetch
;
150 // We've received a wrapped TLK, but we don't have its contents yet. Wait until they arrive.
151 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateWaitForTLK
;
152 // We've received a wrapped TLK, but we can't process it until the keybag unlocks. Wait until then.
153 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateWaitForUnlock
;
154 // Things are unhealthy, but we're not sure entirely why.
155 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateUnhealthy
;
156 // Something has gone horribly wrong with the current key pointers.
157 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateBadCurrentPointers
;
158 // Something has gone wrong creating new TLKs.
159 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateNewTLKsFailed
;
160 // Fatal error. Will not proceed unless fixed from outside class.
161 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateError
;
162 // This CKKS instance has been cancelled.
163 extern CKKSZoneKeyState
* const SecCKKSZoneKeyStateCancelled
;
165 // If you absolutely need to numberify one of the above constants, here's your maps.
166 NSDictionary
<CKKSZoneKeyState
*, NSNumber
*>* CKKSZoneKeyStateMap(void);
167 NSDictionary
<NSNumber
*, CKKSZoneKeyState
*>* CKKSZoneKeyStateInverseMap(void);
168 NSNumber
* CKKSZoneKeyToNumber(CKKSZoneKeyState
* state
);
169 CKKSZoneKeyState
* CKKSZoneKeyRecover(NSNumber
* stateNumber
);
171 /* Hide Item Length */
172 extern const NSUInteger SecCKKSItemPaddingBlockSize
;
175 extern NSString
* const SecCKKSAggdPropagationDelay
;
176 extern NSString
* const SecCKKSAggdPrimaryKeyConflict
;
177 extern NSString
* const SecCKKSAggdViewKeyCount
;
178 extern NSString
* const SecCKKSAggdItemReencryption
;
180 extern NSString
* const SecCKKSUserDefaultsSuite
;
182 /* Queue limits: these should likely be configurable via plist */
183 #define SecCKKSOutgoingQueueItemsAtOnce 100
184 #define SecCKKSIncomingQueueItemsAtOnce 10
188 /* C functions to interact with CKKS */
189 void SecCKKSInitialize(SecDbRef db
);
190 void SecCKKSNotifyBlock(SecDbConnectionRef dbconn
, SecDbTransactionPhase phase
, SecDbTransactionSource source
, CFArrayRef changes
);
192 // Called by XPC approximately every 3 days
193 void SecCKKS24hrNotification(void);
195 // Register this callback to receive a call when the item with this UUID next successfully (or unsuccessfully) exits the outgoing queue.
196 void CKKSRegisterSyncStatusCallback(CFStringRef cfuuid
, SecBoolCFErrorCallback callback
);
198 // Returns true if CloudKit keychain syncing should occur
199 bool SecCKKSIsEnabled(void);
201 bool SecCKKSEnable(void);
202 bool SecCKKSDisable(void);
204 bool SecCKKSResetSyncing(void);
206 bool SecCKKSSyncManifests(void);
207 bool SecCKKSEnableSyncManifests(void);
208 bool SecCKKSSetSyncManifests(bool value
);
210 bool SecCKKSEnforceManifests(void);
211 bool SecCKKSEnableEnforceManifests(void);
212 bool SecCKKSSetEnforceManifests(bool value
);
215 bool SecCKKSTestsEnabled(void);
216 bool SecCKKSTestsEnable(void);
217 bool SecCKKSTestsDisable(void);
219 void SecCKKSTestResetFlags(void);
220 bool SecCKKSTestDisableAutomaticUUID(void);
221 void SecCKKSTestSetDisableAutomaticUUID(bool set
);
223 bool SecCKKSTestDisableSOS(void);
224 void SecCKKSTestSetDisableSOS(bool set
);
226 bool SecCKKSTestDisableKeyNotifications(void);
227 void SecCKKSTestSetDisableKeyNotifications(bool set
);
230 XPC_RETURNS_RETAINED xpc_endpoint_t
231 SecServerCreateCKKSEndpoint(void);
233 // TODO: handle errors better
234 typedef CF_ENUM(CFIndex
, CKKSErrorCode
) {
235 CKKSNoUUIDOnItem
= 15,
238 #define SecTranslateError(nserrorptr, cferror) \
240 *nserrorptr = (__bridge_transfer NSError*) cferror; \
242 CFReleaseNull(cferror); \
245 // Very similar to the secerror, secnotice, and secinfo macros in debugging.h, but add zoneNames
246 #define ckkserrorwithzonename(scope, zoneName, format, ...) { os_log(secLogObjForScope("SecError"), scope "-%@: " format, (zoneName ? zoneName : @"unknown"), ## __VA_ARGS__); }
247 #define ckksnoticewithzonename(scope, zoneName, format, ...) { os_log(secLogObjForCFScope((__bridge CFStringRef)[@(scope "-") stringByAppendingString: (zoneName ? zoneName : @"unknown")]), format, ## __VA_ARGS__); }
248 #define ckksinfowithzonename(scope, zoneName, format, ...) { os_log_debug(secLogObjForCFScope((__bridge CFStringRef)[@(scope "-") stringByAppendingString: (zoneName ? zoneName : @"unknown")]), format, ## __VA_ARGS__); }
250 #define ckkserror(scope, zoneNameHaver, format, ...) \
251 { NSString* znh = zoneNameHaver.zoneName; \
252 ckkserrorwithzonename(scope, znh, format, ## __VA_ARGS__) \
254 #define ckksnotice(scope, zoneNameHaver, format, ...) \
255 { NSString* znh = zoneNameHaver.zoneName; \
256 ckksnoticewithzonename(scope, znh, format, ## __VA_ARGS__) \
258 #define ckksinfo(scope, zoneNameHaver, format, ...) \
259 { NSString* znh = zoneNameHaver.zoneName; \
260 ckksinfowithzonename(scope, znh, format, ## __VA_ARGS__) \
265 #define ckksdebugwithzonename(scope, zoneName, format, ...) { os_log_debug(secLogObjForCFScope((__bridge CFStringRef)[@(scope "-") stringByAppendingString: (zoneName ? zoneName : @"unknown")]), format, ## __VA_ARGS__); }
266 #define ckksdebug(scope, zoneNameHaver, format, ...) \
267 { NSString* znh = zoneNameHaver.zoneName; \
268 ckksdebugwithzonename(scope, znh, format, ## __VA_ARGS__) \
271 #define ckksdebug(scope,...) /* nothing */