]> git.saurik.com Git - apple/security.git/blobdiff - OSX/sec/Security/SecItemBackup.c
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / sec / Security / SecItemBackup.c
index ff08afe6ebda9f5a217ff66da3894c2d715803d7..9581cb8b2d865cbb7bcf120c27c8d336c8fd25d9 100644 (file)
@@ -31,9 +31,9 @@
 #include <Security/SecItemPriv.h>
 #include <Security/SecuritydXPC.h>
 #include <Security/SecFramework.h>
 #include <Security/SecItemPriv.h>
 #include <Security/SecuritydXPC.h>
 #include <Security/SecFramework.h>
-#include <securityd/SecItemServer.h>
+#include "keychain/securityd/SecItemServer.h"
 #include <ipc/securityd_client.h>
 #include <ipc/securityd_client.h>
-#include <Security/SecureObjectSync/SOSBackupEvent.h>
+#include "keychain/SecureObjectSync/SOSBackupEvent.h"
 #include <Security/SecureObjectSync/SOSCloudCircle.h>
 #include <Security/SecureObjectSync/SOSViews.h>
 #include <corecrypto/ccsha1.h>
 #include <Security/SecureObjectSync/SOSCloudCircle.h>
 #include <Security/SecureObjectSync/SOSViews.h>
 #include <corecrypto/ccsha1.h>
 #include <os/activity.h>
 #include <notify.h>
 
 #include <os/activity.h>
 #include <notify.h>
 
-static CFDataRef client_data_data_to_data_error_request(enum SecXPCOperation op, SecurityClient *client, CFDataRef keybag, CFDataRef passcode, CFErrorRef *error) {
+#include <sys/stat.h>
+
+static CFDataRef client_data_data_bool_to_data_error_request(enum SecXPCOperation op, SecurityClient *client, CFDataRef keybag, CFDataRef passcode, bool emcs, CFErrorRef *error) {
     __block CFDataRef result = NULL;
     securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
         return SecXPCDictionarySetDataOptional(message, kSecXPCKeyKeybag, keybag, error)
     __block CFDataRef result = NULL;
     securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
         return SecXPCDictionarySetDataOptional(message, kSecXPCKeyKeybag, keybag, error)
-        && SecXPCDictionarySetDataOptional(message, kSecXPCKeyUserPassword, passcode, error);
+        && SecXPCDictionarySetDataOptional(message, kSecXPCKeyUserPassword, passcode, error)
+        && SecXPCDictionarySetBool(message, kSecXPCKeyEMCSBackup, emcs, NULL);
     }, ^bool(xpc_object_t response, CFErrorRef *error) {
         return (result = SecXPCDictionaryCopyData(response, kSecXPCKeyResult, error));
     });
     }, ^bool(xpc_object_t response, CFErrorRef *error) {
         return (result = SecXPCDictionaryCopyData(response, kSecXPCKeyResult, error));
     });
@@ -121,6 +124,17 @@ static bool string_string_data_data_data_to_bool_error_request(enum SecXPCOperat
     });
 }
 
     });
 }
 
+static CFStringRef string_to_string_error_request(enum SecXPCOperation op, CFStringRef viewName, CFErrorRef *error)
+{
+    __block CFStringRef result = NULL;
+    securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+        return SecXPCDictionarySetString(message, kSecXPCKeyString, viewName, error);
+    }, ^bool(xpc_object_t response, CFErrorRef *error) {
+        return result = SecXPCDictionaryCopyString(response, kSecXPCKeyResult, error);
+    });
+    return result;
+}
+
 static CFArrayRef to_array_error_request(enum SecXPCOperation op, CFErrorRef *error)
 {
     __block CFArrayRef result = NULL;
 static CFArrayRef to_array_error_request(enum SecXPCOperation op, CFErrorRef *error)
 {
     __block CFArrayRef result = NULL;
@@ -145,7 +159,7 @@ static int SecItemBackupHandoffFD(CFStringRef backupName, CFErrorRef *error) {
 CFDataRef _SecKeychainCopyOTABackup(void) {
     __block CFDataRef result;
     os_activity_initiate("_SecKeychainCopyOTABackup", OS_ACTIVITY_FLAG_DEFAULT, ^{
 CFDataRef _SecKeychainCopyOTABackup(void) {
     __block CFDataRef result;
     os_activity_initiate("_SecKeychainCopyOTABackup", OS_ACTIVITY_FLAG_DEFAULT, ^{
-        result = SECURITYD_XPC(sec_keychain_backup, client_data_data_to_data_error_request, SecSecurityClientGet(), NULL, NULL, NULL);
+        result = SECURITYD_XPC(sec_keychain_backup, client_data_data_bool_to_data_error_request, SecSecurityClientGet(), NULL, NULL, false, NULL);
     });
     return result;
 }
     });
     return result;
 }
@@ -153,7 +167,15 @@ CFDataRef _SecKeychainCopyOTABackup(void) {
 CFDataRef _SecKeychainCopyBackup(CFDataRef backupKeybag, CFDataRef password) {
     __block CFDataRef result;
     os_activity_initiate("_SecKeychainCopyBackup", OS_ACTIVITY_FLAG_DEFAULT, ^{
 CFDataRef _SecKeychainCopyBackup(CFDataRef backupKeybag, CFDataRef password) {
     __block CFDataRef result;
     os_activity_initiate("_SecKeychainCopyBackup", OS_ACTIVITY_FLAG_DEFAULT, ^{
-        result = SECURITYD_XPC(sec_keychain_backup, client_data_data_to_data_error_request, SecSecurityClientGet(), backupKeybag, password, NULL);
+        result = SECURITYD_XPC(sec_keychain_backup, client_data_data_bool_to_data_error_request, SecSecurityClientGet(), backupKeybag, password, false, NULL);
+    });
+    return result;
+}
+
+CFDataRef _SecKeychainCopyEMCSBackup(CFDataRef backupKeybag) {
+    __block CFDataRef result;
+    os_activity_initiate("_SecKeychainCopyEMCSBackup", OS_ACTIVITY_FLAG_DEFAULT, ^{
+        result = SECURITYD_XPC(sec_keychain_backup, client_data_data_bool_to_data_error_request, SecSecurityClientGet(), backupKeybag, NULL, true, NULL);
     });
     return result;
 }
     });
     return result;
 }
@@ -189,6 +211,25 @@ _SecKeychainRestoreBackupFromFileDescriptor(int fd, CFDataRef backupKeybag, CFDa
     return result;
 }
 
     return result;
 }
 
+/*
+ * Current promise is that this is low memory usage, so in the current format, ask securityd
+ * to resolve the item for us.
+ */
+
+CFStringRef
+_SecKeychainCopyKeybagUUIDFromFileDescriptor(int fd, CFErrorRef *error)
+{
+    __block CFStringRef result = NULL;
+    os_activity_initiate("_SecKeychainCopyKeybagUUID", OS_ACTIVITY_FLAG_DEFAULT, ^{
+        securityd_send_sync_and_do(sec_keychain_backup_keybag_uuid_id, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+            return SecXPCDictionarySetFileDescriptor(message, kSecXPCKeyFileDescriptor, fd, error);
+        }, ^bool(xpc_object_t response, CFErrorRef *error) {
+            return (result = SecXPCDictionaryCopyString(response, kSecXPCKeyResult, error));
+        });
+    });
+    return result;
+}
+
 
 OSStatus _SecKeychainRestoreBackup(CFDataRef backup, CFDataRef backupKeybag,
                                    CFDataRef password) {
 
 OSStatus _SecKeychainRestoreBackup(CFDataRef backup, CFDataRef backupKeybag,
                                    CFDataRef password) {
@@ -259,19 +300,40 @@ static bool SecKeychainWithBackupFile(CFStringRef backupName, CFErrorRef *error,
     }
 
     // Rewind file to start
     }
 
     // Rewind file to start
-    lseek(fd, 0, SEEK_SET);
+    if (lseek(fd, 0, SEEK_SET)) {
+        secdebug("backup", "Could not seek in fd %d for %@", fd, backupName);
+        return SecCheckErrno(true, error, CFSTR("lseek"));
+    }
 
     FILE *backup = fdopen(fd, "r");
     if (!backup) {
 
     FILE *backup = fdopen(fd, "r");
     if (!backup) {
-        close(fd);
         secdebug("backup", "Receiving file for %@ failed, %d", backupName, errno);
         secdebug("backup", "Receiving file for %@ failed, %d", backupName, errno);
-        return SecCheckErrno(!backup, error, CFSTR("fdopen"));
+        SecCheckErrno(!backup, error, CFSTR("fdopen"));
+        if (close(fd)) {
+            secdebug("backup", "Encountered error closing file %@: %d", backupName, errno);
+            SecCheckErrno(true, error, CFSTR("close"));
+        }
+        return false;
     } else {
     } else {
-        secdebug("backup", "Receiving file for %@ with fd %d of size %llu", backupName, fd, lseek(fd, 0, SEEK_END));
+        struct stat sb;
+        if (fstat(fd, &sb)) {
+            secdebug("backup", "Unable to get file metadata for %@, fd %d", backupName, fd);
+            SecCheckErrno(true, error, CFSTR("fstat"));
+            if (fclose(backup)) {
+                secdebug("backup", "Encountered error closing file %@: %d", backupName, errno);
+                SecCheckErrno(true, error, CFSTR("fclose"));
+            }
+            return false;
+        }
+        secdebug("backup", "Receiving file for %@ with fd %d of size %llu", backupName, fd, sb.st_size);
     }
 
     with(backup);
     }
 
     with(backup);
-    fclose(backup);
+    if (fclose(backup)) {
+        secdebug("backup", "Encountered error %d closing file %@ after backup handler", errno, backupName);
+        SecCheckErrno(true, error, CFSTR("fclose"));
+        // read only file and block has its own error handling for IO failure, no need to return false
+    }
     return true;
 }
 
     return true;
 }
 
@@ -295,6 +357,25 @@ bool SecItemBackupWithRegisteredBackups(CFErrorRef *error, void(^backup)(CFStrin
     return true;
 }
 
     return true;
 }
 
+static CFStringRef SecItemBackupViewAndCopyBackupPeerID(CFStringRef viewName, CFErrorRef *error)
+{
+    __block CFStringRef result;
+    os_activity_initiate("SecItemBackupViewAndCopyBackupPeerID", OS_ACTIVITY_FLAG_DEFAULT, ^{
+        result = SECURITYD_XPC(sec_item_backup_ensure_copy_view, string_to_string_error_request, viewName, error);
+    });
+    return result;
+}
+
+bool SecItemBackupWithRegisteredViewBackup(CFStringRef viewName, CFErrorRef *error) {
+    CFStringRef backupName = SecItemBackupViewAndCopyBackupPeerID(viewName, error);
+    if(backupName == NULL) {
+        return false;
+    }
+    CFReleaseNull(backupName);
+    return true;
+}
+
+
 static bool SecItemBackupDoResetEventBody(const uint8_t *der, const uint8_t *der_end, CFErrorRef *error, void (^handleEvent)(SecBackupEventType et, CFTypeRef key, CFTypeRef item)) {
     size_t sequence_len;
     const uint8_t *sequence_body = ccder_decode_len(&sequence_len, der, der_end);
 static bool SecItemBackupDoResetEventBody(const uint8_t *der, const uint8_t *der_end, CFErrorRef *error, void (^handleEvent)(SecBackupEventType et, CFTypeRef key, CFTypeRef item)) {
     size_t sequence_len;
     const uint8_t *sequence_body = ccder_decode_len(&sequence_len, der, der_end);
@@ -326,7 +407,7 @@ static bool SecItemBackupDoResetEventBody(const uint8_t *der, const uint8_t *der
 
 static bool SecItemBackupDoAddEvent(const uint8_t *der, const uint8_t *der_end, CFErrorRef *error, void (^handleEvent)(SecBackupEventType et, CFTypeRef key, CFTypeRef item)) {
     CFDictionaryRef eventDict = NULL;
 
 static bool SecItemBackupDoAddEvent(const uint8_t *der, const uint8_t *der_end, CFErrorRef *error, void (^handleEvent)(SecBackupEventType et, CFTypeRef key, CFTypeRef item)) {
     CFDictionaryRef eventDict = NULL;
-    const uint8_t *der_end_of_dict = der_decode_dictionary(kCFAllocatorDefault, kCFPropertyListImmutable, &eventDict, error, der, der_end);
+    const uint8_t *der_end_of_dict = der_decode_dictionary(kCFAllocatorDefault, &eventDict, error, der, der_end);
     if (der_end_of_dict && der_end_of_dict != der_end) {
         // Can't ever happen!
         SecError(errSecDecode, error, CFSTR("trailing junk after add"));
     if (der_end_of_dict && der_end_of_dict != der_end) {
         // Can't ever happen!
         SecError(errSecDecode, error, CFSTR("trailing junk after add"));
@@ -538,9 +619,32 @@ void SecItemBackupRestore(CFStringRef backupName, CFStringRef peerID, CFDataRef
     CFReleaseSafe(localError);
 }
 
     CFReleaseSafe(localError);
 }
 
-CFDictionaryRef SecItemBackupCopyMatching(CFDataRef keybag, CFDataRef secret, CFDictionaryRef backup, CFDictionaryRef query, CFErrorRef *error) {
-    SecError(errSecUnimplemented, error, CFSTR("SecItemBackupCopyMatching unimplemented"));
-    return NULL;
+bool SecBackupKeybagAdd(CFDataRef passcode, CFDataRef *identifier, CFURLRef *pathinfo, CFErrorRef *error) {
+    __block bool result = false;
+    os_activity_initiate("_SecServerBackupKeybagAdd", OS_ACTIVITY_FLAG_DEFAULT, ^{
+        securityd_send_sync_and_do(kSecXPCOpBackupKeybagAdd, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+            return SecXPCDictionarySetDataOptional(message, kSecXPCKeyUserPassword, passcode, error);
+        }, ^bool(xpc_object_t response, CFErrorRef *error) {
+            result = SecXPCDictionaryCopyDataOptional(response, kSecXPCKeyBackupKeybagIdentifier, identifier, error) &&
+            SecXPCDictionaryCopyURLOptional(response, kSecXPCKeyBackupKeybagPath, pathinfo, error) &&
+            SecXPCDictionaryGetBool(response, kSecXPCKeyResult, error);
+            return result;
+        });
+    });
+    return result;
+}
+
+bool SecBackupKeybagDelete(CFDictionaryRef query, CFErrorRef *error) {
+    __block bool result = false;
+    os_activity_initiate("_SecBackupKeybagDelete", OS_ACTIVITY_FLAG_DEFAULT, ^{
+        securityd_send_sync_and_do(kSecXPCOpBackupKeybagDelete, error, ^bool(xpc_object_t message, CFErrorRef *error) {
+            return SecXPCDictionarySetPList(message, kSecXPCKeyQuery, query, error);
+        }, ^bool(xpc_object_t response, CFErrorRef *error) {
+            result = SecXPCDictionaryGetBool(response, kSecXPCKeyResult, error);
+            return result;
+        });
+    });
+    return result;
 }
 
 
 }