]> git.saurik.com Git - apple/security.git/blobdiff - OSX/sec/Security/SecItem.m
Security-58286.1.32.tar.gz
[apple/security.git] / OSX / sec / Security / SecItem.m
diff --git a/OSX/sec/Security/SecItem.m b/OSX/sec/Security/SecItem.m
new file mode 100644 (file)
index 0000000..7af25f3
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2017 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Implements SecItem.c things using Obj-c.
+ */
+
+#include <Security/SecBasePriv.h>
+#include <Security/SecItem.h>
+#include <Security/SecItemPriv.h>
+#include <Security/SecItemInternal.h>
+#include <utilities/SecCFRelease.h>
+
+#include <os/activity.h>
+
+#import <Foundation/Foundation.h>
+
+OSStatus _SecItemAddAndNotifyOnSync(CFDictionaryRef attributes, CFTypeRef * CF_RETURNS_RETAINED result, void (^syncCallback)(bool didSync, CFErrorRef error)) {
+    __block SecCFDictionaryCOW attrs = { attributes };
+    OSStatus status = errSecParam;
+
+    os_activity_t activity = os_activity_create("_SecItemAddAndNotifyOnSync", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
+    os_activity_scope(activity);
+
+    status = SecOSStatusWith(^bool(CFErrorRef *statuserror) {
+        return SecItemAuthDoQuery(&attrs, NULL, SecItemAdd, statuserror, ^bool(TKTokenRef token, CFDictionaryRef authedattributes, CFDictionaryRef unused, CFDictionaryRef auth_params, CFErrorRef *autherror) {
+            if (token != NULL) {
+                syncCallback(false, NULL);
+                return false;
+            }
+
+            __block CFTypeRef raw_result = NULL;
+            __block CFErrorRef raw_error = NULL;
+
+            id<SecuritydXPCProtocol> rpc = SecuritydXPCProxyObject(^(NSError *error) {
+                syncCallback(false, (__bridge CFErrorRef)error);
+            });
+            if (rpc == NULL) {
+                return false;
+            }
+            SecuritydXPCCallback* xpcCallback = [[SecuritydXPCCallback alloc] initWithCallback: ^void(bool didSync, NSError* error) {
+                syncCallback(didSync, (__bridge CFErrorRef) error);
+            }];
+
+            dispatch_semaphore_t wait_for_secd = dispatch_semaphore_create(0);
+            [rpc SecItemAddAndNotifyOnSync: (__bridge NSDictionary*) authedattributes syncCallback:xpcCallback complete: ^void (NSDictionary* opDictResult, NSArray* opArrayResult, NSError* operror) {
+                raw_result = opDictResult  ? CFBridgingRetain(opDictResult)  :
+                             opArrayResult ? CFBridgingRetain(opArrayResult) : NULL;
+                raw_error = (CFErrorRef) CFBridgingRetain(operror);
+                dispatch_semaphore_signal(wait_for_secd);
+            }];
+            dispatch_semaphore_wait(wait_for_secd, DISPATCH_TIME_FOREVER);
+
+            if(autherror) {
+                *autherror = raw_error;
+            }
+
+            bool ok = false;
+
+            // SecItemResultProcess isn't intended to handle error cases, so bypass it.
+            if(!raw_error) {
+                ok = SecItemResultProcess(authedattributes, auth_params, token, raw_result, result, autherror);
+            }
+            CFReleaseNull(raw_result);
+            return ok;
+       });
+    });
+    CFReleaseNull(attrs.mutable_dictionary);
+
+    return status;
+}
+
+void SecItemSetCurrentItemAcrossAllDevices(CFStringRef accessGroup,
+                                           CFStringRef identifier,
+                                           CFStringRef viewHint,
+                                           CFDataRef newCurrentItemReference,
+                                           CFDataRef newCurrentItemHash,
+                                           CFDataRef oldCurrentItemReference,
+                                           CFDataRef oldCurrentItemHash,
+                                           void (^complete)(CFErrorRef error))
+{
+    os_activity_t activity = os_activity_create("SecItemSetCurrentItemAcrossAllDevices", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
+    os_activity_scope(activity);
+
+    id<SecuritydXPCProtocol> rpc = SecuritydXPCProxyObject(^(NSError *error) {
+        complete((__bridge CFErrorRef) error);
+    });
+    [rpc secItemSetCurrentItemAcrossAllDevices:(__bridge NSData*)newCurrentItemReference
+                            newCurrentItemHash:(__bridge NSData*)newCurrentItemHash
+                                   accessGroup:(__bridge NSString*)accessGroup
+                                    identifier:(__bridge NSString*)identifier
+                                      viewHint:(__bridge NSString*)viewHint
+                       oldCurrentItemReference:(__bridge NSData*)oldCurrentItemReference
+                            oldCurrentItemHash:(__bridge NSData*)oldCurrentItemHash
+                                      complete: ^ (NSError* operror) {
+        complete((__bridge CFErrorRef) operror);
+    }];
+}
+
+void SecItemFetchCurrentItemAcrossAllDevices(CFStringRef accessGroup,
+                                             CFStringRef identifier,
+                                             CFStringRef viewHint,
+                                             bool fetchCloudValue,
+                                             void (^complete)(CFDataRef persistentRef, CFErrorRef error))
+{
+    os_activity_t activity = os_activity_create("SecItemFetchCurrentItemAcrossAllDevices", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
+    os_activity_scope(activity);
+
+    id<SecuritydXPCProtocol> rpc = SecuritydXPCProxyObject(^(NSError *error) {
+        complete(NULL, (__bridge CFErrorRef) error);
+    });
+    [rpc secItemFetchCurrentItemAcrossAllDevices:(__bridge NSString*)accessGroup
+                                      identifier:(__bridge NSString*)identifier
+                                        viewHint:(__bridge NSString*)viewHint
+                                 fetchCloudValue:fetchCloudValue
+                                        complete: ^(NSData* persistentRef, NSError* operror) {
+                                            complete((__bridge CFDataRef) persistentRef, (__bridge CFErrorRef) operror);
+                                        }];
+}
+
+void _SecItemFetchDigests(NSString *itemClass, NSString *accessGroup, void (^complete)(NSArray<NSDictionary *> *, NSError *))
+{
+    os_activity_t activity = os_activity_create("_SecItemFetchDigests", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT);
+    os_activity_scope(activity);
+
+    id<SecuritydXPCProtocol> rpc = SecuritydXPCProxyObject(^(NSError *error) {
+        complete(NULL, error);
+    });
+    [rpc secItemDigest:itemClass accessGroup:accessGroup complete:complete];
+}
+