]> git.saurik.com Git - apple/security.git/commitdiff
Security-58286.251.4.tar.gz macos-10144 v58286.251.4
authorApple <opensource@apple.com>
Tue, 18 Jun 2019 00:54:59 +0000 (00:54 +0000)
committerApple <opensource@apple.com>
Tue, 18 Jun 2019 00:54:59 +0000 (00:54 +0000)
125 files changed:
OSX/SecurityTestsOSX/SecurityTests-Entitlements.plist
OSX/authd/authd-Entitlements.plist
OSX/authd/authitems.c
OSX/authd/authutilities.c
OSX/authd/server.c
OSX/codesign_tests/SignatureEditing.sh [new file with mode: 0644]
OSX/config/security_framework_macos.xcconfig
OSX/libsecurity_codesigning/CodeSigningHelper/main.cpp
OSX/libsecurity_codesigning/antlr2/src/CharBuffer.cpp
OSX/libsecurity_codesigning/lib/CodeSigner.cpp
OSX/libsecurity_codesigning/lib/CodeSigner.h
OSX/libsecurity_codesigning/lib/RequirementLexer.cpp
OSX/libsecurity_codesigning/lib/SecCode.cpp
OSX/libsecurity_codesigning/lib/SecCode.h
OSX/libsecurity_codesigning/lib/SecCodePriv.h
OSX/libsecurity_codesigning/lib/SecCodeSigner.cpp
OSX/libsecurity_codesigning/lib/SecCodeSigner.h
OSX/libsecurity_codesigning/lib/StaticCode.cpp
OSX/libsecurity_codesigning/lib/StaticCode.h
OSX/libsecurity_codesigning/lib/antlrplugin.cpp
OSX/libsecurity_codesigning/lib/bundlediskrep.cpp
OSX/libsecurity_codesigning/lib/bundlediskrep.h
OSX/libsecurity_codesigning/lib/cdbuilder.cpp
OSX/libsecurity_codesigning/lib/cdbuilder.h
OSX/libsecurity_codesigning/lib/cskernel.cpp
OSX/libsecurity_codesigning/lib/csprocess.h
OSX/libsecurity_codesigning/lib/diskrep.h
OSX/libsecurity_codesigning/lib/machorep.cpp
OSX/libsecurity_codesigning/lib/machorep.h
OSX/libsecurity_codesigning/lib/piddiskrep.cpp
OSX/libsecurity_codesigning/lib/piddiskrep.h
OSX/libsecurity_codesigning/lib/sigblob.cpp
OSX/libsecurity_codesigning/lib/sigblob.h
OSX/libsecurity_codesigning/lib/signer.cpp
OSX/libsecurity_codesigning/lib/signer.h
OSX/libsecurity_codesigning/lib/signerutils.cpp
OSX/libsecurity_codesigning/lib/signerutils.h
OSX/libsecurity_codesigning/requirements.grammar
OSX/libsecurity_keychain/lib/DLDBListCFPref.cpp
OSX/libsecurity_keychain/lib/Item.cpp
OSX/libsecurity_keychain/lib/KeyItem.cpp
OSX/libsecurity_keychain/lib/Keychains.cpp
OSX/libsecurity_keychain/lib/SecAccess.cpp
OSX/libsecurity_keychain/lib/SecItem.cpp
OSX/libsecurity_keychain/regressions/kc-45-change-password.c [new file with mode: 0644]
OSX/libsecurity_keychain/regressions/keychain_regressions.h
OSX/libsecurity_keychain/xpc/main.c
OSX/libsecurity_smime/lib/cmssigdata.c
OSX/libsecurity_smime/regressions/cms-01-basic.c
OSX/libsecurity_smime/regressions/cms-01-basic.h
OSX/libsecurity_ssl/regressions/ssl-53-clientauth.c
OSX/libsecurity_utilities/lib/errors.cpp
OSX/libsecurity_utilities/lib/errors.h
OSX/libsecurity_utilities/lib/machserver.cpp
OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h
OSX/sec/SOSCircle/SecureObjectSync/SOSDigestVector.c
OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c
OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.m
OSX/sec/SOSCircle/SecureObjectSync/ViewList.list
OSX/sec/Security/Regressions/secitem/si-95-cms-basic.c
OSX/sec/Security/Regressions/secitem/si-95-cms-basic.h
OSX/sec/Security/SecAccessControl.c [deleted file]
OSX/sec/Security/SecAccessControl.m [new file with mode: 0644]
OSX/sec/Security/SecCTKKey.m
OSX/sec/Security/SecCTKKeyPriv.h
OSX/sec/Security/SecExports.exp-in
OSX/sec/Security/SecFrameworkStrings.h
OSX/sec/Security/SecItem.c
OSX/sec/Security/SecItemConstants.c
OSX/sec/Security/SecKey.c
OSX/sec/Security/SecKeyAdaptors.m
OSX/sec/securityd/OTATrustUtilities.m
OSX/sec/securityd/Regressions/secd-33-keychain-ctk.m
OSX/sec/securityd/SecPolicyServer.c
OSX/sec/securityd/SecRevocationNetworking.m
OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA2G1-Baltimore.cer [new file with mode: 0644]
OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA8G1-Baltimore.cer [new file with mode: 0644]
OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA8G1-DigiCert.cer [new file with mode: 0644]
OSX/shared_regressions/si-20-sectrust-policies-data/BaltimoreCyberTrustRoot.cer [new file with mode: 0644]
OSX/shared_regressions/si-20-sectrust-policies-data/DigiCertGlobalRootG3.cer [new file with mode: 0644]
OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist
OSX/shared_regressions/si-20-sectrust-policies-data/caldav.cer [new file with mode: 0644]
OSX/shared_regressions/si-20-sectrust-policies-data/generic_apple_server.cer
OSX/shared_regressions/si-20-sectrust-policies-data/itunes.cer [new file with mode: 0644]
OSX/shared_regressions/si-44-seckey-aks.m
OSX/shared_regressions/si-44-seckey-ies.m
OSX/shared_regressions/si-82-sectrust-ct.m
OSX/utilities/src/SecDb.c
OSX/utilities/src/iCloudKeychainTrace.c
Security.exp-in
Security.xcodeproj/project.pbxproj
SecurityTests/SecurityTests-Entitlements.plist
SecurityTool/keychain_export.m
SecurityTool/keychain_set_settings.c
SecurityTool/security.1
SecurityTool/security.c
cssm/cssmapple.h
keychain/CoreDataKeychain/SecCDKeychain.m
keychain/SecItem.h
keychain/SecItemPriv.h
keychain/SecKey.h
keychain/SecKeyPriv.h
keychain/ckks/CKKS.h
keychain/ckks/CKKS.m
keychain/ckks/CKKSIncomingQueueOperation.m
keychain/ckks/CKKSKeychainView.m
keychain/ckks/tests/CKKSSOSTests.m
keychain/ckks/tests/CKKSTests+API.m
keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m
libsecurity_smime/lib/cmssigdata.c
resources/English.lproj/OID.strings
resources/English.lproj/Trust.strings
sectask/SecTask.c
sectask/SecTaskPriv.h
securityd/securityd_service/securityd_service/main.c
securityd/src/SharedMemoryServer.cpp
securityd/src/agentquery.cpp
securityd/src/child.cpp
securityd/src/clientid.cpp
securityd/src/clientid.h
securityd/src/csproxy.cpp
securityd/src/kcdatabase.cpp
securityd/src/process.cpp
securityd/src/process.h
tests/secdmockaks/mockaks.m

index 01ffca584b4a48a17efa4c697b6287dac14aebc9..9b09881791fdde260a467f46c738dc87fe10f183 100644 (file)
@@ -10,6 +10,8 @@
        <true/>
        <key>com.apple.keystore.access-keychain-keys</key>
        <true/>
        <true/>
        <key>com.apple.keystore.access-keychain-keys</key>
        <true/>
+       <key>com.apple.keystore.sik.access</key>
+       <true/>
        <key>com.apple.keystore.device</key>
        <true/>
        <key>restore-keychain</key>
        <key>com.apple.keystore.device</key>
        <true/>
        <key>restore-keychain</key>
index 7ef4f57c7622eb871b025d425d6ff731e3f5e22d..a1885cc8bb4711a7e52500a78d64f44cb1d50b34 100644 (file)
@@ -6,5 +6,7 @@
        <true/>
        <key>com.apple.keystore.console</key>
        <true/>
        <true/>
        <key>com.apple.keystore.console</key>
        <true/>
+       <key>com.apple.security.cs.disable-library-validation</key>
+       <true/>
 </dict>
 </plist>
 </dict>
 </plist>
index 463884e280684fcd1bf8111b7dae8c12970f4927..ea49287ad8ca864d148488dca7f5763fe5554833 100644 (file)
@@ -255,6 +255,10 @@ auth_item_create_with_xpc(xpc_object_t data)
         bool sensitive = xpc_dictionary_get_value(data, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH);
         if (sensitive) {
             size_t sensitiveLength = (size_t)xpc_dictionary_get_uint64(data, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH);
         bool sensitive = xpc_dictionary_get_value(data, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH);
         if (sensitive) {
             size_t sensitiveLength = (size_t)xpc_dictionary_get_uint64(data, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH);
+            if (sensitiveLength > len) {
+                os_log_error(AUTHD_LOG, "Sensitive data len %zu is not valid", sensitiveLength);
+                goto done;
+            }
             item->bufLen = sensitiveLength;
             item->data.valueLength = sensitiveLength;
             item->data.value = calloc(1u, sensitiveLength);
             item->bufLen = sensitiveLength;
             item->data.valueLength = sensitiveLength;
             item->data.value = calloc(1u, sensitiveLength);
index d769467b3abc4d0e5060567ec0dd48597ba8dc50..60b6b2fdfb54f8cfe390d8175eec93ef51b78be4 100644 (file)
@@ -7,6 +7,8 @@
 #include <AssertMacros.h>
 #include <assert.h>
 
 #include <AssertMacros.h>
 #include <assert.h>
 
+AUTHD_DEFINE_LOG
+
 xpc_object_t
 SerializeItemSet(const AuthorizationItemSet * itemSet)
 {
 xpc_object_t
 SerializeItemSet(const AuthorizationItemSet * itemSet)
 {
@@ -67,6 +69,10 @@ DeserializeItemSet(const xpc_object_t data)
             // <rdar://problem/13033889> authd is holding on to multiple copies of my password in the clear
             if (xpc_dictionary_get_value(value, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH) != NULL) {
                 size_t sensitiveLength = (size_t)xpc_dictionary_get_uint64(value, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH);
             // <rdar://problem/13033889> authd is holding on to multiple copies of my password in the clear
             if (xpc_dictionary_get_value(value, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH) != NULL) {
                 size_t sensitiveLength = (size_t)xpc_dictionary_get_uint64(value, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH);
+                if (sensitiveLength > len) {
+                    os_log_error(AUTHD_LOG, "Sensitive data len %zu is not valid", sensitiveLength);
+                    goto done;
+                }
                 dataCopy = malloc(sensitiveLength);
                 require(dataCopy != NULL, done);
                 memcpy(dataCopy, valueData, sensitiveLength);
                 dataCopy = malloc(sensitiveLength);
                 require(dataCopy != NULL, done);
                 memcpy(dataCopy, valueData, sensitiveLength);
index 903c51c87fe5a0cdad717fa2a4707296d580c128..1c29b2ecb97d4c824b8d70682785a64464b3411c 100644 (file)
@@ -37,9 +37,6 @@ static CFMutableDictionaryRef gSessionMap = NULL;
 static CFMutableDictionaryRef gAuthTokenMap = NULL;
 static authdb_t gDatabase = NULL;
 
 static CFMutableDictionaryRef gAuthTokenMap = NULL;
 static authdb_t gDatabase = NULL;
 
-static dispatch_queue_t power_queue;
-static bool gInDarkWake = false;
-static IOPMConnection gIOPMconn = NULL;
 static bool gXPCTransaction = false;
 
 static dispatch_queue_t
 static bool gXPCTransaction = false;
 
 static dispatch_queue_t
@@ -112,71 +109,15 @@ void server_cleanup()
     CFRelease(gSessionMap);
     CFRelease(gAuthTokenMap);
     
     CFRelease(gSessionMap);
     CFRelease(gAuthTokenMap);
     
-    IOPMConnectionSetDispatchQueue(gIOPMconn, NULL);
-    IOPMConnectionRelease(gIOPMconn);
-    
     dispatch_queue_t queue = get_server_dispatch_queue();
     if (queue) {
         dispatch_release(queue);
     }
     dispatch_queue_t queue = get_server_dispatch_queue();
     if (queue) {
         dispatch_release(queue);
     }
-    dispatch_release(power_queue);
-}
-
-static void _IOMPCallBack(void * param AUTH_UNUSED, IOPMConnection connection, IOPMConnectionMessageToken token, IOPMSystemPowerStateCapabilities capabilities)
-{
-    os_log_debug(AUTHD_LOG, "server: IOMP powerstates %i", capabilities);
-    if (capabilities & kIOPMSystemPowerStateCapabilityDisk)
-        os_log_debug(AUTHD_LOG, "server: disk");
-    if (capabilities & kIOPMSystemPowerStateCapabilityNetwork)
-        os_log_debug(AUTHD_LOG, "server: net");
-    if (capabilities & kIOPMSystemPowerStateCapabilityAudio)
-        os_log_debug(AUTHD_LOG, "server: audio");
-    if (capabilities & kIOPMSystemPowerStateCapabilityVideo)
-        os_log_debug(AUTHD_LOG, "server: video");
-    
-    /* if cpu and no display -> in DarkWake */
-    os_log_debug(AUTHD_LOG, "server: DarkWake check current=%i==%i", (capabilities & (kIOPMSystemPowerStateCapabilityCPU|kIOPMSystemPowerStateCapabilityVideo)), kIOPMSystemPowerStateCapabilityCPU);
-    if ((capabilities & (kIOPMSystemPowerStateCapabilityCPU|kIOPMSystemPowerStateCapabilityVideo)) == kIOPMSystemPowerStateCapabilityCPU) {
-        os_log_debug(AUTHD_LOG, "server: enter DW");
-        gInDarkWake = true;
-    } else if (gInDarkWake) {
-        os_log_debug(AUTHD_LOG, "server: exit DW");
-        gInDarkWake = false;
-    }
-    
-    (void)IOPMConnectionAcknowledgeEvent(connection, token);
-    
-    return;
-}
-
-static void
-_setupDarkWake(void *__unused ctx)
-{
-    IOReturn ret;
-    
-    IOPMConnectionCreate(CFSTR("IOPowerWatcher"),
-                         kIOPMSystemPowerStateCapabilityDisk
-                         | kIOPMSystemPowerStateCapabilityNetwork
-                         | kIOPMSystemPowerStateCapabilityAudio
-                         | kIOPMSystemPowerStateCapabilityVideo,
-                         &gIOPMconn);
-
-    ret = IOPMConnectionSetNotification(gIOPMconn, NULL, _IOMPCallBack);
-    if (ret != kIOReturnSuccess)
-        return;
-    
-    IOPMConnectionSetDispatchQueue(gIOPMconn, power_queue);
-
-    IOPMScheduleUserActiveChangedNotification(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(bool active) {
-        if (active) {
-            gInDarkWake = false;
-        }
-    });
 }
 
 bool server_in_dark_wake()
 {
 }
 
 bool server_in_dark_wake()
 {
-    return gInDarkWake;
+    return IOPMIsADarkWake(IOPMConnectionGetSystemCapabilities());
 }
 
 authdb_t server_get_database()
 }
 
 authdb_t server_get_database()
@@ -256,10 +197,6 @@ OSStatus server_init(void)
     authdb_maintenance(dbconn);
     authdb_connection_release(&dbconn);
     
     authdb_maintenance(dbconn);
     authdb_connection_release(&dbconn);
     
-    power_queue = dispatch_queue_create("com.apple.security.auth.power", DISPATCH_QUEUE_SERIAL);
-    require_action(power_queue != NULL, done, status = errAuthorizationInternal);
-    dispatch_async_f(power_queue, NULL, _setupDarkWake);
-
     _setupAuditSessionMonitor();
     _setupSignalHandlers();
     
     _setupAuditSessionMonitor();
     _setupSignalHandlers();
     
diff --git a/OSX/codesign_tests/SignatureEditing.sh b/OSX/codesign_tests/SignatureEditing.sh
new file mode 100644 (file)
index 0000000..9aadfa9
--- /dev/null
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+v=${v:-:}
+
+fails=0
+t=$(mktemp -d /tmp/cs-edit-XXXXXX)
+
+runTest () {
+    test=$1
+    shift
+
+    echo "[BEGIN] ${test}"
+
+    ${v} echo "> $@"
+    "$@" > $t/outfile.txt 2>&1
+    res=$?
+    [ $res != 0 ] && res=1 #normalize
+
+    if expr "$test" : "fail"  > /dev/null; then
+        exp=1
+    else
+        exp=0
+    fi
+
+    ${v} cat $t/outfile.txt
+    if [ $res -eq $exp ]; then
+        echo "[PASS] ${test}"
+        echo
+        rm -f $t/outfile.txt
+    else
+        echo
+        cat $t/outfile.txt
+        echo
+        echo "[FAIL] ${test}"
+        echo
+        fails=$(($fails+1))
+    fi
+}
+
+codesign=${codesign:-codesign}
+
+editTest () {
+    name="$1"
+    shift
+    target="$1"
+    shift
+
+    rm -f $t/cms
+
+    runTest validate-$name $codesign -v -R="anchor apple" -v "$target"
+    runTest dump-cms-$name $codesign -d --dump-cms=$t/cms "$target"
+    runTest edit-nonsense-into-cms-$name $codesign -e "$target" --edit-cms /etc/hosts
+    runTest fail-nonsense-validation-$name $codesign -v -R="anchor apple" -v "$target"
+    runTest edit-original-into-cms-$name $codesign -e "$target" --edit-cms $t/cms
+    runTest success-cms-validation-$name $codesign -v -R="anchor apple" -v "$target"
+    runTest edit-cat-cms-into-cms-$name $codesign -e "$target" --edit-cms $t/cat.cms
+    runTest fail-cat-cms-validation-$name $codesign -v -R="anchor apple" -v "$target"
+    runTest edit-original-again-into-cms-$name $codesign -e "$target" --edit-cms $t/cms
+    runTest success-cms-validation-again-$name $codesign -v -R="anchor apple" -v "$target"
+}
+
+runTest dump-cat-cms $codesign -d --dump-cms=$t/cat.cms /bin/cat
+
+runTest prepare-ls cp -R /bin/ls $t/ls
+editTest ls $t/ls
+runTest prepare-TextEdit cp -R /Applications/TextEdit.app $t/TextEdit.app
+editTest TextEdit $t/TextEdit.app
+
+runTest prepare-codeless cp -R /var/db/gke.bundle $t/gke.bundle
+editTest codeless $t/gke.bundle
+
+runTest codesign-remove-signature $codesign --remove $t/ls
+runTest codesign-omit-adhoc $codesign -s - -f --omit-adhoc-flag $t/ls
+runTest adhoc-omitted sh -c "$codesign -d -v $t/ls 2>&1| grep -F 'flags=0x0(none)'"
+
+# cleanup
+
+if [ $fails != 0 ] ; then
+    echo "$fails signature edit tests failed"
+    exit 1
+else
+    echo "all signature edit tests passed"
+    rm -rf $t
+fi
+
+exit 0
index 1fb5b36f6a2a45dea48df318eeacb75439d37645..09b9eb843da6aafac011d3cfb45f4c86388bc2e2 100644 (file)
@@ -17,7 +17,8 @@ INFOPLIST_FILE = OSX/lib/Info-Security.plist
 
 INSTALL_PATH = $(SYSTEM_LIBRARY_DIR)/Frameworks
 
 
 INSTALL_PATH = $(SYSTEM_LIBRARY_DIR)/Frameworks
 
-OTHER_LDFLAGS = -laks -lCrashReporterClient -Wl,-upward_framework,Foundation -Wl,-no_inits
+ASAN_EXTRA_LDFLAGS_YES = -Wl,-no_warn_inits
+OTHER_LDFLAGS = -laks -lCrashReporterClient -Wl,-upward_framework,Foundation -Wl,-no_inits $(ASAN_EXTRA_LDFLAGS_$(ENABLE_ADDRESS_SANITIZER))
 
 SECTORDER_FLAGS = -order_file_statistics
 APPLY_RULES_IN_COPY_FILES = NO
 
 SECTORDER_FLAGS = -order_file_statistics
 APPLY_RULES_IN_COPY_FILES = NO
index be200db38dcb20992a5935a1252693c64340672a..a7e46bcd4b384e6308cef5dc9d839909ea125cf1 100644 (file)
@@ -40,11 +40,26 @@ request(xpc_connection_t peer, xpc_object_t event)
        if (pid <= 0)
                return;
        
        if (pid <= 0)
                return;
        
+       size_t audit_size;
+       audit_token_t const *audit =
+               (audit_token_t const *)xpc_dictionary_get_data(event, "audit", &audit_size);
+       
+       if (audit != NULL && audit_size != sizeof(audit_token_t)) {
+               Syslog::error("audit token has unexpected size %zu", audit_size);
+               return;
+       }
+       
        xpc_object_t reply = xpc_dictionary_create_reply(event);
        if (reply == NULL)
                return;
        
        xpc_object_t reply = xpc_dictionary_create_reply(event);
        if (reply == NULL)
                return;
        
-       CFTemp<CFDictionaryRef> attributes("{%O=%d}", kSecGuestAttributePid, pid);
+       CFTemp<CFMutableDictionaryRef> attributes("{%O=%d}", kSecGuestAttributePid, pid);
+    
+       if (audit != NULL) {
+               CFRef<CFDataRef> auditData = makeCFData(audit, audit_size);
+               CFDictionaryAddValue(attributes.get(), kSecGuestAttributeAudit,
+                                                        auditData);
+       }
        CFRef<SecCodeRef> code;
        if ((rc = SecCodeCopyGuestWithAttributes(NULL, attributes, kSecCSDefaultFlags, &code.aref())) == noErr) {
                
        CFRef<SecCodeRef> code;
        if ((rc = SecCodeCopyGuestWithAttributes(NULL, attributes, kSecCSDefaultFlags, &code.aref())) == noErr) {
                
index c40495e310d3cc062866e2ec05a4250dbca131f0..b58bd35456d2755865e0d2afd40838781609be4a 100644 (file)
@@ -40,7 +40,15 @@ CharBuffer::CharBuffer(ANTLR_USE_NAMESPACE(std)istream& input_)
 int CharBuffer::getChar()
 {
 //     try {
 int CharBuffer::getChar()
 {
 //     try {
-               return input.get();
+    int i = input.get();
+    
+    if (i == -1) {
+        // pass through EOF
+        return -1;
+    }
+    
+    // prevent negative-valued characters through sign extension of high-bit characters
+    return static_cast<int>(static_cast<unsigned char>(i));
 //     }
 //     catch (ANTLR_USE_NAMESPACE(std)ios_base::failure& e) {
 //             throw CharStreamIOException(e);
 //     }
 //     catch (ANTLR_USE_NAMESPACE(std)ios_base::failure& e) {
 //             throw CharStreamIOException(e);
index 84383ca6214074f85b5e57554aeeb1722228109e..bc11737f28fc70528b10f54b4db77f34cc580abf 100644 (file)
@@ -170,8 +170,9 @@ std::string SecCodeSigner::getTeamIDFromSigner(CFArrayRef certs)
 //
 bool SecCodeSigner::valid() const
 {
 //
 bool SecCodeSigner::valid() const
 {
-       if (mOpFlags & kSecCSRemoveSignature)
+       if (mOpFlags & (kSecCSRemoveSignature | kSecCSEditSignature)) {
                return true;
                return true;
+       }
        return mSigner;
 }
 
        return mSigner;
 }
 
@@ -188,6 +189,9 @@ void SecCodeSigner::sign(SecStaticCode *code, SecCSFlags flags)
        if ((flags | mOpFlags) & kSecCSRemoveSignature) {
                secinfo("signer", "%p will remove signature from %p", this, code);
                operation.remove(flags);
        if ((flags | mOpFlags) & kSecCSRemoveSignature) {
                secinfo("signer", "%p will remove signature from %p", this, code);
                operation.remove(flags);
+       } else if ((flags | mOpFlags) & kSecCSEditSignature) {
+               secinfo("signer", "%p will edit signature of %p", this, code);
+               operation.edit(flags);
        } else {
                if (!valid())
                        MacOSError::throwMe(errSecCSInvalidObjectRef);
        } else {
                if (!valid())
                        MacOSError::throwMe(errSecCSInvalidObjectRef);
@@ -229,6 +233,29 @@ void SecCodeSigner::returnDetachedSignature(BlobCore *blob, Signer &signer)
 SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters)
        : CFDictionary(parameters, errSecCSBadDictionaryFormat)
 {
 SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters)
        : CFDictionary(parameters, errSecCSBadDictionaryFormat)
 {
+       CFNumberRef editCpuType = get<CFNumberRef>(kSecCodeSignerEditCpuType);
+       CFNumberRef editCpuSubtype = get<CFNumberRef>(kSecCodeSignerEditCpuSubtype);
+       if (editCpuType != NULL && editCpuSubtype != NULL) {
+               state.mEditArch = Architecture(cfNumber<uint32_t>(editCpuType),
+                                                                          cfNumber<uint32_t>(editCpuSubtype));
+       }
+       
+       state.mEditCMS = get<CFDataRef>(kSecCodeSignerEditCMS);
+       
+       state.mDryRun = getBool(kSecCodeSignerDryRun);
+       
+       state.mSDKRoot = get<CFURLRef>(kSecCodeSignerSDKRoot);
+       
+       state.mPreserveAFSC = getBool(kSecCodeSignerPreserveAFSC);
+       
+       if (state.mOpFlags & kSecCSEditSignature) {
+               return;
+               /* Everything below this point is irrelevant for
+                * Signature Editing, which does not create any
+                * parts of the signature, only replaces them.
+                */
+       }
+
        // the signer may be an identity or null
        state.mSigner = SecIdentityRef(get<CFTypeRef>(kSecCodeSignerIdentity));
        if (state.mSigner)
        // the signer may be an identity or null
        state.mSigner = SecIdentityRef(get<CFTypeRef>(kSecCodeSignerIdentity));
        if (state.mSigner)
@@ -305,15 +332,11 @@ SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters)
                        MacOSError::throwMe(errSecCSInvalidObjectRef);
        }
        
                        MacOSError::throwMe(errSecCSInvalidObjectRef);
        }
        
-       state.mDryRun = getBool(kSecCodeSignerDryRun);
-
        state.mResourceRules = get<CFDictionaryRef>(kSecCodeSignerResourceRules);
        
        state.mApplicationData = get<CFDataRef>(kSecCodeSignerApplicationData);
        state.mEntitlementData = get<CFDataRef>(kSecCodeSignerEntitlements);
        
        state.mResourceRules = get<CFDictionaryRef>(kSecCodeSignerResourceRules);
        
        state.mApplicationData = get<CFDataRef>(kSecCodeSignerApplicationData);
        state.mEntitlementData = get<CFDataRef>(kSecCodeSignerEntitlements);
        
-       state.mSDKRoot = get<CFURLRef>(kSecCodeSignerSDKRoot);
-    
        if (CFBooleanRef timestampRequest = get<CFBooleanRef>(kSecCodeSignerRequireTimestamp)) {
                state.mWantTimeStamp = timestampRequest == kCFBooleanTrue;
        } else {        // pick default
        if (CFBooleanRef timestampRequest = get<CFBooleanRef>(kSecCodeSignerRequireTimestamp)) {
                state.mWantTimeStamp = timestampRequest == kCFBooleanTrue;
        } else {        // pick default
@@ -336,7 +359,10 @@ SecCodeSigner::Parser::Parser(SecCodeSigner &state, CFDictionaryRef parameters)
                }
                state.mRuntimeVersionOverride = parseRuntimeVersion(runtime);
        }
                }
                state.mRuntimeVersionOverride = parseRuntimeVersion(runtime);
        }
-       state.mPreserveAFSC = getBool(kSecCodeSignerPreserveAFSC);
+       
+       // Don't add the adhoc flag, even if no signer identity was specified.
+       // Useful for editing in the CMS at a later point.
+       state.mOmitAdhocFlag = getBool(kSecCodeSignerOmitAdhocFlag);
 }
 
 
 }
 
 
index d8888f09f791efe509f7b7d2db7b890dd06a0ade..099d18c7e33edf1d0edd30ca982c97d8ad4b4091 100644 (file)
@@ -95,7 +95,12 @@ public:
        LimitedAsync *mLimitedAsync;    // limited async workers for verification
        uint32_t mRuntimeVersionOverride;       // runtime Version Override
        bool mPreserveAFSC;             // preserve AFSC compression
        LimitedAsync *mLimitedAsync;    // limited async workers for verification
        uint32_t mRuntimeVersionOverride;       // runtime Version Override
        bool mPreserveAFSC;             // preserve AFSC compression
+       bool mOmitAdhocFlag;                    // don't add adhoc flag, even without signer identity
 
 
+       // Signature Editing
+       Architecture mEditArch;                 // architecture to edit (defaults to all if empty)
+       CFRef<CFDataRef> mEditCMS;              // CMS to replace in the signature
+       
 };
 
 
 };
 
 
index 83296a4ae7b312860e525e273e9dda9a3bdf6597..646bfaae8452d9a65da72cbe0ea19c9449d5d23d 100644 (file)
@@ -703,156 +703,25 @@ void RequirementLexer::mSTRING(bool _createToken) {
        text.erase(_saveIndex);
        { // ( ... )*
        for (;;) {
        text.erase(_saveIndex);
        { // ( ... )*
        for (;;) {
-               switch ( LA(1)) {
-               case 0x5c /* '\\' */ :
-               {
+               if ((LA(1) == 0x5c /* '\\' */ )) {
                        {
                        _saveIndex = text.length();
                        match('\\' /* charlit */ );
                        text.erase(_saveIndex);
                        match('\"' /* charlit */ );
                        }
                        {
                        _saveIndex = text.length();
                        match('\\' /* charlit */ );
                        text.erase(_saveIndex);
                        match('\"' /* charlit */ );
                        }
-                       break;
                }
                }
-               case 0x0 /* '\0' */ :
-               case 0x1 /* '\1' */ :
-               case 0x2 /* '\2' */ :
-               case 0x3 /* '\3' */ :
-               case 0x4 /* '\4' */ :
-               case 0x5 /* '\5' */ :
-               case 0x6 /* '\6' */ :
-               case 0x7 /* '\7' */ :
-               case 0x8 /* '\10' */ :
-               case 0x9 /* '\t' */ :
-               case 0xa /* '\n' */ :
-               case 0xb /* '\13' */ :
-               case 0xc /* '\14' */ :
-               case 0xd /* '\r' */ :
-               case 0xe /* '\16' */ :
-               case 0xf /* '\17' */ :
-               case 0x10 /* '\20' */ :
-               case 0x11 /* '\21' */ :
-               case 0x12 /* '\22' */ :
-               case 0x13 /* '\23' */ :
-               case 0x14 /* '\24' */ :
-               case 0x15 /* '\25' */ :
-               case 0x16 /* '\26' */ :
-               case 0x17 /* '\27' */ :
-               case 0x18 /* '\30' */ :
-               case 0x19 /* '\31' */ :
-               case 0x1a /* '\32' */ :
-               case 0x1b /* '\33' */ :
-               case 0x1c /* '\34' */ :
-               case 0x1d /* '\35' */ :
-               case 0x1e /* '\36' */ :
-               case 0x1f /* '\37' */ :
-               case 0x20 /* ' ' */ :
-               case 0x21 /* '!' */ :
-               case 0x23 /* '#' */ :
-               case 0x24 /* '$' */ :
-               case 0x25 /* '%' */ :
-               case 0x26 /* '&' */ :
-               case 0x27 /* '\'' */ :
-               case 0x28 /* '(' */ :
-               case 0x29 /* ')' */ :
-               case 0x2a /* '*' */ :
-               case 0x2b /* '+' */ :
-               case 0x2c /* ',' */ :
-               case 0x2d /* '-' */ :
-               case 0x2e /* '.' */ :
-               case 0x2f /* '/' */ :
-               case 0x30 /* '0' */ :
-               case 0x31 /* '1' */ :
-               case 0x32 /* '2' */ :
-               case 0x33 /* '3' */ :
-               case 0x34 /* '4' */ :
-               case 0x35 /* '5' */ :
-               case 0x36 /* '6' */ :
-               case 0x37 /* '7' */ :
-               case 0x38 /* '8' */ :
-               case 0x39 /* '9' */ :
-               case 0x3a /* ':' */ :
-               case 0x3b /* ';' */ :
-               case 0x3c /* '<' */ :
-               case 0x3d /* '=' */ :
-               case 0x3e /* '>' */ :
-               case 0x3f /* '?' */ :
-               case 0x40 /* '@' */ :
-               case 0x41 /* 'A' */ :
-               case 0x42 /* 'B' */ :
-               case 0x43 /* 'C' */ :
-               case 0x44 /* 'D' */ :
-               case 0x45 /* 'E' */ :
-               case 0x46 /* 'F' */ :
-               case 0x47 /* 'G' */ :
-               case 0x48 /* 'H' */ :
-               case 0x49 /* 'I' */ :
-               case 0x4a /* 'J' */ :
-               case 0x4b /* 'K' */ :
-               case 0x4c /* 'L' */ :
-               case 0x4d /* 'M' */ :
-               case 0x4e /* 'N' */ :
-               case 0x4f /* 'O' */ :
-               case 0x50 /* 'P' */ :
-               case 0x51 /* 'Q' */ :
-               case 0x52 /* 'R' */ :
-               case 0x53 /* 'S' */ :
-               case 0x54 /* 'T' */ :
-               case 0x55 /* 'U' */ :
-               case 0x56 /* 'V' */ :
-               case 0x57 /* 'W' */ :
-               case 0x58 /* 'X' */ :
-               case 0x59 /* 'Y' */ :
-               case 0x5a /* 'Z' */ :
-               case 0x5b /* '[' */ :
-               case 0x5d /* ']' */ :
-               case 0x5e /* '^' */ :
-               case 0x5f /* '_' */ :
-               case 0x60 /* '`' */ :
-               case 0x61 /* 'a' */ :
-               case 0x62 /* 'b' */ :
-               case 0x63 /* 'c' */ :
-               case 0x64 /* 'd' */ :
-               case 0x65 /* 'e' */ :
-               case 0x66 /* 'f' */ :
-               case 0x67 /* 'g' */ :
-               case 0x68 /* 'h' */ :
-               case 0x69 /* 'i' */ :
-               case 0x6a /* 'j' */ :
-               case 0x6b /* 'k' */ :
-               case 0x6c /* 'l' */ :
-               case 0x6d /* 'm' */ :
-               case 0x6e /* 'n' */ :
-               case 0x6f /* 'o' */ :
-               case 0x70 /* 'p' */ :
-               case 0x71 /* 'q' */ :
-               case 0x72 /* 'r' */ :
-               case 0x73 /* 's' */ :
-               case 0x74 /* 't' */ :
-               case 0x75 /* 'u' */ :
-               case 0x76 /* 'v' */ :
-               case 0x77 /* 'w' */ :
-               case 0x78 /* 'x' */ :
-               case 0x79 /* 'y' */ :
-               case 0x7a /* 'z' */ :
-               case 0x7b /* '{' */ :
-               case 0x7c /* '|' */ :
-               case 0x7d /* '}' */ :
-               case 0x7e /* '~' */ :
-               case 0x7f:
-               {
+               else if ((_tokenSet_2.member(LA(1)))) {
                        {
                        {
                        match(_tokenSet_2);
                        }
                        }
                        {
                        {
                        match(_tokenSet_2);
                        }
                        }
-                       break;
                }
                }
-               default:
-               {
+               else {
                        goto _loop66;
                }
                        goto _loop66;
                }
-               }
+               
        }
        _loop66:;
        } // ( ... )*
        }
        _loop66:;
        } // ( ... )*
@@ -1241,30 +1110,30 @@ void RequirementLexer::mCPP_COMMENT(bool _createToken) {
 }
 
 
 }
 
 
-const unsigned long RequirementLexer::_tokenSet_0_data_[] = { 0UL, 0UL, 134217726UL, 134217726UL, 0UL, 0UL, 0UL, 0UL };
-const antlr::BitSet RequirementLexer::_tokenSet_0(_tokenSet_0_data_,8);
-const unsigned long RequirementLexer::_tokenSet_1_data_[] = { 0UL, 67043328UL, 126UL, 126UL, 0UL, 0UL, 0UL, 0UL };
+const unsigned long RequirementLexer::_tokenSet_0_data_[] = { 0UL, 0UL, 134217726UL, 134217726UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL };
+const antlr::BitSet RequirementLexer::_tokenSet_0(_tokenSet_0_data_,10);
+const unsigned long RequirementLexer::_tokenSet_1_data_[] = { 0UL, 67043328UL, 126UL, 126UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL };
 // 0 1 2 3 4 5 6 7 8 9 
 // 0 1 2 3 4 5 6 7 8 9 
-const antlr::BitSet RequirementLexer::_tokenSet_1(_tokenSet_1_data_,8);
-const unsigned long RequirementLexer::_tokenSet_2_data_[] = { 4294967295UL, 4294967291UL, 4026531839UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL };
+const antlr::BitSet RequirementLexer::_tokenSet_1(_tokenSet_1_data_,10);
+const unsigned long RequirementLexer::_tokenSet_2_data_[] = { 4294967295UL, 4294967291UL, 4026531839UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967292UL, 2097151UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL };
 // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 
 // 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 
 // 0x1f   ! # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : 
 // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 
 // 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 
 // 0x1f   ! # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : 
-const antlr::BitSet RequirementLexer::_tokenSet_2(_tokenSet_2_data_,8);
-const unsigned long RequirementLexer::_tokenSet_3_data_[] = { 4294966271UL, 4294967295UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL };
+const antlr::BitSet RequirementLexer::_tokenSet_2(_tokenSet_2_data_,16);
+const unsigned long RequirementLexer::_tokenSet_3_data_[] = { 4294966271UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967292UL, 2097151UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL };
 // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xd 0xe 0xf 0x10 0x11 
 // 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 
 //   ! \" # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : 
 // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xd 0xe 0xf 0x10 0x11 
 // 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 
 //   ! \" # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : 
-const antlr::BitSet RequirementLexer::_tokenSet_3(_tokenSet_3_data_,8);
-const unsigned long RequirementLexer::_tokenSet_4_data_[] = { 4294967295UL, 4294934527UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL };
+const antlr::BitSet RequirementLexer::_tokenSet_3(_tokenSet_3_data_,16);
+const unsigned long RequirementLexer::_tokenSet_4_data_[] = { 4294967295UL, 4294934527UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967292UL, 2097151UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL };
 // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 
 // 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 
 // 0x1f   ! \" # $ % & \' ( ) * + , - . 0 1 2 3 4 5 6 7 8 9 : 
 // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 
 // 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 
 // 0x1f   ! \" # $ % & \' ( ) * + , - . 0 1 2 3 4 5 6 7 8 9 : 
-const antlr::BitSet RequirementLexer::_tokenSet_4(_tokenSet_4_data_,8);
-const unsigned long RequirementLexer::_tokenSet_5_data_[] = { 4294967295UL, 4294966271UL, 4294967295UL, 4294967295UL, 0UL, 0UL, 0UL, 0UL };
+const antlr::BitSet RequirementLexer::_tokenSet_4(_tokenSet_4_data_,16);
+const unsigned long RequirementLexer::_tokenSet_5_data_[] = { 4294967295UL, 4294966271UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967292UL, 2097151UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL };
 // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 
 // 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 
 // 0x1f   ! \" # $ % & \' ( ) + , - . / 0 1 2 3 4 5 6 7 8 9 : 
 // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 
 // 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 
 // 0x1f   ! \" # $ % & \' ( ) + , - . / 0 1 2 3 4 5 6 7 8 9 : 
-const antlr::BitSet RequirementLexer::_tokenSet_5(_tokenSet_5_data_,8);
+const antlr::BitSet RequirementLexer::_tokenSet_5(_tokenSet_5_data_,16);
 
 ANTLR_END_NAMESPACE
 
 ANTLR_END_NAMESPACE
index f3269c91f3b2fab196258958d089d41815329f2f..dac2376cd6d282fd170b8511b65856b88780b3da 100644 (file)
@@ -179,7 +179,8 @@ OSStatus SecCodeCopyGuestWithAttributes(SecCodeRef hostRef,
 
 
 //
 
 
 //
-// Shorthand for getting the SecCodeRef for a UNIX process
+// Deprecated since 10.6, DO NOT USE. This can be raced.
+// Use SecCodeCreateWithAuditToken instead.
 //
 OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *processRef)
 {
 //
 OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *processRef)
 {
@@ -193,6 +194,25 @@ OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *processRe
 
        END_CSAPI
 }
 
        END_CSAPI
 }
+
+//
+// Shorthand for getting the SecCodeRef for a UNIX process
+//
+OSStatus SecCodeCreateWithAuditToken(const audit_token_t *audit,
+                                                                        SecCSFlags flags, SecCodeRef *processRef)
+{
+       BEGIN_CSAPI
+       
+       checkFlags(flags);
+       CFRef<CFDataRef> auditData = makeCFData(audit, sizeof(audit_token_t));
+       if (SecCode *guest = KernelCode::active()->locateGuest(CFTemp<CFDictionaryRef>("{%O=%O}", kSecGuestAttributeAudit, auditData.get()))) {
+               CodeSigning::Required(processRef) = guest->handle(false);
+       } else {
+               return errSecCSNoSuchCode;
+       }
+       
+       END_CSAPI
+}
 #endif // TARGET_OS_OSX
 
 
 #endif // TARGET_OS_OSX
 
 
@@ -258,14 +278,16 @@ const CFStringRef kSecCodeInfoTimestamp =         CFSTR("signing-timestamp");
 const CFStringRef kSecCodeInfoTrust =                  CFSTR("trust");
 const CFStringRef kSecCodeInfoUnique =                 CFSTR("unique");
 const CFStringRef kSecCodeInfoCdHashes =        CFSTR("cdhashes");
 const CFStringRef kSecCodeInfoTrust =                  CFSTR("trust");
 const CFStringRef kSecCodeInfoUnique =                 CFSTR("unique");
 const CFStringRef kSecCodeInfoCdHashes =        CFSTR("cdhashes");
+const CFStringRef kSecCodeInfoCdHashesFull =   CFSTR("cdhashes-full");
 const CFStringRef kSecCodeInfoRuntimeVersion =         CFSTR("runtime-version");
 
 const CFStringRef kSecCodeInfoRuntimeVersion =         CFSTR("runtime-version");
 
-
 const CFStringRef kSecCodeInfoCodeDirectory =  CFSTR("CodeDirectory");
 const CFStringRef kSecCodeInfoCodeOffset =             CFSTR("CodeOffset");
 const CFStringRef kSecCodeInfoDiskRepInfo =     CFSTR("DiskRepInfo");
 const CFStringRef kSecCodeInfoResourceDirectory = CFSTR("ResourceDirectory");
 const CFStringRef kSecCodeInfoNotarizationDate = CFSTR("NotarizationDate");
 const CFStringRef kSecCodeInfoCodeDirectory =  CFSTR("CodeDirectory");
 const CFStringRef kSecCodeInfoCodeOffset =             CFSTR("CodeOffset");
 const CFStringRef kSecCodeInfoDiskRepInfo =     CFSTR("DiskRepInfo");
 const CFStringRef kSecCodeInfoResourceDirectory = CFSTR("ResourceDirectory");
 const CFStringRef kSecCodeInfoNotarizationDate = CFSTR("NotarizationDate");
+const CFStringRef kSecCodeInfoCMSDigestHashType = CFSTR("CMSDigestHashType");
+const CFStringRef kSecCodeInfoCMSDigest =        CFSTR("CMSDigest");
 
 /* DiskInfoRepInfo types */
 const CFStringRef kSecCodeInfoDiskRepVersionPlatform =         CFSTR("VersionPlatform");
 
 /* DiskInfoRepInfo types */
 const CFStringRef kSecCodeInfoDiskRepVersionPlatform =         CFSTR("VersionPlatform");
@@ -285,7 +307,8 @@ OSStatus SecCodeCopySigningInformation(SecStaticCodeRef codeRef, SecCSFlags flag
                | kSecCSRequirementInformation
                | kSecCSDynamicInformation
                | kSecCSContentInformation
                | kSecCSRequirementInformation
                | kSecCSDynamicInformation
                | kSecCSContentInformation
-        | kSecCSSkipResourceDirectory);
+        | kSecCSSkipResourceDirectory
+               | kSecCSCalculateCMSDigest);
 
        SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
        CFRef<CFDictionaryRef> info = code->signingInformation(flags);
 
        SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
        CFRef<CFDictionaryRef> info = code->signingInformation(flags);
index b1a6afbc1b5f498cae1dfc7826fb846a7e27871b..5ccfb17051aa528ef504c20df6117286280356f4 100644 (file)
@@ -427,7 +427,8 @@ CF_ENUM(uint32_t) {
        kSecCSRequirementInformation = 1 << 2,
        kSecCSDynamicInformation = 1 << 3,
        kSecCSContentInformation = 1 << 4,
        kSecCSRequirementInformation = 1 << 2,
        kSecCSDynamicInformation = 1 << 3,
        kSecCSContentInformation = 1 << 4,
-    kSecCSSkipResourceDirectory = 1 << 5
+    kSecCSSkipResourceDirectory = 1 << 5,
+    kSecCSCalculateCMSDigest = 1 << 6,
 };
                                                                                                        /* flag required to get this value */
 extern const CFStringRef kSecCodeInfoCertificates;     /* Signing */
 };
                                                                                                        /* flag required to get this value */
 extern const CFStringRef kSecCodeInfoCertificates;     /* Signing */
index 4073c23f488645d631de409f201b7a77d643ba92..3bce444bde38eed5e469422445931375bfcffff4 100644 (file)
@@ -38,13 +38,15 @@ extern "C" {
 
 /*
  *     Private constants for SecCodeCopySigningInformation.
 
 /*
  *     Private constants for SecCodeCopySigningInformation.
- *     These are returned with the 
  */
  */
+extern const CFStringRef kSecCodeInfoCdHashesFull;          /* Internal */
 extern const CFStringRef kSecCodeInfoCodeDirectory;                    /* Internal */
 extern const CFStringRef kSecCodeInfoCodeOffset;                       /* Internal */
 extern const CFStringRef kSecCodeInfoDiskRepInfo;           /* Internal */
 extern const CFStringRef kSecCodeInfoResourceDirectory;                /* Internal */
 extern const CFStringRef kSecCodeInfoNotarizationDate;      /* Internal */
 extern const CFStringRef kSecCodeInfoCodeDirectory;                    /* Internal */
 extern const CFStringRef kSecCodeInfoCodeOffset;                       /* Internal */
 extern const CFStringRef kSecCodeInfoDiskRepInfo;           /* Internal */
 extern const CFStringRef kSecCodeInfoResourceDirectory;                /* Internal */
 extern const CFStringRef kSecCodeInfoNotarizationDate;      /* Internal */
+extern const CFStringRef kSecCodeInfoCMSDigestHashType;     /* Internal */
+extern const CFStringRef kSecCodeInfoCMSDigest;             /* Internal */
 
 extern const CFStringRef kSecCodeInfoDiskRepVersionPlatform;     /* Number */
 extern const CFStringRef kSecCodeInfoDiskRepVersionMin;          /* Number */
 
 extern const CFStringRef kSecCodeInfoDiskRepVersionPlatform;     /* Number */
 extern const CFStringRef kSecCodeInfoDiskRepVersionMin;          /* Number */
@@ -129,21 +131,23 @@ OSStatus SecCodeCopyInternalRequirement(SecStaticCodeRef code, SecRequirementTyp
 
 #if TARGET_OS_OSX
 /*!
 
 #if TARGET_OS_OSX
 /*!
-       @function SecCodeCreateWithPID
+       @function SecCodeCreateWithAuditToken
        Asks the kernel to return a SecCode object for a process identified
        Asks the kernel to return a SecCode object for a process identified
-       by a UNIX process id (pid). This is a shorthand for asking SecGetRootCode()
-       for a guest whose "pid" attribute has the given pid value.
+       by a UNIX audit token. This is a shorthand for asking SecGetRootCode()
+       for a guest whose "audit" attribute has the given audit token.
        
        
-       This is a deprecated convenience function.
-       Call SecCodeCopyGuestWithAttributes instead.
-       
-       @param pid A process id for an existing UNIX process on the system.
+       @param audit A process audit token for an existing UNIX process on the system.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param process On successful return, a SecCode object reference identifying
        the requesteed process.
        @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
        @param process On successful return, a SecCode object reference identifying
        the requesteed process.
        @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        CSCommon.h or certain other Security framework headers.
 */
+OSStatus SecCodeCreateWithAuditToken(const audit_token_t *audit,
+                                     SecCSFlags flags, SecCodeRef *process)
+    AVAILABLE_MAC_OS_X_VERSION_10_14_4_AND_LATER;
+    
+/* Deprecated and unsafe, DO NOT USE. */
 OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *process)
        AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6;
 #endif
 OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *process)
        AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6;
 #endif
index a7e31f657312053d8505c0114664d00b3426c6dc..7e09f760496128dd1d5ee2e0063a17d7da80e700 100644 (file)
@@ -60,7 +60,13 @@ const CFStringRef kSecCodeSignerPreserveMetadata = CFSTR("preserve-metadata");
 const CFStringRef kSecCodeSignerTeamIdentifier =       CFSTR("teamidentifier");
 const CFStringRef kSecCodeSignerPlatformIdentifier = CFSTR("platform-identifier");
 const CFStringRef kSecCodeSignerRuntimeVersion = CFSTR("runtime-version");
 const CFStringRef kSecCodeSignerTeamIdentifier =       CFSTR("teamidentifier");
 const CFStringRef kSecCodeSignerPlatformIdentifier = CFSTR("platform-identifier");
 const CFStringRef kSecCodeSignerRuntimeVersion = CFSTR("runtime-version");
-const CFStringRef kSecCodeSignerPreserveAFSC = CFSTR("preserve-afsc");
+const CFStringRef kSecCodeSignerPreserveAFSC =         CFSTR("preserve-afsc");
+const CFStringRef kSecCodeSignerOmitAdhocFlag =        CFSTR("omit-adhoc-flag");
+
+// Keys for signature editing
+const CFStringRef kSecCodeSignerEditCpuType =  CFSTR("edit-cpu-type");
+const CFStringRef kSecCodeSignerEditCpuSubtype = CFSTR("edit-cpu-subtype");
+const CFStringRef kSecCodeSignerEditCMS =              CFSTR("edit-cms");
 
 
 
 
 
 
@@ -84,7 +90,8 @@ OSStatus SecCodeSignerCreate(CFDictionaryRef parameters, SecCSFlags flags,
        BEGIN_CSAPI
                
        checkFlags(flags,
        BEGIN_CSAPI
                
        checkFlags(flags,
-                 kSecCSRemoveSignature
+                 kSecCSEditSignature
+               | kSecCSRemoveSignature
                | kSecCSSignPreserveSignature
                | kSecCSSignNestedCode
                | kSecCSSignOpaque
                | kSecCSSignPreserveSignature
                | kSecCSSignNestedCode
                | kSecCSSignOpaque
index 2da5670f1d817cd6073d372a92e06a38e00a7cd8..eba1183066b0226d3e772f4de680ccd918d79891 100644 (file)
@@ -165,6 +165,10 @@ extern const CFStringRef kSecCodeSignerTeamIdentifier;
 extern const CFStringRef kSecCodeSignerPlatformIdentifier;
 extern const CFStringRef kSecCodeSignerRuntimeVersion;
 extern const CFStringRef kSecCodeSignerPreserveAFSC;
 extern const CFStringRef kSecCodeSignerPlatformIdentifier;
 extern const CFStringRef kSecCodeSignerRuntimeVersion;
 extern const CFStringRef kSecCodeSignerPreserveAFSC;
+extern const CFStringRef kSecCodeSignerOmitAdhocFlag;
+extern const CFStringRef kSecCodeSignerEditCpuType;
+extern const CFStringRef kSecCodeSignerEditCpuSubtype;
+extern const CFStringRef kSecCodeSignerEditCMS;
 
 enum {
     kSecCodeSignerPreserveIdentifier = 1 << 0,         // preserve signing identifier
 
 enum {
     kSecCodeSignerPreserveIdentifier = 1 << 0,         // preserve signing identifier
@@ -189,7 +193,9 @@ enum {
                useful defaults, and will need to be set before signing is attempted.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
                The kSecCSRemoveSignature flag requests that any existing signature be stripped
                useful defaults, and will need to be set before signing is attempted.
        @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior.
                The kSecCSRemoveSignature flag requests that any existing signature be stripped
-               from the target code instead of signing.
+               from the target code instead of signing. The kSecCSEditSignature flag
+        requests editing of existing signatures, which only works with a very
+        limited set of options.
        @param staticCode On successful return, a SecStaticCode object reference representing
        the file system origin of the given SecCode. On error, unchanged.
        @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
        @param staticCode On successful return, a SecStaticCode object reference representing
        the file system origin of the given SecCode. On error, unchanged.
        @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in
@@ -206,6 +212,7 @@ enum {
        kSecCSSignStrictPreflight = 1 << 7, // fail signing operation if signature would fail strict validation
        kSecCSSignGeneratePEH = 1 << 8,         // generate pre-encryption hashes
     kSecCSSignGenerateEntitlementDER = 1 << 9, // generate entitlement DER
        kSecCSSignStrictPreflight = 1 << 7, // fail signing operation if signature would fail strict validation
        kSecCSSignGeneratePEH = 1 << 8,         // generate pre-encryption hashes
     kSecCSSignGenerateEntitlementDER = 1 << 9, // generate entitlement DER
+    kSecCSEditSignature = 1 << 10,      // edit existing signature
 };
 
 
 };
 
 
index 74038fcc9a25c958338f843957c975d7f0832e8f..5b8b37aef6f3acaf380b4913e303899bf6236972 100644 (file)
@@ -548,6 +548,26 @@ CFArrayRef SecStaticCode::cdHashes()
        return mCDHashes;
 }
 
        return mCDHashes;
 }
 
+//
+// Get a dictionary of untruncated cdhashes for all digest types in this signature.
+//
+CFDictionaryRef SecStaticCode::cdHashesFull()
+{
+       if (!mCDHashFullDict) {
+               CFRef<CFMutableDictionaryRef> cdDict = makeCFMutableDictionary();
+               for (auto const &it : mCodeDirectories) {
+                       CodeDirectory::HashAlgorithm alg = it.first;
+                       const CodeDirectory *cd = (const CodeDirectory *)CFDataGetBytePtr(it.second);
+                       CFRef<CFDataRef> hash = cd->cdhash(false);
+                       if (hash) {
+                               CFDictionaryAddValue(cdDict, CFTempNumber(alg), hash);
+                       }
+               }
+               mCDHashFullDict = cdDict.get();
+       }
+       return mCDHashFullDict;
+}
+
 
 //
 // Return the CMS signature blob; NULL if none found.
 
 //
 // Return the CMS signature blob; NULL if none found.
@@ -1986,6 +2006,7 @@ CFDictionaryRef SecStaticCode::signingInformation(SecCSFlags flags)
        CFDictionaryAddValue(dict, kSecCodeInfoSource, CFTempString(this->signatureSource()));
        CFDictionaryAddValue(dict, kSecCodeInfoUnique, this->cdHash());
        CFDictionaryAddValue(dict, kSecCodeInfoCdHashes, this->cdHashes());
        CFDictionaryAddValue(dict, kSecCodeInfoSource, CFTempString(this->signatureSource()));
        CFDictionaryAddValue(dict, kSecCodeInfoUnique, this->cdHash());
        CFDictionaryAddValue(dict, kSecCodeInfoCdHashes, this->cdHashes());
+       CFDictionaryAddValue(dict, kSecCodeInfoCdHashesFull, this->cdHashesFull());
        const CodeDirectory* cd = this->codeDirectory(false);
        CFDictionaryAddValue(dict, kSecCodeInfoDigestAlgorithm, CFTempNumber(cd->hashType));
        CFRef<CFArrayRef> digests = makeCFArrayFrom(^CFTypeRef(CodeDirectory::HashAlgorithm type) { return CFTempNumber(type); }, hashAlgorithms());
        const CodeDirectory* cd = this->codeDirectory(false);
        CFDictionaryAddValue(dict, kSecCodeInfoDigestAlgorithm, CFTempNumber(cd->hashType));
        CFRef<CFArrayRef> digests = makeCFArrayFrom(^CFTypeRef(CodeDirectory::HashAlgorithm type) { return CFTempNumber(type); }, hashAlgorithms());
@@ -2087,6 +2108,16 @@ CFDictionaryRef SecStaticCode::signingInformation(SecCSFlags flags)
                }
        }
 
                }
        }
 
+       if (flags & kSecCSCalculateCMSDigest) {
+               try {
+                       CFDictionaryAddValue(dict, kSecCodeInfoCMSDigestHashType, CFTempNumber(cmsDigestHashType()));
+                       
+                       CFRef<CFDataRef> cmsDigest = createCmsDigest();
+                       if (cmsDigest) {
+                               CFDictionaryAddValue(dict, kSecCodeInfoCMSDigest, cmsDigest.get());
+                       }
+               } catch (...) { }
+       }
 
        //
        // kSecCSContentInformation adds more information about the physical layout
 
        //
        // kSecCSContentInformation adds more information about the physical layout
@@ -2297,5 +2328,30 @@ bool SecStaticCode::isAppleDeveloperCert(CFArrayRef certs)
        return req->requirement()->validates(ctx);
 }
 
        return req->requirement()->validates(ctx);
 }
 
+CFDataRef SecStaticCode::createCmsDigest()
+{
+       /*
+        * The CMS digest is a hash of the primary (first, most compatible) code directory,
+        * but its hash algorithm is fixed and not related to the code directory's
+        * hash algorithm.
+        */
+       
+       auto it = codeDirectories()->begin();
+       
+       if (it == codeDirectories()->end()) {
+               return NULL;
+       }
+
+       CodeDirectory const * const cd = reinterpret_cast<CodeDirectory const*>(CFDataGetBytePtr(it->second));
+       
+       RefPointer<DynamicHash> hash = cd->hashFor(mCMSDigestHashType);
+       CFMutableDataRef data = CFDataCreateMutable(NULL, hash->digestLength());
+       CFDataSetLength(data, hash->digestLength());
+       hash->update(cd, cd->length());
+       hash->finish(CFDataGetMutableBytePtr(data));
+       
+       return data;
+}
+       
 } // end namespace CodeSigning
 } // end namespace Security
 } // end namespace CodeSigning
 } // end namespace Security
index 2ca6d7da2a23f7d30d059c922706072b5cc99529..567268243d6d3ac10e16c8c0cc492bb4a67f4286 100644 (file)
@@ -125,6 +125,7 @@ public:
        CodeDirectory::HashAlgorithms hashAlgorithms() const { return mHashAlgorithms; }
        CFDataRef cdHash();
        CFArrayRef cdHashes();
        CodeDirectory::HashAlgorithms hashAlgorithms() const { return mHashAlgorithms; }
        CFDataRef cdHash();
        CFArrayRef cdHashes();
+       CFDictionaryRef cdHashesFull();
        CFDataRef signature();
        CFAbsoluteTime signingTime();
        CFAbsoluteTime signingTimestamp();
        CFDataRef signature();
        CFAbsoluteTime signingTime();
        CFAbsoluteTime signingTimestamp();
@@ -205,6 +206,8 @@ public:
 
        void handleOtherArchitectures(void (^handle)(SecStaticCode* other));
 
 
        void handleOtherArchitectures(void (^handle)(SecStaticCode* other));
 
+       uint8_t cmsDigestHashType() const { return mCMSDigestHashType; };
+       CFDataRef createCmsDigest();
 public:
        void staticValidate(SecCSFlags flags, const SecRequirement *req);
        void staticValidateCore(SecCSFlags flags, const SecRequirement *req);
 public:
        void staticValidate(SecCSFlags flags, const SecRequirement *req);
        void staticValidateCore(SecCSFlags flags, const SecRequirement *req);
@@ -233,6 +236,8 @@ private:
        dispatch_once_t mCheckfix30814861builder1_once;
        
 private:
        dispatch_once_t mCheckfix30814861builder1_once;
        
 private:
+       static const uint8_t mCMSDigestHashType = kSecCodeSignatureHashSHA256;
+                                                                               // hash of CMS digest (kSecCodeSignatureHash* constant)
        RefPointer<DiskRep> mRep;                       // on-disk representation
        mutable CodeDirectoryMap mCodeDirectories; // available CodeDirectory blobs by digest type
        mutable CFRef<CFDataRef> mBaseDir;      // the primary CodeDirectory blob (whether it's chosen or not)
        RefPointer<DiskRep> mRep;                       // on-disk representation
        mutable CodeDirectoryMap mCodeDirectories; // available CodeDirectory blobs by digest type
        mutable CFRef<CFDataRef> mBaseDir;      // the primary CodeDirectory blob (whether it's chosen or not)
@@ -284,7 +289,8 @@ private:
        const Requirement *mDesignatedReq;      // cached designated req if we made one up
        CFRef<CFDataRef> mCDHash;                       // hash of chosen CodeDirectory
        CFRef<CFArrayRef> mCDHashes;            // hashes of all CodeDirectories (in digest type code order)
        const Requirement *mDesignatedReq;      // cached designated req if we made one up
        CFRef<CFDataRef> mCDHash;                       // hash of chosen CodeDirectory
        CFRef<CFArrayRef> mCDHashes;            // hashes of all CodeDirectories (in digest type code order)
-       
+       CFRef<CFDictionaryRef> mCDHashFullDict; // untruncated hashes of CodeDirectories (as dictionary)
+
        bool mGotResourceBase;                          // asked mRep for resourceBasePath
        CFRef<CFURLRef> mResourceBase;          // URL form of resource base directory
 
        bool mGotResourceBase;                          // asked mRep for resourceBasePath
        CFRef<CFURLRef> mResourceBase;          // URL form of resource base directory
 
index 0e4dee56b57c36a60e81733cdd26ada6d4ccf54d..306207aae49c355b452df510cd5da85c1f3ad25e 100644 (file)
@@ -49,7 +49,7 @@ private:
 class StringInputStream : public antlr::InputBuffer {
 public:
        StringInputStream(const string &s) : mInput(s), mPos(mInput.begin()) { }
 class StringInputStream : public antlr::InputBuffer {
 public:
        StringInputStream(const string &s) : mInput(s), mPos(mInput.begin()) { }
-       int getChar() { return (mPos == mInput.end()) ? EOF : *mPos++; }
+       int getChar() { return (mPos == mInput.end()) ? EOF : static_cast<unsigned char>(*mPos++); }
 
 private:
        string mInput;
 
 private:
        string mInput;
index b617858180aec950821c5c0701a931bdeb2f92d8..1aa31968cd206b8900f063ce260ec37977f9d9e0 100644 (file)
@@ -363,6 +363,45 @@ CFDataRef BundleDiskRep::component(CodeDirectory::SpecialSlot slot)
        }
 }
 
        }
 }
 
+BundleDiskRep::RawComponentMap BundleDiskRep::createRawComponents()
+{
+       RawComponentMap map;
+
+       /* Those are the slots known to BundleDiskReps.
+        * Unlike e.g. MachOReps, we cannot handle unknown slots,
+        * as we won't know their slot <-> filename mapping.
+        */
+       int const slots[] = {
+               cdCodeDirectorySlot, cdSignatureSlot, cdResourceDirSlot,
+               cdTopDirectorySlot, cdEntitlementSlot, cdEntitlementDERSlot,
+               cdRepSpecificSlot};
+       
+       for (int slot = 0; slot < (int)(sizeof(slots)/sizeof(slots[0])); ++slot) {
+               /* Here, we only handle metaData slots, i.e. slots that
+                * are explicit files in the _CodeSignature directory.
+                * Main executable slots (if the main executable is a
+                * EditableDiskRep) are handled when editing the
+                * main executable's rep explicitly.
+                * There is also an Info.plist slot, which is not a
+                * real part of the code signature.
+                */
+               CFRef<CFDataRef> data = metaData(slot);
+               
+               if (data) {
+                       map[slot] = data;
+               }
+       }
+       
+       for (CodeDirectory::Slot slot = cdAlternateCodeDirectorySlots; slot < cdAlternateCodeDirectoryLimit; ++slot) {
+               CFRef<CFDataRef> data = metaData(slot);
+               
+               if (data) {
+                       map[slot] = data;
+               }
+       }
+       
+       return map;
+}
 
 // Check that all components of this BundleDiskRep come from either the main
 // executable or the _CodeSignature directory (not mix-and-match).
 
 // Check that all components of this BundleDiskRep come from either the main
 // executable or the _CodeSignature directory (not mix-and-match).
index a166a7e005da15895a42416b8f6ebcb1374d4b17..1333505571445880c5811c74c6d8e69e9af19ebe 100644 (file)
@@ -55,14 +55,16 @@ namespace CodeSigning {
 // if it is in Mach-O format, or in files in a _CodeSignature directory if not.
 // This DiskRep supports resource sealing.
 //
 // if it is in Mach-O format, or in files in a _CodeSignature directory if not.
 // This DiskRep supports resource sealing.
 //
-class BundleDiskRep : public DiskRep {
+class BundleDiskRep : public DiskRep, public EditableDiskRep {
 public:
        BundleDiskRep(const char *path, const Context *ctx = NULL);
        BundleDiskRep(CFBundleRef ref, const Context *ctx = NULL);
        ~BundleDiskRep();
        
        CFDataRef component(CodeDirectory::SpecialSlot slot);
 public:
        BundleDiskRep(const char *path, const Context *ctx = NULL);
        BundleDiskRep(CFBundleRef ref, const Context *ctx = NULL);
        ~BundleDiskRep();
        
        CFDataRef component(CodeDirectory::SpecialSlot slot);
+       RawComponentMap createRawComponents();
        CFDataRef identification();
        CFDataRef identification();
+       DiskRep *mainExecRep() const { return mExecRep.get(); };
        std::string mainExecutablePath();
        CFURLRef copyCanonicalPath();
        std::string resourcesRootPath();
        std::string mainExecutablePath();
        CFURLRef copyCanonicalPath();
        std::string resourcesRootPath();
index e3c4240ddb68e1e0d96c686ce9e8e048f9a0818f..7fefc1c5e190a2363215dbb455340450a7bec8db 100644 (file)
@@ -80,13 +80,18 @@ void CodeDirectory::Builder::executable(string path,
 
 void CodeDirectory::Builder::reopen(string path, size_t offset, size_t length)
 {
 
 void CodeDirectory::Builder::reopen(string path, size_t offset, size_t length)
 {
-       assert(mExec);                                  // already called executable()
+       assert(opened());                                       // already called executable()
        mExec.close();
        mExec.open(path);
        mExecOffset = offset;
        mExecLength = length;
 }
 
        mExec.close();
        mExec.open(path);
        mExecOffset = offset;
        mExecLength = length;
 }
 
+bool CodeDirectory::Builder::opened()
+{
+       return bool(mExec);
+}
+
 
 //
 // Set the source for one special slot
 
 //
 // Set the source for one special slot
index 7872fd58a2c1afb2ea885109ecd8815aaf2053bd..7137444ce9a3e7798f315a1d6eb8d97f79d6aa4b 100644 (file)
@@ -49,6 +49,7 @@ public:
        
        void executable(string path, size_t pagesize, size_t offset, size_t length);
        void reopen(string path, size_t offset, size_t length);
        
        void executable(string path, size_t pagesize, size_t offset, size_t length);
        void reopen(string path, size_t offset, size_t length);
+       bool opened();
 
        void specialSlot(SpecialSlot slot, CFDataRef data);
        void identifier(const std::string &code) { mIdentifier = code; }
 
        void specialSlot(SpecialSlot slot, CFDataRef data);
        void identifier(const std::string &code) { mIdentifier = code; }
index 7595bd5207aeae6af6840c9c0bdde5f0ba3e798d..0d1c485227beecaa86e2cccb9361ca4d63a95b69 100644 (file)
@@ -106,7 +106,7 @@ SecCode *KernelCode::locateGuest(CFDictionaryRef attributes)
                                        MacOSError::throwMe(errSecCSInvalidAttributeValues);
 
                        try {
                                        MacOSError::throwMe(errSecCSInvalidAttributeValues);
 
                        try {
-                               diskRep = new PidDiskRep(pid, infoPlist);
+                               diskRep = new PidDiskRep(pid, audit, infoPlist);
                        } catch (...) { }
        }
        
                        } catch (...) { }
        }
        
index 1e38473b944a6e57a4d729796df4f1435ed76e6a..f26e1c7874f709257fb2fbb4630f3f6fd38db261 100644 (file)
@@ -38,7 +38,7 @@ namespace CodeSigning {
 
 //
 // A SecCode that represents a running UNIX process.
 
 //
 // A SecCode that represents a running UNIX process.
-// Processes are identified by pid.
+// Processes are identified by pid and audit token.
 //
 // ProcessCode inherits GenericCode's access to the cshosting Mach protocol to
 // deal with guests.
 //
 // ProcessCode inherits GenericCode's access to the cshosting Mach protocol to
 // deal with guests.
index cf90ae61f5487e4f90a1663bed6e6a0217b5b9f7..069cb95f8c396708542ccc7d352070c068232096 100644 (file)
@@ -158,6 +158,27 @@ public:
        static const size_t monolithicPageSize = 0;             // default page size for non-Mach-O executables
 };
 
        static const size_t monolithicPageSize = 0;             // default page size for non-Mach-O executables
 };
 
+/*
+ * Editable Disk Reps allow editing of their existing code signature.
+ * Specifically, they allow for individual components to be replaced,
+ * while preserving all other components.
+ * Lots of restrictions apply, e.g. machO signatures' superblobs may
+ * not change in size, and components covered by the code directory
+ * cannot be replaced without adjusting the code directory.
+ * Replacing or adding CMS blobs (having reserved enough size in the
+ * superblob beforehand) is the original reason this trait exists.
+ */
+class EditableDiskRep {
+public:
+       typedef std::map<CodeDirectory::Slot, CFCopyRef<CFDataRef>> RawComponentMap;
+       
+       /* Return all components in raw form.
+        * Signature editing will add all the components obtained hereby
+        * back to their specific slots, though some of them may have
+        * been replaced in the map.
+        */
+       virtual RawComponentMap createRawComponents() = 0;
+};
 
 //
 // Write-access objects.
 
 //
 // Write-access objects.
index 6986c7251fa7028358a30783d9d9124ffbb6276f..02e7faa8bae1baf03095e2fbe53a462a135aab93 100644 (file)
@@ -265,6 +265,21 @@ CFDataRef MachORep::component(CodeDirectory::SpecialSlot slot)
        }
 }
 
        }
 }
 
+//
+// Retrieve all components, used for signature editing.
+//
+EditableDiskRep::RawComponentMap MachORep::createRawComponents()
+{
+       EditableDiskRep::RawComponentMap  blobMap;
+       const EmbeddedSignatureBlob &blobs = *signingData();
+       
+       for (unsigned int i = 0; i < blobs.count(); ++i) {
+               CodeDirectory::Slot slot = blobs.type(i);
+               const BlobCore *blob = blobs.blob(i);
+               blobMap[slot] = blobs.blobData(slot, blob);
+       }
+       return blobMap;
+}
 
 // Retrieve a component from the embedded signature SuperBlob (if present).
 // This reads the entire signing SuperBlob when first called for an executable,
 
 // Retrieve a component from the embedded signature SuperBlob (if present).
 // This reads the entire signing SuperBlob when first called for an executable,
@@ -275,6 +290,18 @@ CFDataRef MachORep::component(CodeDirectory::SpecialSlot slot)
 // calls wouldn't be slower in the end.
 //
 CFDataRef MachORep::embeddedComponent(CodeDirectory::SpecialSlot slot)
 // calls wouldn't be slower in the end.
 //
 CFDataRef MachORep::embeddedComponent(CodeDirectory::SpecialSlot slot)
+{
+       if (signingData()) {
+               return signingData()->component(slot);
+       }
+       
+       // not found
+       return NULL;
+}
+       
+       
+
+EmbeddedSignatureBlob *MachORep::signingData()
 {
        if (!mSigningData) {            // fetch and cache
                auto_ptr<MachO> macho(mainExecutableImage()->architecture());
 {
        if (!mSigningData) {            // fetch and cache
                auto_ptr<MachO> macho(mainExecutableImage()->architecture());
@@ -284,20 +311,16 @@ CFDataRef MachORep::embeddedComponent(CodeDirectory::SpecialSlot slot)
                                size_t length = macho->flip(cs->datasize);
                                if ((mSigningData = EmbeddedSignatureBlob::readBlob(macho->fd(), macho->offset() + offset, length))) {
                                        secinfo("machorep", "%zd signing bytes in %d blob(s) from %s(%s)",
                                size_t length = macho->flip(cs->datasize);
                                if ((mSigningData = EmbeddedSignatureBlob::readBlob(macho->fd(), macho->offset() + offset, length))) {
                                        secinfo("machorep", "%zd signing bytes in %d blob(s) from %s(%s)",
-                                               mSigningData->length(), mSigningData->count(),
-                                               mainExecutablePath().c_str(), macho->architecture().name());
+                                                       mSigningData->length(), mSigningData->count(),
+                                                       mainExecutablePath().c_str(), macho->architecture().name());
                                } else {
                                        secinfo("machorep", "failed to read signing bytes from %s(%s)",
                                } else {
                                        secinfo("machorep", "failed to read signing bytes from %s(%s)",
-                                               mainExecutablePath().c_str(), macho->architecture().name());
+                                                       mainExecutablePath().c_str(), macho->architecture().name());
                                        MacOSError::throwMe(errSecCSSignatureInvalid);
                                }
                        }
        }
                                        MacOSError::throwMe(errSecCSSignatureInvalid);
                                }
                        }
        }
-       if (mSigningData)
-               return mSigningData->component(slot);
-       
-       // not found
-       return NULL;
+       return mSigningData;
 }
 
 
 }
 
 
index 69d089a638fa14d1b1ef3065aee7ad05fedd4492..ef2181bb6dddb9011387019f1d7f927ed5d300c7 100644 (file)
@@ -45,12 +45,13 @@ namespace CodeSigning {
 // that it's driven directly from the signing code, with no
 // abstractions to get in the way.
 //
 // that it's driven directly from the signing code, with no
 // abstractions to get in the way.
 //
-class MachORep : public SingleDiskRep {
+class MachORep : public SingleDiskRep, public EditableDiskRep {
 public:
        MachORep(const char *path, const Context *ctx = NULL);
        virtual ~MachORep();
        
        CFDataRef component(CodeDirectory::SpecialSlot slot);
 public:
        MachORep(const char *path, const Context *ctx = NULL);
        virtual ~MachORep();
        
        CFDataRef component(CodeDirectory::SpecialSlot slot);
+       RawComponentMap createRawComponents();
        CFDataRef identification();
        Universal *mainExecutableImage();
        void prepareForSigning(SigningContext &context);
        CFDataRef identification();
        Universal *mainExecutableImage();
        void prepareForSigning(SigningContext &context);
@@ -86,9 +87,10 @@ protected:
 
 private:
        static bool needsExecSeg(const MachO& macho);
 
 private:
        static bool needsExecSeg(const MachO& macho);
+       EmbeddedSignatureBlob *signingData();
 
        Universal *mExecutable; // cached Mach-O/Universal reference to mainExecutablePath()
 
        Universal *mExecutable; // cached Mach-O/Universal reference to mainExecutablePath()
-       EmbeddedSignatureBlob *mSigningData; // cached signing data from current architecture
+       mutable EmbeddedSignatureBlob *mSigningData; // cached signing data from current architecture
 };
 
 
 };
 
 
index 76d785dca6aa07ae012187a9e0e7110024d7fea6..0aeeb81e1123f650a21396d802f17f5ededf3874 100644 (file)
@@ -58,8 +58,12 @@ PidDiskRep::fetchData(void)
        assert(request != NULL);
        xpc_dictionary_set_string(request, "command", "fetchData");
        xpc_dictionary_set_int64(request, "pid", mPid);
        assert(request != NULL);
        xpc_dictionary_set_string(request, "command", "fetchData");
        xpc_dictionary_set_int64(request, "pid", mPid);
+       
+       if (mAudit) {
+               xpc_dictionary_set_data(request, "audit", mAudit.get(), sizeof(audit_token_t));
+       }
        xpc_dictionary_set_data(request, "infohash", CFDataGetBytePtr(mInfoPlistHash), CFDataGetLength(mInfoPlistHash));
        xpc_dictionary_set_data(request, "infohash", CFDataGetBytePtr(mInfoPlistHash), CFDataGetLength(mInfoPlistHash));
-        
+       
        xpc_object_t reply = xpc_connection_send_message_with_reply_sync(conn, request);
        if (reply && xpc_get_type(reply) == XPC_TYPE_DICTIONARY) {
                const void *data;
        xpc_object_t reply = xpc_connection_send_message_with_reply_sync(conn, request);
        if (reply && xpc_get_type(reply) == XPC_TYPE_DICTIONARY) {
                const void *data;
@@ -89,20 +93,30 @@ PidDiskRep::fetchData(void)
 }
 
 
 }
 
 
-PidDiskRep::PidDiskRep(pid_t pid, CFDataRef infoPlist)
+PidDiskRep::PidDiskRep(pid_t pid, audit_token_t *audit, CFDataRef infoPlist)
        : mDataFetched(false)
 {
         BlobCore header;
        : mDataFetched(false)
 {
         BlobCore header;
-        CODESIGN_DISKREP_CREATE_KERNEL(this);
-        
+       
         mPid = pid;
         mInfoPlist = infoPlist;
         mPid = pid;
         mInfoPlist = infoPlist;
-
-//        fetchData();
     
     
-        int rcent = ::csops(pid, CS_OPS_BLOB, &header, sizeof(header));
+        if (audit != NULL) {
+            mAudit.reset(new audit_token_t);
+            memcpy(mAudit.get(), audit, sizeof(audit_token_t));
+        }
+    
+        //        fetchData();
+    
+        int rcent = EINVAL;
+       
+        if (audit != NULL) {
+            rcent = ::csops_audittoken(pid, CS_OPS_BLOB, &header, sizeof(header), mAudit.get());
+        } else {
+            rcent = ::csops(pid, CS_OPS_BLOB, &header, sizeof(header));
+        }
         if (rcent == 0)
         if (rcent == 0)
-                MacOSError::throwMe(errSecCSNoSuchCode);
+            MacOSError::throwMe(errSecCSNoSuchCode);
         
         if (errno != ERANGE)
                 UnixError::throwMe(errno);
         
         if (errno != ERANGE)
                 UnixError::throwMe(errno);
@@ -112,8 +126,12 @@ PidDiskRep::PidDiskRep(pid_t pid, CFDataRef infoPlist)
         
         uint32_t bufferLen = (uint32_t)header.length();
         mBuffer = new uint8_t [bufferLen];
         
         uint32_t bufferLen = (uint32_t)header.length();
         mBuffer = new uint8_t [bufferLen];
-        
-        UnixError::check(::csops(pid, CS_OPS_BLOB, mBuffer, bufferLen));
+    
+        if (audit != NULL) {
+            UnixError::check(::csops_audittoken(pid, CS_OPS_BLOB, mBuffer, bufferLen, mAudit.get()));
+        } else {
+            UnixError::check(::csops(pid, CS_OPS_BLOB, mBuffer, bufferLen));
+        }
 
         const EmbeddedSignatureBlob *b = (const EmbeddedSignatureBlob *)mBuffer;
         if (!b->validateBlob(bufferLen))
 
         const EmbeddedSignatureBlob *b = (const EmbeddedSignatureBlob *)mBuffer;
         if (!b->validateBlob(bufferLen))
@@ -185,6 +203,7 @@ UnixPlusPlus::FileDesc &PidDiskRep::fd()
 string PidDiskRep::mainExecutablePath()
 {
         char path[MAXPATHLEN * 2];
 string PidDiskRep::mainExecutablePath()
 {
         char path[MAXPATHLEN * 2];
+        // This is unsafe by pid only, but so is using that path in general.
         if(::proc_pidpath(mPid, path, sizeof(path)) == 0)
                UnixError::throwMe(errno);
 
         if(::proc_pidpath(mPid, path, sizeof(path)) == 0)
                UnixError::throwMe(errno);
 
@@ -194,12 +213,19 @@ string PidDiskRep::mainExecutablePath()
 bool PidDiskRep::appleInternalForcePlatform() const
 {
        uint32_t flags = 0;
 bool PidDiskRep::appleInternalForcePlatform() const
 {
        uint32_t flags = 0;
-       int rcent = ::csops(mPid, CS_OPS_STATUS, &flags, sizeof(flags));
-
+       int rcent = EINVAL;
+       
+       if (mAudit != NULL) {
+               rcent = ::csops_audittoken(mPid, CS_OPS_STATUS, &flags, sizeof(flags),
+                                                                  mAudit.get());
+       } else {
+               rcent = ::csops(mPid, CS_OPS_STATUS, &flags, sizeof(flags));
+       }
+       
        if (rcent != 0) {
                MacOSError::throwMe(errSecCSNoSuchCode);
        }
        if (rcent != 0) {
                MacOSError::throwMe(errSecCSNoSuchCode);
        }
-
+       
        return (flags & CS_PLATFORM_BINARY) == CS_PLATFORM_BINARY;
 }
                 
        return (flags & CS_PLATFORM_BINARY) == CS_PLATFORM_BINARY;
 }
                 
index a530984e7922f6d8b92b85f3b9c84a399fa21a22..c58430099d5d180123fb9b82bd345edb0b6de780 100644 (file)
 #ifndef _H_PIDDISKREP
 #define _H_PIDDISKREP
 
 #ifndef _H_PIDDISKREP
 #define _H_PIDDISKREP
 
+#include <memory>
+
 #include "diskrep.h"
 
 namespace Security {
 namespace CodeSigning {
                 
                 
 #include "diskrep.h"
 
 namespace Security {
 namespace CodeSigning {
                 
                 
-//
-// A KernelDiskRep represents a (the) kernel on disk.
-// It has no write support, so we can't sign the kernel,
-// which is fine since we unconditionally trust it anyway.
-//
 class PidDiskRep : public DiskRep {
 public:
 class PidDiskRep : public DiskRep {
 public:
-        PidDiskRep(pid_t pid, CFDataRef infoPlist);
+        PidDiskRep(pid_t pid, audit_token_t *audit, CFDataRef infoPlist);
         ~PidDiskRep();
         
         CFDataRef component(CodeDirectory::SpecialSlot slot);
         ~PidDiskRep();
         
         CFDataRef component(CodeDirectory::SpecialSlot slot);
@@ -64,6 +61,7 @@ private:
         const BlobCore *blob() { return (const BlobCore *)mBuffer; }
         void fetchData(void);
         pid_t mPid;
         const BlobCore *blob() { return (const BlobCore *)mBuffer; }
         void fetchData(void);
         pid_t mPid;
+        std::unique_ptr<audit_token_t> mAudit;
         uint8_t *mBuffer;
                CFRef<CFDataRef> mInfoPlistHash;
         CFRef<CFDataRef> mInfoPlist;
         uint8_t *mBuffer;
                CFRef<CFDataRef> mInfoPlistHash;
         CFRef<CFDataRef> mInfoPlist;
index 6e7cf0285319e2ef9398677b6979ba8fdd14d11e..ecac7081deb6c68bdaf74de6018af95b59e996fa 100644 (file)
@@ -34,17 +34,24 @@ namespace CodeSigning {
 
 CFDataRef EmbeddedSignatureBlob::component(CodeDirectory::SpecialSlot slot) const
 {
 
 CFDataRef EmbeddedSignatureBlob::component(CodeDirectory::SpecialSlot slot) const
 {
-       if (const BlobCore *blob = this->find(slot)) {
-               if (CodeDirectory::slotAttributes(slot) & cdComponentIsBlob) {
-                       return makeCFData(*blob);       // is a native Blob
-               } else if (const BlobWrapper *wrap = BlobWrapper::specific(blob)) {
-                       return makeCFData(*wrap);
-               } else {
-                       MacOSError::throwMe(errSecCSSignatureInvalid);
-               }
+       const BlobCore *blob = this->find(slot);
+       
+       if (blob) {
+               return blobData(slot, blob);
        }
        return NULL;
 }
        }
        return NULL;
 }
+       
+CFDataRef EmbeddedSignatureBlob::blobData(CodeDirectory::SpecialSlot slot, BlobCore const *blob)
+{
+       if (CodeDirectory::slotAttributes(slot) & cdComponentIsBlob) {
+               return makeCFData(*blob);       // is a native Blob
+       } else if (const BlobWrapper *wrap = BlobWrapper::specific(blob)) {
+               return makeCFData(*wrap);
+       } else {
+               MacOSError::throwMe(errSecCSSignatureInvalid);
+       }
+}
 
 
 void EmbeddedSignatureBlob::Maker::component(CodeDirectory::SpecialSlot slot, CFDataRef data)
 
 
 void EmbeddedSignatureBlob::Maker::component(CodeDirectory::SpecialSlot slot, CFDataRef data)
index eed6b5c5c1325d718c45333fd9935eea28285c49..392e840416d012b361e3df903f15fd6675804214 100644 (file)
@@ -43,6 +43,7 @@ namespace CodeSigning {
 class EmbeddedSignatureBlob : public SuperBlobCore<EmbeddedSignatureBlob, 0xfade0cc0, uint32_t> {
        typedef SuperBlobCore<EmbeddedSignatureBlob, 0xfade0cc0, uint32_t> _Core;
 public:
 class EmbeddedSignatureBlob : public SuperBlobCore<EmbeddedSignatureBlob, 0xfade0cc0, uint32_t> {
        typedef SuperBlobCore<EmbeddedSignatureBlob, 0xfade0cc0, uint32_t> _Core;
 public:
+       static CFDataRef blobData(CodeDirectory::SpecialSlot slot, BlobCore const *blob);
        CFDataRef component(CodeDirectory::SpecialSlot slot) const;
        
        class Maker : public _Core::Maker {
        CFDataRef component(CodeDirectory::SpecialSlot slot) const;
        
        class Maker : public _Core::Maker {
index 9e81b53a1219468f8484564d8e85bbebfee65c15..b5f07c40ce5e92c738ddcf10a4d5c088d84d6e71 100644 (file)
@@ -24,6 +24,7 @@
 //
 // signer - Signing operation supervisor and controller
 //
 //
 // signer - Signing operation supervisor and controller
 //
+#include "bundlediskrep.h"
 #include "der_plist.h"
 #include "signer.h"
 #include "resources.h"
 #include "der_plist.h"
 #include "signer.h"
 #include "resources.h"
@@ -205,7 +206,8 @@ void SecCodeSigner::Signer::prepare(SecCSFlags flags)
        }
        if (!haveCdFlags)
                cdFlags = 0;
        }
        if (!haveCdFlags)
                cdFlags = 0;
-       if (state.mSigner == SecIdentityRef(kCFNull))   // ad-hoc signing requested...
+       if ((state.mSigner == SecIdentityRef(kCFNull)) &&
+               !state.mOmitAdhocFlag)  // ad-hoc signing requested...
                cdFlags |= kSecCodeSignatureAdhoc;      // ... so note that
 
        // prepare the internal requirements input
                cdFlags |= kSecCodeSignatureAdhoc;      // ... so note that
 
        // prepare the internal requirements input
@@ -996,5 +998,207 @@ void SecCodeSigner::Signer::cookEntitlements(CFDataRef entitlements, bool genera
        }
 }
 
        }
 }
 
+//// Signature Editing
+       
+void SecCodeSigner::Signer::edit(SecCSFlags flags)
+{
+       rep = code->diskRep()->base();
+       
+       Universal *fat = state.mNoMachO ? NULL : rep->mainExecutableImage();
+       
+       prepareForEdit(flags);
+       
+       if (fat != NULL) {
+               editMachO(fat);
+       } else {
+               editArchitectureAgnostic();
+       }
+}
+
+EditableDiskRep *SecCodeSigner::Signer::editMainExecutableRep(DiskRep *rep)
+{
+       EditableDiskRep *mainExecRep = NULL;
+       BundleDiskRep *bundleDiskRep = dynamic_cast<BundleDiskRep*>(rep);
+       
+       if (bundleDiskRep) {
+               mainExecRep = dynamic_cast<EditableDiskRep*>(bundleDiskRep->mainExecRep());
+       }
+       
+       return mainExecRep;
+}
+       
+void SecCodeSigner::Signer::prepareForEdit(SecCSFlags flags) {
+       setDigestAlgorithms(code->hashAlgorithms());
+       
+       Universal *machO = (code->diskRep()->mainExecutableIsMachO() ?
+                                               code->diskRep()->mainExecutableImage() : NULL);
+       
+       /* We need at least one architecture in all cases because we index our
+        * RawComponentMaps by architecture. However, only machOs have any
+        * architecture at all, for generic targets there will just be one
+        * RawComponentMap.
+        * So if the main executable is not a machO, we just choose the local
+        * (signer's) main architecture as dummy value for the first element in our pair. */
+       editMainArch = (machO != NULL ? machO->bestNativeArch() : Architecture::local());
+
+       if (machO != NULL) {
+               if (machO->narrowed()) {
+                       /* --arch gives us a narrowed SecStaticCode, but because
+                        * codesign_allocate always creates or replaces signatures
+                        * for all slices, we must operate on the universal
+                        * SecStaticCode. Instead, we provide --edit-arch to specify
+                        * which slices to edit, the others have their code signature
+                        * copied without modifications.
+                        */
+                       MacOSError::throwMe(errSecCSNotSupported,
+                                                               "Signature editing must be performed on universal binary instead of narrow slice (using --edit-arch instead of --arch).");
+               }
+
+               if (state.mEditArch && !machO->isUniversal()) {
+                       MacOSError::throwMe(errSecCSInvalidFlags,
+                                                               "--edit-arch is only valid for universal binaries.");
+               }
+               
+               if (state.mEditCMS && machO->isUniversal() && !state.mEditArch) {
+                       /* Each slice has its own distinct code signature,
+                        * so a CMS blob is only valid for its one slice.
+                        * Therefore, replacing all CMS blobs in all slices
+                        * with the same blob is rather nonsensical, and we refuse.
+                        *
+                        * (Universal binaries with only one slice can exist,
+                        * and in that case the slice to operate on would be
+                        * umambiguous, but we are not treating those binaries
+                        * specially and still want --edit-arch for consistency.)
+                        */
+                       MacOSError::throwMe(errSecCSNotSupported,
+                                                               "CMS editing must be performed on specific slice (specified with --edit-arch).");
+               }
+       }
+       
+       void (^editArch)(SecStaticCode *code, Architecture arch) =
+       ^(SecStaticCode *code, Architecture arch) {
+               EditableDiskRep *editRep = dynamic_cast<EditableDiskRep *>(code->diskRep());
+               
+               if (editRep == NULL) {
+                       MacOSError::throwMe(errSecCSNotSupported,
+                                                               "Signature editing not supported for code of this type.");
+               }
+               
+               EditableDiskRep *mainExecRep = editMainExecutableRep(code->diskRep());
+               
+               if (mainExecRep != NULL) {
+                       // Delegate editing to the main executable if it is an EditableDiskRep.
+                       //(Which is the case for machOs.)
+                       editRep = mainExecRep;
+               }
+
+               editComponents[arch] = std::make_unique<RawComponentMap>(editRep->createRawComponents());
+               
+               if (!state.mEditArch || arch == state.mEditArch) {
+                       if (state.mEditCMS) {
+                               CFDataRef cms = state.mEditCMS.get();
+                               (*editComponents[arch])[cdSignatureSlot] = cms;
+                       }
+               }
+       };
+       
+       editArch(code, editMainArch);
+       
+       code->handleOtherArchitectures(^(Security::CodeSigning::SecStaticCode *subcode) {
+               Universal *fat = subcode->diskRep()->mainExecutableImage();
+               assert(fat && fat->narrowed()); // handleOtherArchitectures gave us a focused architecture slice.
+               Architecture arch = fat->bestNativeArch();      // actually, only architecture for this slice.
+               editArch(subcode, arch);
+       });
+       
+       /* The resource dictionary is special, because it is
+        * considered "global" instead of per architecture.
+        * For editing, that means it's usually not embedded
+        * in the main executable's signature if it exists,
+        * but in the containing disk rep (e.g. the
+        * CodeResources file if the rep is a Bundle).
+        */
+       resourceDictData = rep->component(cdResourceDirSlot);
+}
+       
+void SecCodeSigner::Signer::editMachO(Universal *fat) {
+       // Mach-O executable at the core - perform multi-architecture signature editing
+       RefPointer<DiskRep::Writer> writer = rep->writer();
+       
+       if (state.mPreserveAFSC)
+               writer->setPreserveAFSC(state.mPreserveAFSC);
+       
+       unique_ptr<ArchEditor> editor(new MachOEditor(writer, *fat,
+                                                                                                 this->digestAlgorithms(),
+                                                                                                 rep->mainExecutablePath()));
+       assert(editor->count() > 0);
+       
+       if (resourceDictData && !editor->attribute(writerNoGlobal)) {
+               // For when the resource dict is "global", e.g. for bundles.
+               editor->component(cdResourceDirSlot, resourceDictData);
+       }
+       
+       for (MachOEditor::Iterator it = editor->begin(); it != editor->end(); ++it) {
+               MachOEditor::Arch &arch = *it->second;
+               arch.source.reset(fat->architecture(it->first)); // transfer ownership
+               
+               if (resourceDictData && editor->attribute(writerNoGlobal)) {
+                       // Technically possible to embed a resource dict in the embedded sig.
+                       arch.component(cdResourceDirSlot, resourceDictData);
+               }
+               
+               for (auto const &entry : *editComponents[arch.architecture]) {
+                       CodeDirectory::Slot slot = entry.first;
+                       CFDataRef data = entry.second.get();
+                       arch.component(slot, data);
+               }
+               
+               /* We must preserve the original superblob's size, as the size is
+                * also in the macho's load commands, which are itself covered
+                * by the signature. */
+               arch.blobSize = arch.source->signingLength();
+       }
+       
+       editor->allocate();
+       
+       for (MachOEditor::Iterator it = editor->begin(); it != editor->end(); ++it) {
+               MachOEditor::Arch &arch = *it->second;
+               editor->reset(arch);
+               
+               if (!state.mDryRun) {
+                       EmbeddedSignatureBlob *blob = arch.make();
+                       editor->write(arch, blob);      // takes ownership of blob
+               }
+       }
+       
+       if (!state.mDryRun) {
+               editor->commit();
+       }
+
+}
+
+void SecCodeSigner::Signer::editArchitectureAgnostic()
+{
+       if (state.mDryRun) {
+               return;
+
+       }
+       // non-Mach-O executable - single-instance signature editing
+       RefPointer<DiskRep::Writer> writer = rep->writer();
+       
+       if(state.mPreserveAFSC)
+               writer->setPreserveAFSC(state.mPreserveAFSC);
+       
+       for (auto const &entry : *editComponents[editMainArch]) {
+               CodeDirectory::Slot slot = entry.first;
+               CFDataRef data = entry.second.get();
+               
+               writer->component(slot, data);
+       }
+
+       // commit to storage
+       writer->flush();
+}
+
 } // end namespace CodeSigning
 } // end namespace Security
 } // end namespace CodeSigning
 } // end namespace Security
index f43494f04b77b14501cc8098990f6c8f82c25a57..960cf7960785c7b6f92aac8bcde3d3e83801d1bb 100644 (file)
@@ -51,6 +51,7 @@ public:
 
        void sign(SecCSFlags flags);
        void remove(SecCSFlags flags);
 
        void sign(SecCSFlags flags);
        void remove(SecCSFlags flags);
+       void edit(SecCSFlags flags);
        
        SecCodeSigner &state;
        SecStaticCode * const code;
        
        SecCodeSigner &state;
        SecStaticCode * const code;
@@ -66,6 +67,10 @@ protected:
        void prepare(SecCSFlags flags);                         // set up signing parameters
        void signMachO(Universal *fat, const Requirement::Context &context); // sign a Mach-O binary
        void signArchitectureAgnostic(const Requirement::Context &context); // sign anything else
        void prepare(SecCSFlags flags);                         // set up signing parameters
        void signMachO(Universal *fat, const Requirement::Context &context); // sign a Mach-O binary
        void signArchitectureAgnostic(const Requirement::Context &context); // sign anything else
+       
+       void prepareForEdit(SecCSFlags flags);          // set up signature editing
+       void editMachO(Universal *fat);                         // edit a Mach-O binary
+       void editArchitectureAgnostic();                        // edit anything else
 
        // HashAlgorithm -> PreEncrypt hashes
        typedef std::map<CodeDirectory::HashAlgorithm, CFCopyRef<CFDataRef> >
 
        // HashAlgorithm -> PreEncrypt hashes
        typedef std::map<CodeDirectory::HashAlgorithm, CFCopyRef<CFDataRef> >
@@ -79,6 +84,10 @@ protected:
        // Architecture -> RuntimeVersionMap
        typedef std::map<Architecture, RuntimeVersionMap>
                RuntimeVersionMaps;
        // Architecture -> RuntimeVersionMap
        typedef std::map<Architecture, RuntimeVersionMap>
                RuntimeVersionMaps;
+       // Architecture -> RawComponentMap
+       typedef EditableDiskRep::RawComponentMap RawComponentMap;
+       typedef std::map<Architecture, std::unique_ptr<RawComponentMap>>
+               RawComponentMaps;
 
        void populate(DiskRep::Writer &writer);         // global
        void populate(CodeDirectory::Builder &builder, DiskRep::Writer &writer,
 
        void populate(DiskRep::Writer &writer);         // global
        void populate(CodeDirectory::Builder &builder, DiskRep::Writer &writer,
@@ -101,6 +110,8 @@ protected:
        SecCSFlags signingFlags() const;
        
 private:
        SecCSFlags signingFlags() const;
        
 private:
+       static EditableDiskRep *editMainExecutableRep(DiskRep *rep);
+       
        void addPreEncryptHashes(PreEncryptHashMap &map, SecStaticCode const *code);
        void addRuntimeVersions(RuntimeVersionMap &map, SecStaticCode const *code);
        
        void addPreEncryptHashes(PreEncryptHashMap &map, SecStaticCode const *code);
        void addRuntimeVersions(RuntimeVersionMap &map, SecStaticCode const *code);
        
@@ -137,6 +148,10 @@ private:
        bool strict;                                    // strict validation
        bool generateEntitlementDER;    // generate entitlement DER
        
        bool strict;                                    // strict validation
        bool generateEntitlementDER;    // generate entitlement DER
        
+       // Signature Editing
+       Architecture editMainArch;              // main architecture for editing
+       RawComponentMaps editComponents; // components for signature
+       
 private:
        Mutex resourceLock;
 };
 private:
        Mutex resourceLock;
 };
index ec0cf4835045046971d8ec16f2e631152927eee3..f6da5e936cd7142612990322bafe4659a46568b7 100644 (file)
@@ -262,7 +262,11 @@ void MachOEditor::reset(Arch &arch)
 
        for (auto type = mHashTypes.begin(); type != mHashTypes.end(); ++type) {
                arch.eachDigest(^(CodeDirectory::Builder& builder) {
 
        for (auto type = mHashTypes.begin(); type != mHashTypes.end(); ++type) {
                arch.eachDigest(^(CodeDirectory::Builder& builder) {
-                       builder.reopen(tempPath, arch.source->offset(), arch.source->signingOffset());
+                       /* Signature editing may have no need for cd builders, and not
+                        * have opened them, so only reopen them conditionally. */
+                       if (builder.opened()) {
+                               builder.reopen(tempPath, arch.source->offset(), arch.source->signingOffset());
+                       }
                });
        }
 }
                });
        }
 }
index 53c6e51f3ad0d3003bd19221888be01ecb294255..1bd01d8ce9d92a53e5f6b5c29a60f12cb30550e2 100644 (file)
@@ -86,7 +86,7 @@ public:
 
 //
 // A multi-architecture editing assistant.
 
 //
 // A multi-architecture editing assistant.
-// ArchEditor collects (Mach-O) architectures in use, and maintains per-archtitecture
+// ArchEditor collects (Mach-O) architectures in use, and maintains per-architecture
 // data structures. It must be subclassed to express a particular way to handle the signing
 // data.
 //
 // data structures. It must be subclassed to express a particular way to handle the signing
 // data.
 //
index 4fd99c702847379cc4d101defe9d2a1b5fe8a6cc..2886f22ca964b055cbc18bb338514887bc6c94c8 100644 (file)
@@ -418,6 +418,11 @@ class RequirementLexer extends Lexer;
 options {
        k=2;
        testLiterals=false;
 options {
        k=2;
        testLiterals=false;
+
+    // Pass through valid UTF-8 (which excludes hex C0-C1 and F5-FF),
+       // but also exclude ASCII control characters below 0x20 (space).
+       // Byte ranges according to Unicode 11.0, paragraph 3.9 D92.
+       charVocabulary='\000'..'\277' | '\302'..'\364';
 }
 
 protected
 }
 
 protected
index 3cd84cc4e83b96334e55845656b6eeb86cc9ac17..aa168bd8b3d257f6b514296606b21580078e1dda 100644 (file)
@@ -1034,6 +1034,12 @@ DLDbListCFPref::defaultDLDbIdentifier()
             if (mDefaultDLDbIdentifier.mImpl != NULL && actualIdentifier.mImpl != NULL)
             {
                 st_result = stat(actualIdentifier.dbName(), &st);
             if (mDefaultDLDbIdentifier.mImpl != NULL && actualIdentifier.mImpl != NULL)
             {
                 st_result = stat(actualIdentifier.dbName(), &st);
+
+                // Always claim that the system keychain exists for purposes of the search list
+                if (st_result && 0 == strncmp(actualIdentifier.dbName(), kSystemKeychainPath, strlen(kSystemKeychainPath))) {
+                    secnotice("secpref", "System keychain (%s) does not exist. Continuing as if it does...", actualIdentifier.dbName());
+                    st_result = 0;
+                }
             }
 
             if (st_result)
             }
 
             if (st_result)
index 2ec227ef090dee51d57673381f5aea79654ca951..bea27fec5077ffe1e6476bb256615fbd9c18aec4 100644 (file)
@@ -640,7 +640,7 @@ bool ItemImpl::checkIntegrityFromDictionary(AclBearer& aclBearer, DbAttributes*
             return false; // No MAC, no integrity.
         }
 
             return false; // No MAC, no integrity.
         }
 
-        throw cssme;
+        throw;
     }
 
     secnotice("integrity", "***** INVALID ITEM");
     }
 
     secnotice("integrity", "***** INVALID ITEM");
@@ -1833,7 +1833,7 @@ ItemImpl::getContent(DbAttributes *dbAttributes, CssmDataContainer *itemData)
                 }
             } catch(CssmError cssme) {
                 secnotice("integrity", "error while checking integrity, denying access: %s", cssme.what());
                 }
             } catch(CssmError cssme) {
                 secnotice("integrity", "error while checking integrity, denying access: %s", cssme.what());
-                throw cssme;
+                throw;
             }
 
                        SSDbUniqueRecordImpl* impl = dynamic_cast<SSDbUniqueRecordImpl *>(&(*dbUniqueRecord()));
             }
 
                        SSDbUniqueRecordImpl* impl = dynamic_cast<SSDbUniqueRecordImpl *>(&(*dbUniqueRecord()));
index 04095492f77283bcae1e8a75598a7ec69647fab0..fed9dae0607ca31255587013a143ef23a3f71e4f 100644 (file)
@@ -489,7 +489,7 @@ KeyItem::key()
         } catch(CssmError cssme) {
             mKey.release();
             secnotice("integrity", "error while checking integrity, denying access: %s", cssme.what());
         } catch(CssmError cssme) {
             mKey.release();
             secnotice("integrity", "error while checking integrity, denying access: %s", cssme.what());
-            throw cssme;
+            throw;
         }
     }
 
         }
     }
 
index e3ce4cb0650e25fc49dfaa8f5b381c7522cfc0c0..2b125fa8ec7aeee2d97e88b98102e1dc20391db2 100644 (file)
@@ -656,11 +656,14 @@ KeychainImpl::changePassphrase(UInt32 oldPasswordLength, const void *oldPassword
        UInt32 newPasswordLength, const void *newPassword)
 {
        StLock<Mutex>_(mMutex);
        UInt32 newPasswordLength, const void *newPassword)
 {
        StLock<Mutex>_(mMutex);
-       
+
+    secnotice("KCspi", "Attempting to change passphrase for %s", mDb->name());
+
        bool isSmartcard =      (mDb->dl()->guid() == gGuidAppleSdCSPDL);
 
        TrackingAllocator allocator(Allocator::standard());
        AutoCredentials cred = AutoCredentials(allocator);
        bool isSmartcard =      (mDb->dl()->guid() == gGuidAppleSdCSPDL);
 
        TrackingAllocator allocator(Allocator::standard());
        AutoCredentials cred = AutoCredentials(allocator);
+
        if (oldPassword)
        {
                const CssmData &oldPass = *new(allocator) CssmData(const_cast<void *>(oldPassword), oldPasswordLength);
        if (oldPassword)
        {
                const CssmData &oldPass = *new(allocator) CssmData(const_cast<void *>(oldPassword), oldPasswordLength);
index bb3adfc6712bd6dae0801072eaca95785c41a9f6..301cf0e52eea15b3b5f84e800b9b94bfc5ba3241 100644 (file)
@@ -323,8 +323,7 @@ SecAccessRef SecAccessCreateWithOwnerAndACL(uid_t userId, gid_t groupId, SecAcce
 
     CFIndex rightsSize = numAcls > 0 ? numAcls : 1;
 
 
     CFIndex rightsSize = numAcls > 0 ? numAcls : 1;
 
-       CSSM_ACL_AUTHORIZATION_TAG rights[rightsSize];
-       memset(rights, 0, sizeof(rights));
+       std::vector<CSSM_ACL_AUTHORIZATION_TAG> rights(numAcls);
 
        for (CFIndex iCnt = 0; iCnt < numAcls; iCnt++)
        {
 
        for (CFIndex iCnt = 0; iCnt < numAcls; iCnt++)
        {
@@ -384,7 +383,7 @@ SecAccessRef SecAccessCreateWithOwnerAndACL(uid_t userId, gid_t groupId, SecAcce
                                { CSSM_LIST_TYPE_UNKNOWN, &subject1, &subject2 },
                                false,  // Delegate
                                // rights for this entry
                                { CSSM_LIST_TYPE_UNKNOWN, &subject1, &subject2 },
                                false,  // Delegate
                                // rights for this entry
-                               { (uint32)numAcls, rights },
+                               { (uint32)numAcls, rights.data() },
                                // rest is defaulted
                        }
                }
                                // rest is defaulted
                        }
                }
index ab0419a2e464507d53fbbfa29ac25c09945d37d8..ad88d453afc834ecf5df225ce809a9e14d666af6 100644 (file)
@@ -548,13 +548,10 @@ _ConvertNewFormatToOldFormat(
 
        // make storage to extract the dictionary items
        CFIndex itemsInDictionary = CFDictionaryGetCount(dictionaryRef);
 
        // make storage to extract the dictionary items
        CFIndex itemsInDictionary = CFDictionaryGetCount(dictionaryRef);
-       CFTypeRef keys[itemsInDictionary];
-       CFTypeRef values[itemsInDictionary];
+       std::vector<CFTypeRef> keys(itemsInDictionary);
+       std::vector<CFTypeRef> values(itemsInDictionary);
 
 
-       CFTypeRef *keysPtr = keys;
-       CFTypeRef *valuesPtr = values;
-
-       CFDictionaryGetKeysAndValues(dictionaryRef, keys, values);
+       CFDictionaryGetKeysAndValues(dictionaryRef, keys.data(), values.data());
 
        // count the number of items we are interested in
        CFIndex count = 0;
 
        // count the number of items we are interested in
        CFIndex count = 0;
@@ -562,12 +559,12 @@ _ConvertNewFormatToOldFormat(
 
        // since this is one of those nasty order n^2 loops, we cache as much stuff as possible so that
        // we don't pay the price for this twice
 
        // since this is one of those nasty order n^2 loops, we cache as much stuff as possible so that
        // we don't pay the price for this twice
-       SecKeychainAttrType tags[itemsInDictionary];
-       ItemRepresentation types[itemsInDictionary];
+       std::vector<SecKeychainAttrType> tags(itemsInDictionary);
+       std::vector<ItemRepresentation> types(itemsInDictionary);
 
        for (i = 0; i < itemsInDictionary; ++i)
        {
 
        for (i = 0; i < itemsInDictionary; ++i)
        {
-               CFTypeRef key = keysPtr[i];
+               CFTypeRef key = keys[i];
 
                int j;
                for (j = 0; j < infoNumItems; ++j)
 
                int j;
                for (j = 0; j < infoNumItems; ++j)
@@ -584,7 +581,7 @@ _ConvertNewFormatToOldFormat(
                if (j >= infoNumItems)
                {
                        // if we got here, we aren't interested in this item.
                if (j >= infoNumItems)
                {
                        // if we got here, we aren't interested in this item.
-                       valuesPtr[i] = NULL;
+                       values[i] = NULL;
                }
        }
 
                }
        }
 
@@ -602,7 +599,7 @@ _ConvertNewFormatToOldFormat(
 
                        // we have to clone the data pointer.  The caller will need to make sure to throw these away
                        // with _FreeAttrList when it is done...
 
                        // we have to clone the data pointer.  The caller will need to make sure to throw these away
                        // with _FreeAttrList when it is done...
-                       attrList->attr[resultPointer].data = CloneDataByType(types[i], valuesPtr[i], attrList->attr[resultPointer].length);
+                       attrList->attr[resultPointer].data = CloneDataByType(types[i], values[i], attrList->attr[resultPointer].length);
                        resultPointer += 1;
                }
        }
                        resultPointer += 1;
                }
        }
@@ -2364,19 +2361,6 @@ _ReplaceKeychainItem(
        for (i=0, newCount=0; i < attrList->count; i++) {
                if (attrList->attr[i].length > 0) {
                        newAttrList.attr[newCount++] = attrList->attr[i];
        for (i=0, newCount=0; i < attrList->count; i++) {
                if (attrList->attr[i].length > 0) {
                        newAttrList.attr[newCount++] = attrList->attr[i];
-               #if 0
-                       // debugging code to log item attributes
-                       SecKeychainAttrType tag = attrList->attr[i].tag;
-                       SecKeychainAttrType htag=(SecKeychainAttrType)OSSwapConstInt32(tag);
-                       char tmp[sizeof(SecKeychainAttrType) + 1];
-                       char tmpdata[attrList->attr[i].length + 1];
-                       memcpy(tmp, &htag, sizeof(SecKeychainAttrType));
-                       tmp[sizeof(SecKeychainAttrType)]=0;
-                       memcpy(tmpdata, attrList->attr[i].data, attrList->attr[i].length);
-                       tmpdata[attrList->attr[i].length]=0;
-                       secitemlog(priority, "item attr '%s' = %d bytes: \"%s\"",
-                               tmp, (int)attrList->attr[i].length, tmpdata);
-               #endif
                }
        }
        newAttrList.count = newCount;
                }
        }
        newAttrList.count = newCount;
diff --git a/OSX/libsecurity_keychain/regressions/kc-45-change-password.c b/OSX/libsecurity_keychain/regressions/kc-45-change-password.c
new file mode 100644 (file)
index 0000000..c944f79
--- /dev/null
@@ -0,0 +1,33 @@
+#include <Security/SecKeychain.h>
+#include <Security/SecKeychainPriv.h>
+
+#include "keychain_regressions.h"
+#include "kc-helpers.h"
+
+int kc_45_change_password(int argc, char *const *argv)
+{
+    plan_tests(14);
+
+    initializeKeychainTests(__FUNCTION__);
+
+    ok_status(SecKeychainSetUserInteractionAllowed(FALSE), "SecKeychainSetUserInteractionAllowed(FALSE)");
+
+    SecKeychainRef keychain = createNewKeychain("test", "before");
+    ok_status(SecKeychainLock(keychain), "SecKeychainLock");
+    is_status(SecKeychainChangePassword(keychain, 0, NULL, 5, "after"), errSecAuthFailed, "Change PW w/ null pw while locked");
+    is_status(SecKeychainChangePassword(keychain, 5, "badpw", 5, "after"), errSecAuthFailed, "Change PW w/ bad pw while locked");
+    ok_status(SecKeychainUnlock(keychain, 6, "before", true), "SecKeychainUnlock");
+    is_status(SecKeychainChangePassword(keychain, 0, NULL, 5, "after"), errSecAuthFailed, "Change PW w/ null pw while unlocked");
+    is_status(SecKeychainChangePassword(keychain, 5, "badpw", 5, "after"), errSecAuthFailed, "Change PW w/ bad pw while unlocked");
+
+    ok_status(SecKeychainChangePassword(keychain, 6, "before", 7, "between"), "Change PW w/ good pw while unlocked");
+    ok_status(SecKeychainLock(keychain), "SecKeychainLock");
+    ok_status(SecKeychainChangePassword(keychain, 7, "between", 7, "after"), "Change PW w/ good pw while locked");
+    checkPrompts(0, "Unexpected keychain access prompt");
+
+    ok_status(SecKeychainDelete(keychain), "%s: SecKeychainDelete", testName);
+    CFRelease(keychain);
+
+    deleteTestFiles();
+    return 0;
+}
index b9ae13c90012d2a448a7ffa157af2997688ca950..7599d26c176ecb4eef6ee02017ba49f4b93d4d9e 100644 (file)
@@ -44,6 +44,7 @@ ONE_TEST(kc_41_sececkey)
 ONE_TEST(kc_42_trust_revocation)
 ONE_TEST(kc_43_seckey_interop)
 ONE_TEST(kc_44_secrecoverypassword)
 ONE_TEST(kc_42_trust_revocation)
 ONE_TEST(kc_43_seckey_interop)
 ONE_TEST(kc_44_secrecoverypassword)
+ONE_TEST(kc_45_change_password)
 ONE_TEST(si_20_sectrust_provisioning)
 ONE_TEST(si_33_keychain_backup)
 ONE_TEST(si_34_one_true_keychain)
 ONE_TEST(si_20_sectrust_provisioning)
 ONE_TEST(si_33_keychain_backup)
 ONE_TEST(si_34_one_true_keychain)
index 6b337e26143f550d9ad6c9b1be2f27daf0e22acd..29c8a0d06e0f22b0d31980e9f64597135c03dfc6 100644 (file)
@@ -396,9 +396,9 @@ int main(int argc, const char *argv[])
     }
     
     // make storage for the real path
     }
     
     // make storage for the real path
-    char buffer[total_length];
-    strlcpy(buffer, home_dir, total_length);
-    strlcat(buffer, g_path_to_plist, total_length);
+    char buffer[PATH_MAX];
+    strlcpy(buffer, home_dir, sizeof(buffer));
+    strlcat(buffer, g_path_to_plist, sizeof(buffer));
     keychain_prefs_path = xpc_string_create(buffer);
     home = xpc_string_create(home_dir);
     
     keychain_prefs_path = xpc_string_create(buffer);
     home = xpc_string_create(home_dir);
     
index a173aa139083ebe4356aed9ba1844617d1ecab0e..3d4dc41a80d876b098b31a651ed0960df26ca75f 100644 (file)
@@ -749,8 +749,11 @@ SecCmsSignedDataVerifySignerInfo(SecCmsSignedDataRef sigd, int i,
     CSSM_DATA_PTR contentType, digest;
     OSStatus status, status2;
 
     CSSM_DATA_PTR contentType, digest;
     OSStatus status, status2;
 
-    cinfo = &(sigd->contentInfo);
+    if (sigd == NULL || sigd->signerInfos == NULL || i >= SecCmsSignedDataSignerInfoCount(sigd)) {
+        return errSecParam;
+    }
 
 
+    cinfo = &(sigd->contentInfo);
     signerinfo = sigd->signerInfos[i];
 
     /* Signature or digest level verificationStatus errors should supercede
     signerinfo = sigd->signerInfos[i];
 
     /* Signature or digest level verificationStatus errors should supercede
@@ -759,19 +762,19 @@ SecCmsSignedDataVerifySignerInfo(SecCmsSignedDataRef sigd, int i,
     /* Find digest and contentType for signerinfo */
     algiddata = SecCmsSignerInfoGetDigestAlg(signerinfo);
     if (algiddata == NULL) {
     /* Find digest and contentType for signerinfo */
     algiddata = SecCmsSignerInfoGetDigestAlg(signerinfo);
     if (algiddata == NULL) {
-        return errSecInternalError; // shouldn't have happened, this is likely due to corrupted data
+        return errSecInvalidDigestAlgorithm;
     }
     
     digest = SecCmsSignedDataGetDigestByAlgTag(sigd, algiddata->offset);
     }
     
     digest = SecCmsSignedDataGetDigestByAlgTag(sigd, algiddata->offset);
-       if(digest == NULL) {
-               /* 
-                * No digests; this probably had detached content the caller has to 
-                * deal with. 
-                * FIXME: need some error return for this (as well as many 
-                * other places in this library).
-                */
-               return errSecDataNotAvailable;
-       }
+    if(digest == NULL) {
+        /*
+         * No digests; this probably had detached content the caller has to
+         * deal with.
+         * FIXME: need some error return for this (as well as many
+         * other places in this library).
+         */
+        return errSecDataNotAvailable;
+    }
     contentType = SecCmsContentInfoGetContentTypeOID(cinfo);
 
     /* verify signature */
     contentType = SecCmsContentInfoGetContentTypeOID(cinfo);
 
     /* verify signature */
index e5e037a16b342a20787529ca3ee17f982140f384..da6677f27bd73a9c2933477cc2d482e5497ba90a 100644 (file)
@@ -393,7 +393,7 @@ static void sign_tests(SecIdentityRef identity, bool isRSA) {
 
 /* Verifying with attributes goes through a different code path than verifying without,
  * so we need to test both. */
 
 /* Verifying with attributes goes through a different code path than verifying without,
  * so we need to test both. */
-#define kNumberVerifyTests 12
+#define kNumberVerifyTests 13
 static void verify_tests(SecKeychainRef kc, bool isRsa) {
     /* no attributes */
     is(verify_please(kc, (isRsa) ? rsa_md5 : ec_md5,
 static void verify_tests(SecKeychainRef kc, bool isRsa) {
     /* no attributes */
     is(verify_please(kc, (isRsa) ? rsa_md5 : ec_md5,
@@ -421,6 +421,9 @@ static void verify_tests(SecKeychainRef kc, bool isRsa) {
     /***** Once more, with validation errors *****/
 
     /* no attributes */
     /***** Once more, with validation errors *****/
 
     /* no attributes */
+    is(verify_please(kc, (isRsa) ? rsa_sinfo_unknown_digest : ec_sinfo_unknown_digest,
+                     (isRsa) ? sizeof(rsa_sinfo_unknown_digest) : sizeof(ec_sinfo_unknown_digest)),
+       errSecInvalidDigestAlgorithm, "Verify unknown digest OID in signer info");
     is(invalidate_and_verify(kc, (isRsa) ? rsa_md5 : ec_md5,
                      (isRsa) ? sizeof(rsa_md5) : sizeof(ec_md5)),
        SECFailure, "Verify invalid MD5, no attributes");
     is(invalidate_and_verify(kc, (isRsa) ? rsa_md5 : ec_md5,
                      (isRsa) ? sizeof(rsa_md5) : sizeof(ec_md5)),
        SECFailure, "Verify invalid MD5, no attributes");
index dc46feeb33e743212176322059a86f11b97e0af9..371b8f69bdf8d5fa2effe8371f7239003c0131b3 100644 (file)
@@ -233,6 +233,89 @@ unsigned char _ec_identity[] = {
 /*
  * MARK: RSA-signed messages (no attributes)
  */
 /*
  * MARK: RSA-signed messages (no attributes)
  */
+unsigned char rsa_sinfo_unknown_digest[] = {
+    0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
+    0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x29, 0x54, 0x68, 0x69, 0x73, 0x20,
+    0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x20, 0x41,
+    0x69, 0x6e, 0x27, 0x74, 0x20, 0x69, 0x74, 0x20, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xa0, 0x82, 0x03, 0xe5, 0x30, 0x82, 0x03, 0xe1, 0x30, 0x82, 0x02, 0xc9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
+    0x04, 0x74, 0x3f, 0x1d, 0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
+    0x30, 0x81, 0xa7, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x43, 0x4d, 0x53, 0x20, 0x52, 0x53,
+    0x41, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+    0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65,
+    0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53, 0x65, 0x63,
+    0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e,
+    0x64, 0x20, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+    0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f, 0x06,
+    0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
+    0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x33, 0x31, 0x34,
+    0x30, 0x30, 0x31, 0x38, 0x32, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x31, 0x33, 0x30, 0x30, 0x31, 0x38, 0x32,
+    0x39, 0x5a, 0x30, 0x81, 0xa7, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x43, 0x4d, 0x53, 0x20,
+    0x52, 0x53, 0x41, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53,
+    0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20,
+    0x61, 0x6e, 0x64, 0x20, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11,
+    0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30,
+    0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61,
+    0x6d, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+    0x02, 0x82, 0x01, 0x01, 0x00, 0xe2, 0x9b, 0xcb, 0x6c, 0x77, 0xb7, 0xd1, 0x05, 0xa0, 0xae, 0x86, 0x20, 0x45, 0xd3, 0xf4,
+    0x24, 0x8d, 0x25, 0x34, 0x31, 0xa9, 0xe2, 0x10, 0x36, 0xf5, 0x0a, 0x0b, 0x90, 0x4a, 0xa5, 0x6b, 0x5c, 0x16, 0xcd, 0xb0,
+    0x72, 0xe9, 0xa9, 0x80, 0x5f, 0x6d, 0xb2, 0x4d, 0xd9, 0x58, 0x16, 0x9f, 0x68, 0x81, 0x9a, 0x6b, 0xeb, 0xd5, 0x4b, 0xf7,
+    0x7d, 0x59, 0xe9, 0x46, 0x2b, 0x5b, 0x8f, 0xe4, 0xec, 0xab, 0x5c, 0x07, 0x74, 0xa2, 0x0e, 0x59, 0xbb, 0xfc, 0xd3, 0xcf,
+    0xf7, 0x21, 0x88, 0x6c, 0x88, 0xd9, 0x6b, 0xa3, 0xa3, 0x4e, 0x5b, 0xd1, 0x1c, 0xfb, 0x04, 0xf5, 0xb2, 0x12, 0x0e, 0x54,
+    0x59, 0x4d, 0xce, 0x0a, 0xe0, 0x26, 0x24, 0x06, 0xeb, 0xc8, 0xa2, 0xc6, 0x41, 0x28, 0xf9, 0x79, 0xe4, 0xb1, 0x4e, 0x00,
+    0x6f, 0x6e, 0xf8, 0x96, 0x9e, 0x45, 0x28, 0x70, 0xec, 0xc7, 0xdc, 0xa2, 0xdd, 0x92, 0xab, 0xdd, 0x6f, 0xd8, 0x57, 0xba,
+    0xcc, 0x29, 0xbe, 0xb7, 0x00, 0x1e, 0x8d, 0x13, 0x3f, 0x47, 0x34, 0x3c, 0xd0, 0xc6, 0xc8, 0x17, 0xdf, 0x74, 0x8a, 0xb1,
+    0xc3, 0x68, 0xd5, 0xba, 0x76, 0x60, 0x55, 0x5f, 0x8d, 0xfa, 0xbd, 0xe7, 0x11, 0x9e, 0x59, 0x96, 0xe5, 0x93, 0x70, 0xad,
+    0x41, 0xfb, 0x61, 0x46, 0x70, 0xc4, 0x05, 0x12, 0x23, 0x23, 0xc0, 0x9d, 0xc8, 0xc5, 0xf5, 0x96, 0xe5, 0x48, 0x10, 0x86,
+    0x8a, 0x1e, 0x3b, 0x83, 0xd1, 0x47, 0x3a, 0x27, 0x00, 0x71, 0x10, 0xa3, 0x52, 0xba, 0xae, 0x01, 0x43, 0x87, 0x9c, 0x6a,
+    0x1b, 0xea, 0x1a, 0x44, 0x4f, 0x4a, 0xac, 0xd4, 0x82, 0x55, 0xee, 0x1f, 0x25, 0x9c, 0x55, 0xca, 0xd2, 0xd0, 0x3a, 0x0b,
+    0x70, 0x90, 0x60, 0x49, 0x47, 0x02, 0xfd, 0x89, 0x2c, 0x9a, 0x26, 0x36, 0x34, 0x8f, 0x24, 0x39, 0x8c, 0xe9, 0xa2, 0x52,
+    0x8f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x13, 0x30, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+    0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+    0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4c, 0xed, 0x5b, 0xaf, 0x13, 0x16, 0x5d, 0xe2, 0xdd, 0x5c, 0x48, 0x1c, 0xd5,
+    0x6e, 0x8b, 0x04, 0x51, 0xd6, 0x38, 0x80, 0xfd, 0x52, 0x4a, 0x34, 0xdc, 0x13, 0x35, 0x6e, 0x64, 0x39, 0x39, 0x39, 0x09,
+    0xa7, 0x6c, 0x2d, 0x39, 0xf2, 0x04, 0x21, 0xe3, 0xea, 0x8f, 0xf8, 0xbe, 0x46, 0x0e, 0x20, 0x82, 0xd0, 0xc5, 0x60, 0xbf,
+    0x57, 0x6f, 0xd8, 0x29, 0xb4, 0x66, 0xdb, 0xbf, 0x92, 0xc9, 0xdc, 0x90, 0x97, 0x0f, 0x2f, 0x59, 0xa0, 0x13, 0xf3, 0xa4,
+    0xca, 0xde, 0x3f, 0x80, 0x2a, 0x99, 0xb4, 0xee, 0x71, 0xc3, 0x56, 0x71, 0x51, 0x37, 0x55, 0xa1, 0x60, 0x89, 0xab, 0x94,
+    0x0e, 0xb9, 0x70, 0xa5, 0x55, 0xf3, 0x1a, 0x87, 0xa4, 0x41, 0x4c, 0x45, 0xba, 0xb6, 0x56, 0xd6, 0x45, 0x56, 0x12, 0x60,
+    0xe5, 0x91, 0xec, 0xf7, 0xbe, 0x39, 0xa4, 0x80, 0x08, 0x9f, 0xea, 0x17, 0x12, 0x0e, 0xa6, 0xe6, 0xef, 0x09, 0xf7, 0x61,
+    0x51, 0x57, 0x73, 0xe3, 0x57, 0x88, 0xd7, 0xf8, 0x5f, 0xaf, 0x5d, 0xaf, 0x88, 0x32, 0xb4, 0x09, 0x3e, 0x7c, 0x25, 0x77,
+    0x35, 0xe9, 0x3e, 0x6e, 0x0a, 0xb9, 0xb4, 0xa3, 0x06, 0x07, 0x0f, 0x7e, 0x93, 0x26, 0x16, 0x38, 0x1e, 0x4e, 0x72, 0xaf,
+    0x06, 0x44, 0x1e, 0x8d, 0x96, 0xa6, 0x15, 0x9c, 0x82, 0x6d, 0x71, 0x99, 0x84, 0x8d, 0x12, 0x46, 0xf2, 0xbb, 0xa7, 0x63,
+    0x7a, 0x32, 0xda, 0xa9, 0xde, 0xb6, 0x34, 0x14, 0xfb, 0x07, 0x0c, 0xab, 0x3b, 0x0a, 0xa1, 0x8b, 0xda, 0x15, 0xb3, 0x63,
+    0xf3, 0x5c, 0x45, 0x2f, 0x0b, 0x6e, 0xc7, 0x27, 0x72, 0xc1, 0x37, 0x56, 0x30, 0xe3, 0x26, 0xbb, 0x19, 0x4f, 0x91, 0xa1,
+    0xd0, 0x30, 0x29, 0x5b, 0x79, 0x79, 0x5c, 0xe6, 0x4f, 0xed, 0xcf, 0x81, 0xb2, 0x50, 0x35, 0x96, 0x23, 0xb2, 0x9f, 0xca,
+    0x3f, 0xb5, 0x54, 0x31, 0x82, 0x01, 0xdb, 0x30, 0x82, 0x01, 0xd7, 0x02, 0x01, 0x01, 0x30, 0x81, 0xb0, 0x30, 0x81, 0xa7,
+    0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x43, 0x4d, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54,
+    0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+    0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41,
+    0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
+    0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x40, 0x61, 0x70,
+    0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x02, 0x04, 0x74, 0x3f, 0x1d, 0x98, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x0d, 0x02, 0x20, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+    0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x44, 0x4f, 0x1c, 0x4f, 0x73, 0x46, 0xb4, 0x67, 0x86, 0x53, 0x6e, 0x09, 0x4a, 0x18,
+    0x89, 0x82, 0xb0, 0x9d, 0xf5, 0xa9, 0x81, 0x21, 0x97, 0x2d, 0x1c, 0x61, 0x4a, 0xa0, 0x9a, 0xa1, 0x6d, 0xb0, 0xb2, 0xbe,
+    0xc8, 0x27, 0x4a, 0x0e, 0xbd, 0x52, 0xf2, 0x56, 0x8a, 0xb6, 0x41, 0x45, 0xfc, 0xf6, 0x09, 0xb7, 0x83, 0x89, 0x87, 0xc6,
+    0x5c, 0xfb, 0xe0, 0x22, 0x75, 0x9b, 0xa2, 0x24, 0x65, 0xd0, 0x51, 0xe0, 0xc6, 0x00, 0xad, 0x39, 0x50, 0x84, 0x31, 0x5c,
+    0x63, 0x54, 0x8c, 0x3c, 0xa3, 0x69, 0x7f, 0xb2, 0x2c, 0x60, 0xa1, 0x5d, 0x6a, 0xac, 0xb2, 0x02, 0x26, 0x5b, 0x82, 0x61,
+    0x2e, 0xb0, 0x32, 0xf7, 0x4e, 0xa3, 0x31, 0x00, 0xa7, 0x29, 0x4b, 0xdc, 0x30, 0x7f, 0x33, 0x14, 0x5a, 0xf1, 0x58, 0x5e,
+    0x90, 0x77, 0xf3, 0x9c, 0x68, 0xbe, 0xe9, 0x4c, 0xf6, 0x33, 0x64, 0xdf, 0x3f, 0xf4, 0xb9, 0x6b, 0xd5, 0x54, 0xb8, 0x4a,
+    0x8f, 0xbb, 0xce, 0xde, 0x4a, 0x58, 0x9e, 0xad, 0x67, 0x99, 0xbe, 0xe7, 0x0a, 0x54, 0x2b, 0x19, 0x0c, 0x45, 0x45, 0x41,
+    0x9e, 0x56, 0x07, 0x45, 0x95, 0x56, 0x92, 0xa8, 0xd6, 0x8f, 0xab, 0xb0, 0x9b, 0x39, 0xcb, 0x5a, 0x0d, 0x29, 0x2d, 0x8b,
+    0x53, 0xf4, 0x85, 0xb1, 0xec, 0x6f, 0x95, 0xd2, 0x6e, 0xd5, 0x36, 0x65, 0xd4, 0x30, 0x4d, 0x26, 0x37, 0x8b, 0x06, 0x39,
+    0xf5, 0xe6, 0xde, 0x8c, 0xf0, 0x84, 0x69, 0x96, 0xd7, 0xb9, 0x22, 0x24, 0xf5, 0x74, 0x69, 0x4e, 0x2b, 0xea, 0x9d, 0x5a,
+    0xd7, 0xfc, 0xea, 0x7d, 0x8f, 0xd7, 0x34, 0x7f, 0x4f, 0x8a, 0x5c, 0xb6, 0x73, 0x9a, 0x8f, 0xa0, 0x74, 0x5e, 0xca, 0xdc,
+    0xc9, 0x78, 0x85, 0x46, 0xb8, 0x79, 0x29, 0x10, 0xa5, 0x6c, 0x1e, 0x4e, 0xac, 0xba, 0x8e, 0xa2, 0x2d, 0xf8, 0x40, 0x2d,
+    0xde, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
 unsigned char rsa_md5[] = {
     0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
     0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
 unsigned char rsa_md5[] = {
     0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
     0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
@@ -750,6 +833,59 @@ unsigned char rsa_sha256_attr[] = {
 /*
  * MARK: EC-signed messages (no attributes)
  */
 /*
  * MARK: EC-signed messages (no attributes)
  */
+unsigned char ec_sinfo_unknown_digest[] = {
+    0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
+    0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x29, 0x54, 0x68, 0x69, 0x73, 0x20,
+    0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x20, 0x41,
+    0x69, 0x6e, 0x27, 0x74, 0x20, 0x69, 0x74, 0x20, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xa0, 0x82, 0x02, 0x57, 0x30, 0x82, 0x02, 0x53, 0x30, 0x82, 0x01, 0xf9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
+    0x04, 0x50, 0x2b, 0xa2, 0xa7, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x81, 0xa6,
+    0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x43, 0x4d, 0x53, 0x20, 0x45, 0x43, 0x20, 0x54, 0x65,
+    0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+    0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
+    0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41, 0x72,
+    0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
+    0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x40, 0x61, 0x70, 0x70,
+    0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x33, 0x31, 0x34, 0x30, 0x30, 0x31, 0x39,
+    0x35, 0x36, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x31, 0x33, 0x30, 0x30, 0x31, 0x39, 0x35, 0x36, 0x5a, 0x30, 0x81,
+    0xa6, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x43, 0x4d, 0x53, 0x20, 0x45, 0x43, 0x20, 0x54,
+    0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+    0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41,
+    0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
+    0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x40, 0x61, 0x70,
+    0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,
+    0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x71, 0x39, 0x79, 0x59, 0x3f, 0x88,
+    0x07, 0x03, 0x42, 0x1a, 0x09, 0x93, 0x0d, 0xcd, 0x1b, 0x5a, 0xa7, 0x2f, 0x7d, 0x5f, 0xc2, 0x7b, 0xd9, 0x81, 0xb8, 0x81,
+    0xa1, 0x4e, 0xc5, 0x36, 0xae, 0xc7, 0xe1, 0xa4, 0xf0, 0x0f, 0x4e, 0x75, 0x34, 0xbc, 0xb0, 0xc8, 0xf3, 0xe6, 0x87, 0x6c,
+    0xc4, 0xcd, 0x8c, 0x8f, 0x1c, 0xbc, 0xb1, 0x16, 0x46, 0x22, 0x6f, 0xfa, 0x00, 0xfc, 0xac, 0x57, 0x65, 0xe1, 0xa3, 0x13,
+    0x30, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
+    0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0x81,
+    0x1b, 0xed, 0x5a, 0x08, 0x6d, 0xdb, 0x89, 0xef, 0x27, 0x9b, 0x8d, 0xe6, 0x6f, 0xd0, 0x56, 0xfd, 0xb9, 0x33, 0xe4, 0x85,
+    0x7a, 0x2f, 0x65, 0x39, 0x6c, 0x0d, 0xef, 0xd5, 0x82, 0xc9, 0x7d, 0x02, 0x20, 0x34, 0x18, 0xb8, 0xaf, 0xf2, 0x05, 0xcb,
+    0xeb, 0xf7, 0x1c, 0x73, 0x77, 0x8d, 0x03, 0xcc, 0xc7, 0x80, 0x34, 0x44, 0x8f, 0x51, 0x6a, 0x6d, 0x80, 0x46, 0xce, 0xf5,
+    0xbe, 0x85, 0x40, 0x5a, 0xdd, 0x31, 0x82, 0x01, 0x1b, 0x30, 0x82, 0x01, 0x17, 0x02, 0x01, 0x01, 0x30, 0x81, 0xaf, 0x30,
+    0x81, 0xa6, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x43, 0x4d, 0x53, 0x20, 0x45, 0x43, 0x20,
+    0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72,
+    0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20,
+    0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+    0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x40, 0x61,
+    0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x02, 0x04, 0x50, 0x2b, 0xa2, 0xa7, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x02, 0x20, 0x05, 0x00, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x04,
+    0x47, 0x30, 0x45, 0x02, 0x21, 0x00, 0xa2, 0x9f, 0x73, 0x2d, 0x2a, 0xa0, 0xca, 0xb4, 0xf6, 0xc9, 0xfd, 0x68, 0xd2, 0xe7,
+    0x8d, 0x07, 0xdd, 0x60, 0xcc, 0xe1, 0xb6, 0xfe, 0xa9, 0x11, 0xd8, 0xb7, 0x68, 0xa4, 0xe3, 0xed, 0x1b, 0x42, 0x02, 0x20,
+    0x4b, 0x64, 0x3e, 0xe0, 0x50, 0x29, 0x89, 0x30, 0xd0, 0x32, 0x2d, 0xfc, 0xd3, 0x6b, 0xe8, 0x06, 0x15, 0xe2, 0x91, 0x99,
+    0x7b, 0x26, 0xc4, 0xa3, 0x85, 0xf0, 0x05, 0x95, 0x4d, 0xf9, 0x51, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
 unsigned char ec_md5[] = {
     0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
     0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
 unsigned char ec_md5[] = {
     0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
     0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
index bd0aaea64eb7484f011931b9327eec7b9c192bec..e2e9f709ee612515fc7e49c15146fd54ead84b27 100644 (file)
@@ -336,9 +336,9 @@ tests(void)
                 fcntl(sp[1], F_SETNOSIGPIPE, 1);
 
                 bool break_on_req = (j!=0);
                 fcntl(sp[1], F_SETNOSIGPIPE, 1);
 
                 bool break_on_req = (j!=0);
-                SSLClientAuthenticationType auth = (k == 0) ? kNeverAuthenticate
-                                                   : (k == 1) ? kTryAuthenticate
-                                                   : kAlwaysAuthenticate;
+                SSLAuthenticate auth = (k == 0) ? kNeverAuthenticate
+                        : (k == 1) ? kTryAuthenticate
+                            : kAlwaysAuthenticate;
 
                 CFArrayRef client_certs = (i == 0) ? NULL
                                           : (i == 1) ? trusted_client_chain()
 
                 CFArrayRef client_certs = (i == 0) ? NULL
                                           : (i == 1) ? trusted_client_chain()
index 9c99aea556b9b3d15397a2b407721df5350a1d6c..e715b11d3e93756c5903ddc5702c96319a2b034b 100644 (file)
@@ -199,6 +199,12 @@ int MacOSError::unixError() const
 void MacOSError::throwMe(int error)
 { throw MacOSError(error); }
 
 void MacOSError::throwMe(int error)
 { throw MacOSError(error); }
 
+void MacOSError::throwMe(int error, char const *message, ...)
+{
+    // Ignoring the message for now, will do something with it later.
+    throw MacOSError(error);
+}
+
 MacOSError MacOSError::make(int error)
 { return MacOSError(error); }
 
 MacOSError MacOSError::make(int error)
 { return MacOSError(error); }
 
index d3ee946c76ca37fb0a04a8b8137707a388919d93..4baae8f38c3524d745d50f6f11d371b32d9dd1b2 100644 (file)
@@ -100,6 +100,7 @@ public:
     
     static void check(OSStatus status) { if (status != errSecSuccess) throwMe(status); }
     static void throwMe(int err) __attribute__((noreturn));
     
     static void check(OSStatus status) { if (status != errSecSuccess) throwMe(status); }
     static void throwMe(int err) __attribute__((noreturn));
+    static void throwMe(int err, char const *message, ...) __attribute__((noreturn));
 
     static MacOSError make(int err);
 };
 
     static MacOSError make(int err);
 };
index 29ffa83a3c97936646451b291667abb3192e464b..30408289b788c09693dd86c022324d2968b25f90 100644 (file)
@@ -562,6 +562,9 @@ kern_return_t cdsa_mach_notify_dead_name(mach_port_t, mach_port_name_t port)
                MachServer::active().notifyDeadName(port);
        } catch (...) {
        }
                MachServer::active().notifyDeadName(port);
        } catch (...) {
        }
+    // the act of receiving a dead name notification allocates a dead-name
+    // right that must be deallocated
+    mach_port_deallocate(mach_task_self(), port);
        return KERN_SUCCESS;
 }
 
        return KERN_SUCCESS;
 }
 
index 6a03d1842f4a77edb333f270edcc6e2ce953196f..99f58033ec4ce5344b1ebd19914e227650490683 100644 (file)
@@ -562,6 +562,7 @@ extern const CFStringRef kCKKSViewAutoUnlock;
 extern const CFStringRef kCKKSViewHealth;
 extern const CFStringRef kCKKSViewApplePay;
 extern const CFStringRef kCKKSViewHome;
 extern const CFStringRef kCKKSViewHealth;
 extern const CFStringRef kCKKSViewApplePay;
 extern const CFStringRef kCKKSViewHome;
+extern const CFStringRef kCKKSViewLimitedPeersAllowed;
 
 
 /*!
 
 
 /*!
index 41449d5938868d61bd3c5e4a962fb07ceffb5fe6..b23b682c79c8ff61aa15d6b11011abe00c05f3c5 100644 (file)
@@ -61,8 +61,9 @@ static bool SOSDigestVectorEnsureCapacity(struct SOSDigestVector *dv, size_t cou
 
 static void SOSDigestVectorAppendOrdered(struct SOSDigestVector *dv, const uint8_t *digest)
 {
 
 static void SOSDigestVectorAppendOrdered(struct SOSDigestVector *dv, const uint8_t *digest)
 {
-       if (SOSDigestVectorEnsureCapacity(dv, dv->count + 1))
+    if (digest && SOSDigestVectorEnsureCapacity(dv, dv->count + 1)) {
         memcpy(dv->digest[dv->count++], digest, SOSDigestSize);
         memcpy(dv->digest[dv->count++], digest, SOSDigestSize);
+    }
 }
 
 void SOSDigestVectorAppend(struct SOSDigestVector *dv, const uint8_t *digest)
 }
 
 void SOSDigestVectorAppend(struct SOSDigestVector *dv, const uint8_t *digest)
index 672ebed2d8af855dc8606bb481198b58841bdd78..fe1b18c47f227688d7831d6221c93d7ffa37e149 100644 (file)
@@ -471,7 +471,8 @@ bool SOSEngineInitializePeerCoder(SOSEngineRef engine, SOSFullPeerInfoRef myPeer
 
     ok &= SOSEngineWithPeerID(engine, peerID, error, ^(SOSPeerRef peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) {
         ok = SOSEngineEnsureCoder_locked(engine, txn, peerID, myPeerInfo, peerInfo, coder, error);
 
     ok &= SOSEngineWithPeerID(engine, peerID, error, ^(SOSPeerRef peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) {
         ok = SOSEngineEnsureCoder_locked(engine, txn, peerID, myPeerInfo, peerInfo, coder, error);
-        *forceSaveState = ok;
+        // Only set if the codersNeedSaving state gets set.
+        *forceSaveState = engine->codersNeedSaving;
     });
 
     return ok;
     });
 
     return ok;
@@ -936,7 +937,12 @@ static void SOSEngineObjectWithView(SOSEngineRef engine, SOSObjectRef object, vo
             CFTypeRef tomb = SecDbItemGetCachedValueWithName(item, kSecAttrTombstone);
             char cvalue = 0;
             bool isTomb = (isNumber(tomb) && CFNumberGetValue(tomb, kCFNumberCharType, &cvalue) && cvalue == 1);
             CFTypeRef tomb = SecDbItemGetCachedValueWithName(item, kSecAttrTombstone);
             char cvalue = 0;
             bool isTomb = (isNumber(tomb) && CFNumberGetValue(tomb, kCFNumberCharType, &cvalue) && cvalue == 1);
-            CFTypeRef viewHint = SecDbItemGetCachedValueWithName(item, kSecAttrSyncViewHint);
+            CFStringRef viewHint = SecDbItemGetCachedValueWithName(item, kSecAttrSyncViewHint);
+
+            // check that view hint is a string, if its unset it will be kCFNull
+            if (!isString(viewHint)) {
+                viewHint = NULL;
+            }
 
             // Intecept CKKS-handled items here and short-circuit function
             if(SOSViewHintInCKKSSystem(viewHint)) {
 
             // Intecept CKKS-handled items here and short-circuit function
             if(SOSViewHintInCKKSSystem(viewHint)) {
index b3aa9753eb38abe4706b11a43f563a5f37f4fc76..4e81b1c130240649fffc4d6891f582eb80d00d79 100644 (file)
@@ -183,7 +183,7 @@ static SecKeyRef ccec2SecKey(ccec_full_ctx_t fk)
 
     CFRelease(keyattributes);
     CFRelease(exportedkey);
 
     CFRelease(keyattributes);
     CFRelease(exportedkey);
-    bzero(export_keybytes, 0);
+    cc_clear(export_size, export_keybytes);
     return retval;
 }
 
     return retval;
 }
 
index 165b384239bddae09b248a8ff8099fcc14c2825b..19b3cdd645f65a6c9424864c976826bf4b118c4b 100644 (file)
@@ -47,4 +47,5 @@ DOVIEWMACRO(AutoUnlock,             "AutoUnlock",           "autounlock",
 DOVIEWMACRO(Health,                 "Health",               "health",                  CKKS, D,  , A,  ,  )
 DOVIEWMACRO(ApplePay,               "ApplePay",             "applepay",                CKKS, D,  , A,  ,  )
 DOVIEWMACRO(Home,                   "Home",                 "home",                    CKKS, D,  , A,  ,  )
 DOVIEWMACRO(Health,                 "Health",               "health",                  CKKS, D,  , A,  ,  )
 DOVIEWMACRO(ApplePay,               "ApplePay",             "applepay",                CKKS, D,  , A,  ,  )
 DOVIEWMACRO(Home,                   "Home",                 "home",                    CKKS, D,  , A,  ,  )
+DOVIEWMACRO(LimitedPeersAllowed,    "LimitedPeersAllowed",  "limitedpeersallowed",     CKKS, D,  , A,  ,  )
 
 
index 04a292f382f5ebbfc9c262ce445973e2abb25181..18611e4448de69de618897a3fd2ab5ba1e3eec77 100644 (file)
@@ -391,7 +391,7 @@ static void sign_tests(SecIdentityRef identity, bool isRSA) {
 
 /* Verifying with attributes goes through a different code path than verifying without,
  * so we need to test both. */
 
 /* Verifying with attributes goes through a different code path than verifying without,
  * so we need to test both. */
-#define kNumberVerifyTests 12
+#define kNumberVerifyTests 13
 static void verify_tests(SecKeychainRef kc, bool isRsa) {
     /* no attributes */
     is(verify_please(kc, (isRsa) ? rsa_md5 : ec_md5,
 static void verify_tests(SecKeychainRef kc, bool isRsa) {
     /* no attributes */
     is(verify_please(kc, (isRsa) ? rsa_md5 : ec_md5,
@@ -418,6 +418,9 @@ static void verify_tests(SecKeychainRef kc, bool isRsa) {
     /***** Once more, with validation errors *****/
 
     /* no attributes */
     /***** Once more, with validation errors *****/
 
     /* no attributes */
+    is(verify_please(kc, (isRsa) ? rsa_sinfo_unknown_digest : ec_sinfo_unknown_digest,
+                     (isRsa) ? sizeof(rsa_sinfo_unknown_digest) : sizeof(ec_sinfo_unknown_digest)),
+       errSecInvalidDigestAlgorithm, "Verify unknown digest OID in signer info");
     is(invalidate_and_verify(kc, (isRsa) ? rsa_md5 : ec_md5,
                              (isRsa) ? sizeof(rsa_md5) : sizeof(ec_md5)),
        SECFailure, "Verify invalid MD5, no attributes");
     is(invalidate_and_verify(kc, (isRsa) ? rsa_md5 : ec_md5,
                              (isRsa) ? sizeof(rsa_md5) : sizeof(ec_md5)),
        SECFailure, "Verify invalid MD5, no attributes");
index dc46feeb33e743212176322059a86f11b97e0af9..371b8f69bdf8d5fa2effe8371f7239003c0131b3 100644 (file)
@@ -233,6 +233,89 @@ unsigned char _ec_identity[] = {
 /*
  * MARK: RSA-signed messages (no attributes)
  */
 /*
  * MARK: RSA-signed messages (no attributes)
  */
+unsigned char rsa_sinfo_unknown_digest[] = {
+    0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
+    0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x29, 0x54, 0x68, 0x69, 0x73, 0x20,
+    0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x20, 0x41,
+    0x69, 0x6e, 0x27, 0x74, 0x20, 0x69, 0x74, 0x20, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xa0, 0x82, 0x03, 0xe5, 0x30, 0x82, 0x03, 0xe1, 0x30, 0x82, 0x02, 0xc9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
+    0x04, 0x74, 0x3f, 0x1d, 0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
+    0x30, 0x81, 0xa7, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x43, 0x4d, 0x53, 0x20, 0x52, 0x53,
+    0x41, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+    0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65,
+    0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53, 0x65, 0x63,
+    0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e,
+    0x64, 0x20, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+    0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f, 0x06,
+    0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65,
+    0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x33, 0x31, 0x34,
+    0x30, 0x30, 0x31, 0x38, 0x32, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x31, 0x33, 0x30, 0x30, 0x31, 0x38, 0x32,
+    0x39, 0x5a, 0x30, 0x81, 0xa7, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x43, 0x4d, 0x53, 0x20,
+    0x52, 0x53, 0x41, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53,
+    0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20,
+    0x61, 0x6e, 0x64, 0x20, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11,
+    0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30,
+    0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61,
+    0x6d, 0x65, 0x40, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
+    0x02, 0x82, 0x01, 0x01, 0x00, 0xe2, 0x9b, 0xcb, 0x6c, 0x77, 0xb7, 0xd1, 0x05, 0xa0, 0xae, 0x86, 0x20, 0x45, 0xd3, 0xf4,
+    0x24, 0x8d, 0x25, 0x34, 0x31, 0xa9, 0xe2, 0x10, 0x36, 0xf5, 0x0a, 0x0b, 0x90, 0x4a, 0xa5, 0x6b, 0x5c, 0x16, 0xcd, 0xb0,
+    0x72, 0xe9, 0xa9, 0x80, 0x5f, 0x6d, 0xb2, 0x4d, 0xd9, 0x58, 0x16, 0x9f, 0x68, 0x81, 0x9a, 0x6b, 0xeb, 0xd5, 0x4b, 0xf7,
+    0x7d, 0x59, 0xe9, 0x46, 0x2b, 0x5b, 0x8f, 0xe4, 0xec, 0xab, 0x5c, 0x07, 0x74, 0xa2, 0x0e, 0x59, 0xbb, 0xfc, 0xd3, 0xcf,
+    0xf7, 0x21, 0x88, 0x6c, 0x88, 0xd9, 0x6b, 0xa3, 0xa3, 0x4e, 0x5b, 0xd1, 0x1c, 0xfb, 0x04, 0xf5, 0xb2, 0x12, 0x0e, 0x54,
+    0x59, 0x4d, 0xce, 0x0a, 0xe0, 0x26, 0x24, 0x06, 0xeb, 0xc8, 0xa2, 0xc6, 0x41, 0x28, 0xf9, 0x79, 0xe4, 0xb1, 0x4e, 0x00,
+    0x6f, 0x6e, 0xf8, 0x96, 0x9e, 0x45, 0x28, 0x70, 0xec, 0xc7, 0xdc, 0xa2, 0xdd, 0x92, 0xab, 0xdd, 0x6f, 0xd8, 0x57, 0xba,
+    0xcc, 0x29, 0xbe, 0xb7, 0x00, 0x1e, 0x8d, 0x13, 0x3f, 0x47, 0x34, 0x3c, 0xd0, 0xc6, 0xc8, 0x17, 0xdf, 0x74, 0x8a, 0xb1,
+    0xc3, 0x68, 0xd5, 0xba, 0x76, 0x60, 0x55, 0x5f, 0x8d, 0xfa, 0xbd, 0xe7, 0x11, 0x9e, 0x59, 0x96, 0xe5, 0x93, 0x70, 0xad,
+    0x41, 0xfb, 0x61, 0x46, 0x70, 0xc4, 0x05, 0x12, 0x23, 0x23, 0xc0, 0x9d, 0xc8, 0xc5, 0xf5, 0x96, 0xe5, 0x48, 0x10, 0x86,
+    0x8a, 0x1e, 0x3b, 0x83, 0xd1, 0x47, 0x3a, 0x27, 0x00, 0x71, 0x10, 0xa3, 0x52, 0xba, 0xae, 0x01, 0x43, 0x87, 0x9c, 0x6a,
+    0x1b, 0xea, 0x1a, 0x44, 0x4f, 0x4a, 0xac, 0xd4, 0x82, 0x55, 0xee, 0x1f, 0x25, 0x9c, 0x55, 0xca, 0xd2, 0xd0, 0x3a, 0x0b,
+    0x70, 0x90, 0x60, 0x49, 0x47, 0x02, 0xfd, 0x89, 0x2c, 0x9a, 0x26, 0x36, 0x34, 0x8f, 0x24, 0x39, 0x8c, 0xe9, 0xa2, 0x52,
+    0x8f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x13, 0x30, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
+    0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+    0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4c, 0xed, 0x5b, 0xaf, 0x13, 0x16, 0x5d, 0xe2, 0xdd, 0x5c, 0x48, 0x1c, 0xd5,
+    0x6e, 0x8b, 0x04, 0x51, 0xd6, 0x38, 0x80, 0xfd, 0x52, 0x4a, 0x34, 0xdc, 0x13, 0x35, 0x6e, 0x64, 0x39, 0x39, 0x39, 0x09,
+    0xa7, 0x6c, 0x2d, 0x39, 0xf2, 0x04, 0x21, 0xe3, 0xea, 0x8f, 0xf8, 0xbe, 0x46, 0x0e, 0x20, 0x82, 0xd0, 0xc5, 0x60, 0xbf,
+    0x57, 0x6f, 0xd8, 0x29, 0xb4, 0x66, 0xdb, 0xbf, 0x92, 0xc9, 0xdc, 0x90, 0x97, 0x0f, 0x2f, 0x59, 0xa0, 0x13, 0xf3, 0xa4,
+    0xca, 0xde, 0x3f, 0x80, 0x2a, 0x99, 0xb4, 0xee, 0x71, 0xc3, 0x56, 0x71, 0x51, 0x37, 0x55, 0xa1, 0x60, 0x89, 0xab, 0x94,
+    0x0e, 0xb9, 0x70, 0xa5, 0x55, 0xf3, 0x1a, 0x87, 0xa4, 0x41, 0x4c, 0x45, 0xba, 0xb6, 0x56, 0xd6, 0x45, 0x56, 0x12, 0x60,
+    0xe5, 0x91, 0xec, 0xf7, 0xbe, 0x39, 0xa4, 0x80, 0x08, 0x9f, 0xea, 0x17, 0x12, 0x0e, 0xa6, 0xe6, 0xef, 0x09, 0xf7, 0x61,
+    0x51, 0x57, 0x73, 0xe3, 0x57, 0x88, 0xd7, 0xf8, 0x5f, 0xaf, 0x5d, 0xaf, 0x88, 0x32, 0xb4, 0x09, 0x3e, 0x7c, 0x25, 0x77,
+    0x35, 0xe9, 0x3e, 0x6e, 0x0a, 0xb9, 0xb4, 0xa3, 0x06, 0x07, 0x0f, 0x7e, 0x93, 0x26, 0x16, 0x38, 0x1e, 0x4e, 0x72, 0xaf,
+    0x06, 0x44, 0x1e, 0x8d, 0x96, 0xa6, 0x15, 0x9c, 0x82, 0x6d, 0x71, 0x99, 0x84, 0x8d, 0x12, 0x46, 0xf2, 0xbb, 0xa7, 0x63,
+    0x7a, 0x32, 0xda, 0xa9, 0xde, 0xb6, 0x34, 0x14, 0xfb, 0x07, 0x0c, 0xab, 0x3b, 0x0a, 0xa1, 0x8b, 0xda, 0x15, 0xb3, 0x63,
+    0xf3, 0x5c, 0x45, 0x2f, 0x0b, 0x6e, 0xc7, 0x27, 0x72, 0xc1, 0x37, 0x56, 0x30, 0xe3, 0x26, 0xbb, 0x19, 0x4f, 0x91, 0xa1,
+    0xd0, 0x30, 0x29, 0x5b, 0x79, 0x79, 0x5c, 0xe6, 0x4f, 0xed, 0xcf, 0x81, 0xb2, 0x50, 0x35, 0x96, 0x23, 0xb2, 0x9f, 0xca,
+    0x3f, 0xb5, 0x54, 0x31, 0x82, 0x01, 0xdb, 0x30, 0x82, 0x01, 0xd7, 0x02, 0x01, 0x01, 0x30, 0x81, 0xb0, 0x30, 0x81, 0xa7,
+    0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x43, 0x4d, 0x53, 0x20, 0x52, 0x53, 0x41, 0x20, 0x54,
+    0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+    0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41,
+    0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
+    0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x40, 0x61, 0x70,
+    0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x02, 0x04, 0x74, 0x3f, 0x1d, 0x98, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x0d, 0x02, 0x20, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
+    0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x44, 0x4f, 0x1c, 0x4f, 0x73, 0x46, 0xb4, 0x67, 0x86, 0x53, 0x6e, 0x09, 0x4a, 0x18,
+    0x89, 0x82, 0xb0, 0x9d, 0xf5, 0xa9, 0x81, 0x21, 0x97, 0x2d, 0x1c, 0x61, 0x4a, 0xa0, 0x9a, 0xa1, 0x6d, 0xb0, 0xb2, 0xbe,
+    0xc8, 0x27, 0x4a, 0x0e, 0xbd, 0x52, 0xf2, 0x56, 0x8a, 0xb6, 0x41, 0x45, 0xfc, 0xf6, 0x09, 0xb7, 0x83, 0x89, 0x87, 0xc6,
+    0x5c, 0xfb, 0xe0, 0x22, 0x75, 0x9b, 0xa2, 0x24, 0x65, 0xd0, 0x51, 0xe0, 0xc6, 0x00, 0xad, 0x39, 0x50, 0x84, 0x31, 0x5c,
+    0x63, 0x54, 0x8c, 0x3c, 0xa3, 0x69, 0x7f, 0xb2, 0x2c, 0x60, 0xa1, 0x5d, 0x6a, 0xac, 0xb2, 0x02, 0x26, 0x5b, 0x82, 0x61,
+    0x2e, 0xb0, 0x32, 0xf7, 0x4e, 0xa3, 0x31, 0x00, 0xa7, 0x29, 0x4b, 0xdc, 0x30, 0x7f, 0x33, 0x14, 0x5a, 0xf1, 0x58, 0x5e,
+    0x90, 0x77, 0xf3, 0x9c, 0x68, 0xbe, 0xe9, 0x4c, 0xf6, 0x33, 0x64, 0xdf, 0x3f, 0xf4, 0xb9, 0x6b, 0xd5, 0x54, 0xb8, 0x4a,
+    0x8f, 0xbb, 0xce, 0xde, 0x4a, 0x58, 0x9e, 0xad, 0x67, 0x99, 0xbe, 0xe7, 0x0a, 0x54, 0x2b, 0x19, 0x0c, 0x45, 0x45, 0x41,
+    0x9e, 0x56, 0x07, 0x45, 0x95, 0x56, 0x92, 0xa8, 0xd6, 0x8f, 0xab, 0xb0, 0x9b, 0x39, 0xcb, 0x5a, 0x0d, 0x29, 0x2d, 0x8b,
+    0x53, 0xf4, 0x85, 0xb1, 0xec, 0x6f, 0x95, 0xd2, 0x6e, 0xd5, 0x36, 0x65, 0xd4, 0x30, 0x4d, 0x26, 0x37, 0x8b, 0x06, 0x39,
+    0xf5, 0xe6, 0xde, 0x8c, 0xf0, 0x84, 0x69, 0x96, 0xd7, 0xb9, 0x22, 0x24, 0xf5, 0x74, 0x69, 0x4e, 0x2b, 0xea, 0x9d, 0x5a,
+    0xd7, 0xfc, 0xea, 0x7d, 0x8f, 0xd7, 0x34, 0x7f, 0x4f, 0x8a, 0x5c, 0xb6, 0x73, 0x9a, 0x8f, 0xa0, 0x74, 0x5e, 0xca, 0xdc,
+    0xc9, 0x78, 0x85, 0x46, 0xb8, 0x79, 0x29, 0x10, 0xa5, 0x6c, 0x1e, 0x4e, 0xac, 0xba, 0x8e, 0xa2, 0x2d, 0xf8, 0x40, 0x2d,
+    0xde, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
 unsigned char rsa_md5[] = {
     0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
     0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
 unsigned char rsa_md5[] = {
     0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
     0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
@@ -750,6 +833,59 @@ unsigned char rsa_sha256_attr[] = {
 /*
  * MARK: EC-signed messages (no attributes)
  */
 /*
  * MARK: EC-signed messages (no attributes)
  */
+unsigned char ec_sinfo_unknown_digest[] = {
+    0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
+    0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x80, 0x24, 0x80, 0x04, 0x29, 0x54, 0x68, 0x69, 0x73, 0x20,
+    0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x69, 0x73, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x2e, 0x20, 0x41,
+    0x69, 0x6e, 0x27, 0x74, 0x20, 0x69, 0x74, 0x20, 0x70, 0x72, 0x65, 0x74, 0x74, 0x79, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xa0, 0x82, 0x02, 0x57, 0x30, 0x82, 0x02, 0x53, 0x30, 0x82, 0x01, 0xf9, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
+    0x04, 0x50, 0x2b, 0xa2, 0xa7, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x81, 0xa6,
+    0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x43, 0x4d, 0x53, 0x20, 0x45, 0x43, 0x20, 0x54, 0x65,
+    0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+    0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e,
+    0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
+    0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41, 0x72,
+    0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
+    0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48,
+    0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x40, 0x61, 0x70, 0x70,
+    0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x33, 0x31, 0x34, 0x30, 0x30, 0x31, 0x39,
+    0x35, 0x36, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x34, 0x31, 0x33, 0x30, 0x30, 0x31, 0x39, 0x35, 0x36, 0x5a, 0x30, 0x81,
+    0xa6, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x43, 0x4d, 0x53, 0x20, 0x45, 0x43, 0x20, 0x54,
+    0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55,
+    0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
+    0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41,
+    0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
+    0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x40, 0x61, 0x70,
+    0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,
+    0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x71, 0x39, 0x79, 0x59, 0x3f, 0x88,
+    0x07, 0x03, 0x42, 0x1a, 0x09, 0x93, 0x0d, 0xcd, 0x1b, 0x5a, 0xa7, 0x2f, 0x7d, 0x5f, 0xc2, 0x7b, 0xd9, 0x81, 0xb8, 0x81,
+    0xa1, 0x4e, 0xc5, 0x36, 0xae, 0xc7, 0xe1, 0xa4, 0xf0, 0x0f, 0x4e, 0x75, 0x34, 0xbc, 0xb0, 0xc8, 0xf3, 0xe6, 0x87, 0x6c,
+    0xc4, 0xcd, 0x8c, 0x8f, 0x1c, 0xbc, 0xb1, 0x16, 0x46, 0x22, 0x6f, 0xfa, 0x00, 0xfc, 0xac, 0x57, 0x65, 0xe1, 0xa3, 0x13,
+    0x30, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
+    0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0x81,
+    0x1b, 0xed, 0x5a, 0x08, 0x6d, 0xdb, 0x89, 0xef, 0x27, 0x9b, 0x8d, 0xe6, 0x6f, 0xd0, 0x56, 0xfd, 0xb9, 0x33, 0xe4, 0x85,
+    0x7a, 0x2f, 0x65, 0x39, 0x6c, 0x0d, 0xef, 0xd5, 0x82, 0xc9, 0x7d, 0x02, 0x20, 0x34, 0x18, 0xb8, 0xaf, 0xf2, 0x05, 0xcb,
+    0xeb, 0xf7, 0x1c, 0x73, 0x77, 0x8d, 0x03, 0xcc, 0xc7, 0x80, 0x34, 0x44, 0x8f, 0x51, 0x6a, 0x6d, 0x80, 0x46, 0xce, 0xf5,
+    0xbe, 0x85, 0x40, 0x5a, 0xdd, 0x31, 0x82, 0x01, 0x1b, 0x30, 0x82, 0x01, 0x17, 0x02, 0x01, 0x01, 0x30, 0x81, 0xaf, 0x30,
+    0x81, 0xa6, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x10, 0x43, 0x4d, 0x53, 0x20, 0x45, 0x43, 0x20,
+    0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x55, 0x53, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20,
+    0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72,
+    0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20,
+    0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+    0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a,
+    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x40, 0x61,
+    0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x02, 0x04, 0x50, 0x2b, 0xa2, 0xa7, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x0d, 0x02, 0x20, 0x05, 0x00, 0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x04,
+    0x47, 0x30, 0x45, 0x02, 0x21, 0x00, 0xa2, 0x9f, 0x73, 0x2d, 0x2a, 0xa0, 0xca, 0xb4, 0xf6, 0xc9, 0xfd, 0x68, 0xd2, 0xe7,
+    0x8d, 0x07, 0xdd, 0x60, 0xcc, 0xe1, 0xb6, 0xfe, 0xa9, 0x11, 0xd8, 0xb7, 0x68, 0xa4, 0xe3, 0xed, 0x1b, 0x42, 0x02, 0x20,
+    0x4b, 0x64, 0x3e, 0xe0, 0x50, 0x29, 0x89, 0x30, 0xd0, 0x32, 0x2d, 0xfc, 0xd3, 0x6b, 0xe8, 0x06, 0x15, 0xe2, 0x91, 0x99,
+    0x7b, 0x26, 0xc4, 0xa3, 0x85, 0xf0, 0x05, 0x95, 0x4d, 0xf9, 0x51, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
 unsigned char ec_md5[] = {
     0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
     0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
 unsigned char ec_md5[] = {
     0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01,
     0x31, 0x0e, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09,
diff --git a/OSX/sec/Security/SecAccessControl.c b/OSX/sec/Security/SecAccessControl.c
deleted file mode 100644 (file)
index ed8671b..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright (c) 2014 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@
- */
-
-/*
- * SecAccessControl.c - CoreFoundation based access control object
- */
-
-#include <TargetConditionals.h>
-#include <AssertMacros.h>
-#include "SecAccessControl.h"
-#include "SecAccessControlPriv.h"
-#include "SecItem.h"
-#include "SecItemPriv.h"
-#include <utilities/SecCFWrappers.h>
-#include <utilities/SecCFError.h>
-#include <utilities/der_plist.h>
-#include <libaks_acl_cf_keys.h>
-#include <ACMDefs.h>
-#include <ACMAclDefs.h>
-
-static CFTypeRef kSecAccessControlKeyProtection = CFSTR("prot");
-static CFTypeRef kSecAccessControlKeyBound = CFSTR("bound");
-
-struct __SecAccessControl {
-    CFRuntimeBase _base;
-    CFMutableDictionaryRef dict;
-};
-
-static SecAccessConstraintRef SecAccessConstraintCreateValueOfKofN(CFAllocatorRef allocator, size_t numRequired, CFArrayRef constraints, CFErrorRef *error);
-
-static CFStringRef SecAccessControlCopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
-    SecAccessControlRef access_control = (SecAccessControlRef)cf;
-    return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<SecAccessControlRef: %p>"), access_control);
-}
-
-static Boolean SecAccessControlCompare(CFTypeRef lhs, CFTypeRef rhs) {
-    SecAccessControlRef laccess_control = (SecAccessControlRef)lhs;
-    SecAccessControlRef raccess_control = (SecAccessControlRef)rhs;
-    return (laccess_control == raccess_control) || CFEqual(laccess_control->dict, raccess_control->dict);
-}
-
-static void SecAccessControlDestroy(CFTypeRef cf) {
-    SecAccessControlRef access_control = (SecAccessControlRef)cf;
-    CFReleaseSafe(access_control->dict);
-}
-
-CFGiblisWithCompareFor(SecAccessControl);
-
-static CFMutableDictionaryRef SecAccessControlGetMutableConstraints(SecAccessControlRef access_control) {
-    CFMutableDictionaryRef constraints = (CFMutableDictionaryRef)CFDictionaryGetValue(access_control->dict, kAKSKeyAcl);
-
-    if (!constraints) {
-        CFMutableDictionaryRef newConstraints = CFDictionaryCreateMutableForCFTypes(CFGetAllocator(access_control));
-        CFDictionarySetValue(access_control->dict, kAKSKeyAcl, newConstraints);
-        CFRelease(newConstraints);
-
-        constraints = (CFMutableDictionaryRef)CFDictionaryGetValue(access_control->dict, kAKSKeyAcl);
-    }
-
-    return constraints;
-}
-
-SecAccessControlRef SecAccessControlCreate(CFAllocatorRef allocator, CFErrorRef *error) {
-    SecAccessControlRef access_control = CFTypeAllocate(SecAccessControl, struct __SecAccessControl, allocator);
-       if (!access_control) {
-        SecError(errSecAllocate, error, CFSTR("allocate memory for SecAccessControl"));
-        return NULL;
-    }
-
-    access_control->dict = CFDictionaryCreateMutableForCFTypes(allocator);
-    return access_control;
-}
-
-static CFDataRef _getEmptyData() {
-    static CFMutableDataRef emptyData = NULL;
-    static dispatch_once_t onceToken;
-
-    dispatch_once(&onceToken, ^{
-        emptyData = CFDataCreateMutable(kCFAllocatorDefault, 0);
-    });
-
-    return emptyData;
-}
-
-SecAccessControlRef SecAccessControlCreateWithFlags(CFAllocatorRef allocator, CFTypeRef protection,
-                                                    SecAccessControlCreateFlags flags, CFErrorRef *error) {
-    SecAccessControlRef access_control = NULL;
-    CFTypeRef constraint = NULL;
-    CFMutableArrayRef constraints = NULL;
-
-    require_quiet(access_control = SecAccessControlCreate(allocator, error), errOut);
-
-    if (!SecAccessControlSetProtection(access_control, protection, error))
-        goto errOut;
-
-    if (flags) {
-        bool or = (flags & kSecAccessControlOr) ? true : false;
-        bool and = (flags & kSecAccessControlAnd) ? true : false;
-
-        if (or && and) {
-            SecError(errSecParam, error, CFSTR("only one logical operation can be set"));
-            goto errOut;
-        }
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunguarded-availability-new"
-
-        SecAccessControlCreateFlags maskedFlags = flags & (kSecAccessControlBiometryAny | kSecAccessControlBiometryCurrentSet);
-        if (maskedFlags && maskedFlags != kSecAccessControlBiometryAny && maskedFlags != kSecAccessControlBiometryCurrentSet) {
-            SecError(errSecParam, error, CFSTR("only one bio constraint can be set"));
-            goto errOut;
-        }
-
-        if (flags & kSecAccessControlUserPresence && flags & ~(kSecAccessControlUserPresence | kSecAccessControlApplicationPassword | kSecAccessControlPrivateKeyUsage)) {
-            SecError(errSecParam, error, CFSTR("kSecAccessControlUserPresence can be combined only with kSecAccessControlApplicationPassword and kSecAccessControlPrivateKeyUsage"));
-            goto errOut;
-        }
-
-        constraints = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
-
-        if (flags & kSecAccessControlUserPresence) {
-            require_quiet(constraint = SecAccessConstraintCreatePolicy(allocator, CFSTR(kACMPolicyDeviceOwnerAuthentication), error), errOut);
-            CFArrayAppendValue(constraints, constraint);
-            CFReleaseNull(constraint);
-        }
-
-        if (flags & kSecAccessControlDevicePasscode) {
-            require_quiet(constraint = SecAccessConstraintCreatePasscode(allocator), errOut);
-            CFArrayAppendValue(constraints, constraint);
-            CFReleaseNull(constraint);
-        }
-
-        if (flags & kSecAccessControlBiometryAny) {
-            require_quiet(constraint = SecAccessConstraintCreateBiometryAny(allocator, _getEmptyData()), errOut);
-            CFArrayAppendValue(constraints, constraint);
-            CFReleaseNull(constraint);
-        }
-
-        if (flags & kSecAccessControlBiometryCurrentSet) {
-            require_quiet(constraint = SecAccessConstraintCreateBiometryCurrentSet(allocator, _getEmptyData(), _getEmptyData()), errOut);
-            CFArrayAppendValue(constraints, constraint);
-            CFReleaseNull(constraint);
-        }
-
-#pragma clang diagnostic pop
-
-        if (flags & kSecAccessControlApplicationPassword) {
-            SecAccessControlSetRequirePassword(access_control, true);
-        }
-
-        CFIndex constraints_count = CFArrayGetCount(constraints);
-        if (constraints_count > 1) {
-            require_quiet(constraint = SecAccessConstraintCreateValueOfKofN(allocator, or?1:constraints_count, constraints, error), errOut);
-            if (flags & kSecAccessControlPrivateKeyUsage) {
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpSign, constraint, error), errOut);
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpComputeKey, constraint, error), errOut);
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpAttest, kCFBooleanTrue, error), errOut);
-            }
-            else {
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDecrypt, constraint, error), errOut);
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpEncrypt, kCFBooleanTrue, error), errOut);
-            }
-            require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDelete, kCFBooleanTrue, error), errOut);
-            CFReleaseNull(constraint);
-        } else if (constraints_count == 1) {
-            if (flags & kSecAccessControlPrivateKeyUsage) {
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpSign, CFArrayGetValueAtIndex(constraints, 0), error), errOut);
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpComputeKey, CFArrayGetValueAtIndex(constraints, 0), error), errOut);
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpAttest, kCFBooleanTrue, error), errOut);
-            }
-            else {
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDecrypt, CFArrayGetValueAtIndex(constraints, 0), error), errOut);
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpEncrypt, kCFBooleanTrue, error), errOut);
-            }
-            require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDelete, kCFBooleanTrue, error), errOut);
-        } else {
-            if (flags & kSecAccessControlPrivateKeyUsage) {
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpSign, kCFBooleanTrue, error), errOut);
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpComputeKey, kCFBooleanTrue, error), errOut);
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpAttest, kCFBooleanTrue, error), errOut);
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDelete, kCFBooleanTrue, error), errOut);
-            }
-            else {
-                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDefaultAcl, kCFBooleanTrue, error), errOut);
-            }
-        }
-
-        CFReleaseNull(constraints);
-    }
-    else {
-        require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDefaultAcl, kCFBooleanTrue, error), errOut);
-    }
-
-    return access_control;
-
-errOut:
-    CFReleaseSafe(access_control);
-    CFReleaseSafe(constraints);
-    CFReleaseSafe(constraint);
-    return NULL;
-}
-
-CFTypeRef SecAccessControlGetProtection(SecAccessControlRef access_control) {
-    return CFDictionaryGetValue(access_control->dict, kSecAccessControlKeyProtection);
-}
-
-static bool checkItemInArray(CFTypeRef item, const CFTypeRef *values, CFIndex count, CFStringRef errMessage, CFErrorRef *error) {
-    for (CFIndex i = 0; i < count; i++) {
-        if (CFEqualSafe(item, values[i])) {
-            return true;
-        }
-    }
-    return SecError(errSecParam, error, CFSTR("%@: %@"), errMessage, item);
-}
-
-#define CheckItemInArray(item, values, msg) \
-{ \
-    const CFTypeRef vals[] = values; \
-    if (!checkItemInArray(item, vals, sizeof(vals)/sizeof(*vals), msg, error)) { \
-        return false; \
-    } \
-}
-
-#define ItemArray(...) { __VA_ARGS__ }
-
-
-bool SecAccessControlSetProtection(SecAccessControlRef access_control, CFTypeRef protection, CFErrorRef *error) {
-    if (!protection || CFGetTypeID(protection) != CFDictionaryGetTypeID()) {
-        // Verify protection type.
-        CheckItemInArray(protection, ItemArray(kSecAttrAccessibleAlwaysPrivate, kSecAttrAccessibleAfterFirstUnlock,
-                                               kSecAttrAccessibleWhenUnlocked, kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate,
-                                               kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
-                                               kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
-                                               kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
-                                               kSecAttrAccessibleUntilReboot),
-                         CFSTR("SecAccessControl: invalid protection"));
-    }
-
-    // Protection valid, use it.
-    CFDictionarySetValue(access_control->dict, kSecAccessControlKeyProtection, protection);
-    return true;
-}
-
-SecAccessConstraintRef SecAccessConstraintCreatePolicy(CFAllocatorRef allocator, CFTypeRef policy, CFErrorRef *error) {
-    return CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintPolicy), policy, NULL);
-}
-
-SecAccessConstraintRef SecAccessConstraintCreatePasscode(CFAllocatorRef allocator) {
-    return CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintUserPasscode), kCFBooleanTrue, NULL);
-}
-
-SecAccessConstraintRef SecAccessConstraintCreateBiometryAny(CFAllocatorRef allocator, CFDataRef catacombUUID) {
-    CFMutableDictionaryRef bioDict = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclParamBioCatacombUUID), catacombUUID, NULL);
-    SecAccessConstraintRef constraint = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintBio), bioDict, NULL);
-    CFReleaseSafe(bioDict);
-    return constraint;
-}
-
-SecAccessConstraintRef SecAccessConstraintCreateTouchIDAny(CFAllocatorRef allocator, CFDataRef catacombUUID) {
-    return SecAccessConstraintCreateBiometryAny(allocator, catacombUUID);
-}
-
-SecAccessConstraintRef SecAccessConstraintCreateBiometryCurrentSet(CFAllocatorRef allocator, CFDataRef catacombUUID, CFDataRef bioDbHash) {
-    CFMutableDictionaryRef bioDict = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclParamBioCatacombUUID), catacombUUID, NULL);
-    CFDictionarySetValue(bioDict, CFSTR(kACMKeyAclParamBioDatabaseHash), bioDbHash);
-    SecAccessConstraintRef constraint = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintBio), bioDict, NULL);
-    CFReleaseSafe(bioDict);
-    return constraint;
-}
-
-SecAccessConstraintRef SecAccessConstraintCreateTouchIDCurrentSet(CFAllocatorRef allocator, CFDataRef catacombUUID, CFDataRef bioDbHash) {
-    return SecAccessConstraintCreateBiometryCurrentSet(allocator, catacombUUID, bioDbHash);
-}
-
-static SecAccessConstraintRef SecAccessConstraintCreateValueOfKofN(CFAllocatorRef allocator, size_t numRequired, CFArrayRef constraints, CFErrorRef *error) {
-    CFNumberRef k = CFNumberCreateWithCFIndex(allocator, numRequired);
-    CFMutableDictionaryRef kofn = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclParamKofN), k, NULL);
-    CFRelease(k);
-
-    /* Populate kofn dictionary with constraint keys from the array. note that for now we just ignore any additional
-       constraint parameters, but we might err-out if some parameter is found, since we cannot propagate parameteres
-       into k-of-n dictionary. */
-    const CFTypeRef keysToCopy[] = { CFSTR(kACMKeyAclConstraintBio), CFSTR(kACMKeyAclConstraintPolicy),
-        CFSTR(kACMKeyAclConstraintUserPasscode) };
-    SecAccessConstraintRef constraint;
-    CFArrayForEachC(constraints, constraint) {
-        require_quiet(isDictionary(constraint), errOut);
-        bool found = false;
-        for (CFIndex i = 0; i < (CFIndex)(sizeof(keysToCopy) / sizeof(keysToCopy[0])); i++) {
-            CFTypeRef value = CFDictionaryGetValue(constraint, keysToCopy[i]);
-            if (value) {
-                CFDictionarySetValue(kofn, keysToCopy[i], value);
-                found = true;
-                break;
-            }
-        }
-        require_quiet(found, errOut);
-    }
-
-    return kofn;
-
-errOut:
-    SecError(errSecParam, error, CFSTR("SecAccessControl: invalid constraint for k-of-n"));
-    CFReleaseSafe(kofn);
-    return NULL;
-}
-
-SecAccessConstraintRef SecAccessConstraintCreateKofN(CFAllocatorRef allocator, size_t numRequired, CFArrayRef constraints, CFErrorRef *error) {
-    SecAccessConstraintRef valueOfKofN =  SecAccessConstraintCreateValueOfKofN(allocator, numRequired, constraints, error);
-    require_quiet(valueOfKofN, errOut);
-
-    SecAccessConstraintRef constraint = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintKofN), valueOfKofN, NULL);
-    CFReleaseSafe(valueOfKofN);
-    return constraint;
-
-errOut:
-    return NULL;
-}
-
-bool SecAccessControlAddConstraintForOperation(SecAccessControlRef access_control, CFTypeRef operation, CFTypeRef constraint, CFErrorRef *error) {
-    CheckItemInArray(operation, ItemArray(kAKSKeyOpEncrypt, kAKSKeyOpDecrypt,
-                                          kAKSKeyOpSign, kAKSKeyOpAttest, kAKSKeyOpComputeKey,
-                                          kAKSKeyOpSync, kAKSKeyOpDefaultAcl, kAKSKeyOpDelete),
-                     CFSTR("SecAccessControl: invalid operation"));
-    if (!isDictionary(constraint) && !CFEqual(constraint, kCFBooleanTrue) && !CFEqual(constraint, kCFBooleanFalse) ) {
-        return SecError(errSecParam, error, CFSTR("invalid constraint"));
-    }
-
-    CFMutableDictionaryRef constraints = SecAccessControlGetMutableConstraints(access_control);
-    CFDictionarySetValue(constraints, operation, constraint);
-    return true;
-}
-
-SecAccessConstraintRef SecAccessControlGetConstraint(SecAccessControlRef access_control, CFTypeRef operation) {
-    CFMutableDictionaryRef ops = (CFMutableDictionaryRef)CFDictionaryGetValue(access_control->dict, kAKSKeyAcl);
-    if (!ops || CFDictionaryGetCount(ops) == 0)
-        // No ACL is present, this means that everything is allowed.
-        return kCFBooleanTrue;
-
-    SecAccessConstraintRef constraint = CFDictionaryGetValue(ops, operation);
-    if (!constraint) {
-        constraint = CFDictionaryGetValue(ops, kAKSKeyOpDefaultAcl);
-    }
-    return constraint;
-}
-
-CFDataRef SecAccessControlCopyConstraintData(SecAccessControlRef access_control, CFTypeRef operation) {
-    SecAccessConstraintRef constraint = SecAccessControlGetConstraint(access_control, operation);
-
-    size_t len = der_sizeof_plist(constraint, NULL);
-    CFMutableDataRef encoded = CFDataCreateMutable(0, len);
-    CFDataSetLength(encoded, len);
-    uint8_t *der_end = CFDataGetMutableBytePtr(encoded);
-    const uint8_t *der = der_end;
-    der_end += len;
-    der_end = der_encode_plist(constraint, NULL, der, der_end);
-    if (!der_end) {
-        CFReleaseNull(encoded);
-    }
-    return encoded;
-}
-
-CFDictionaryRef SecAccessControlGetConstraints(SecAccessControlRef access_control) {
-    return CFDictionaryGetValue(access_control->dict, kAKSKeyAcl);
-}
-
-void SecAccessControlSetConstraints(SecAccessControlRef access_control, CFDictionaryRef constraints) {
-    CFMutableDictionaryRef mutableConstraints = CFDictionaryCreateMutableCopy(CFGetAllocator(access_control), 0, constraints);
-    CFDictionarySetValue(access_control->dict, kAKSKeyAcl, mutableConstraints);
-    CFReleaseSafe(mutableConstraints);
-}
-
-void SecAccessControlSetRequirePassword(SecAccessControlRef access_control, bool require) {
-    CFMutableDictionaryRef constraints = SecAccessControlGetMutableConstraints(access_control);
-    CFDictionarySetValue(constraints, kAKSKeyAclParamRequirePasscode, require?kCFBooleanTrue:kCFBooleanFalse);
-}
-
-bool SecAccessControlGetRequirePassword(SecAccessControlRef access_control) {
-    CFMutableDictionaryRef acl = (CFMutableDictionaryRef)CFDictionaryGetValue(access_control->dict, kAKSKeyAcl);
-    if (acl) {
-        return CFEqualSafe(CFDictionaryGetValue(acl, kAKSKeyAclParamRequirePasscode), kCFBooleanTrue);
-    }
-
-    return false;
-}
-
-void SecAccessControlSetBound(SecAccessControlRef access_control, bool bound) {
-    CFDictionarySetValue(access_control->dict, kSecAccessControlKeyBound, bound ? kCFBooleanTrue : kCFBooleanFalse);
-}
-
-bool SecAccessControlIsBound(SecAccessControlRef access_control) {
-    CFTypeRef bound = CFDictionaryGetValue(access_control->dict, kSecAccessControlKeyBound);
-    return bound != NULL && CFEqualSafe(bound, kCFBooleanTrue);
-}
-
-CFDataRef SecAccessControlCopyData(SecAccessControlRef access_control) {
-    size_t len = der_sizeof_plist(access_control->dict, NULL);
-    CFMutableDataRef encoded = CFDataCreateMutable(0, len);
-    CFDataSetLength(encoded, len);
-    uint8_t *der_end = CFDataGetMutableBytePtr(encoded);
-    const uint8_t *der = der_end;
-    der_end += len;
-    der_end = der_encode_plist(access_control->dict, NULL, der, der_end);
-    if (!der_end) {
-        CFReleaseNull(encoded);
-    }
-    return encoded;
-}
-
-SecAccessControlRef SecAccessControlCreateFromData(CFAllocatorRef allocator, CFDataRef data, CFErrorRef *error) {
-    SecAccessControlRef access_control;
-    require_quiet(access_control = SecAccessControlCreate(allocator, error), errOut);
-
-    CFPropertyListRef plist;
-    const uint8_t *der = CFDataGetBytePtr(data);
-    const uint8_t *der_end = der + CFDataGetLength(data);
-    require_quiet(der = der_decode_plist(0, kCFPropertyListMutableContainers, &plist, error, der, der_end), errOut);
-    if (der != der_end) {
-        SecError(errSecDecode, error, CFSTR("trailing garbage at end of SecAccessControl data"));
-        goto errOut;
-    }
-
-    CFReleaseSafe(access_control->dict);
-    access_control->dict = (CFMutableDictionaryRef)plist;
-    return access_control;
-
-errOut:
-    CFReleaseSafe(access_control);
-    return NULL;
-}
diff --git a/OSX/sec/Security/SecAccessControl.m b/OSX/sec/Security/SecAccessControl.m
new file mode 100644 (file)
index 0000000..1f172f7
--- /dev/null
@@ -0,0 +1,470 @@
+/*
+ * Copyright (c) 2014 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@
+ */
+
+/*
+ * SecAccessControl.m - CoreFoundation based access control object
+ */
+
+#include <TargetConditionals.h>
+#include <AssertMacros.h>
+#include "SecAccessControl.h"
+#include "SecAccessControlPriv.h"
+#include "SecItem.h"
+#include "SecItemPriv.h"
+#include <utilities/SecCFWrappers.h>
+#include <utilities/SecCFError.h>
+#include <utilities/der_plist.h>
+#include <libaks_acl_cf_keys.h>
+#include <ACMDefs.h>
+#include <ACMAclDefs.h>
+
+static CFTypeRef kSecAccessControlKeyProtection = CFSTR("prot");
+static CFTypeRef kSecAccessControlKeyBound = CFSTR("bound");
+
+struct __SecAccessControl {
+    CFRuntimeBase _base;
+    CFMutableDictionaryRef dict;
+};
+
+static SecAccessConstraintRef SecAccessConstraintCreateValueOfKofN(CFAllocatorRef allocator, size_t numRequired, CFArrayRef constraints, CFErrorRef *error);
+
+static void dumpValue(id value, NSMutableString *target, NSString *separator) {
+    if (value == nil) {
+        // Do nothing.
+    } else if (CFGetTypeID((__bridge CFTypeRef)value) == CFBooleanGetTypeID()) {
+        [target appendString:[value boolValue] ? @"true" : @"false"];
+    } else if ([value isKindOfClass:NSNumber.class]) {
+        [target appendString:[value string]];
+    } else if ([value isKindOfClass:NSString.class]) {
+        [target appendString:value];
+    } else if ([value isKindOfClass:NSDictionary.class]) {
+        [value enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
+            [target appendString:separator];
+            dumpValue(key, target, @"");
+            [target appendString:@"("];
+            dumpValue(obj, target, @"");
+            [target appendString:@")"];
+        }];
+    }
+}
+
+static CFStringRef SecAccessControlCopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
+    SecAccessControlRef access_control = (SecAccessControlRef)cf;
+    NSDictionary *contents = (__bridge NSDictionary *)access_control->dict;
+    NSMutableString *dump = [NSMutableString string];
+    dumpValue(contents[(__bridge id)kSecAccessControlKeyProtection], dump, @"");
+    dumpValue(contents[(__bridge id)kAKSKeyAcl], dump, @";");
+    return CFBridgingRetain([NSString stringWithFormat:@"<SecAccessControlRef: %@>", dump]);
+}
+
+static Boolean SecAccessControlCompare(CFTypeRef lhs, CFTypeRef rhs) {
+    SecAccessControlRef laccess_control = (SecAccessControlRef)lhs;
+    SecAccessControlRef raccess_control = (SecAccessControlRef)rhs;
+    return (laccess_control == raccess_control) || CFEqual(laccess_control->dict, raccess_control->dict);
+}
+
+static void SecAccessControlDestroy(CFTypeRef cf) {
+    SecAccessControlRef access_control = (SecAccessControlRef)cf;
+    CFReleaseSafe(access_control->dict);
+}
+
+CFGiblisWithCompareFor(SecAccessControl);
+
+static CFMutableDictionaryRef SecAccessControlGetMutableConstraints(SecAccessControlRef access_control) {
+    CFMutableDictionaryRef constraints = (CFMutableDictionaryRef)CFDictionaryGetValue(access_control->dict, kAKSKeyAcl);
+
+    if (!constraints) {
+        CFMutableDictionaryRef newConstraints = CFDictionaryCreateMutableForCFTypes(CFGetAllocator(access_control));
+        CFDictionarySetValue(access_control->dict, kAKSKeyAcl, newConstraints);
+        CFRelease(newConstraints);
+
+        constraints = (CFMutableDictionaryRef)CFDictionaryGetValue(access_control->dict, kAKSKeyAcl);
+    }
+
+    return constraints;
+}
+
+SecAccessControlRef SecAccessControlCreate(CFAllocatorRef allocator, CFErrorRef *error) {
+    SecAccessControlRef access_control = CFTypeAllocate(SecAccessControl, struct __SecAccessControl, allocator);
+       if (!access_control) {
+        SecError(errSecAllocate, error, CFSTR("allocate memory for SecAccessControl"));
+        return NULL;
+    }
+
+    access_control->dict = CFDictionaryCreateMutableForCFTypes(allocator);
+    return access_control;
+}
+
+static CFDataRef _getEmptyData() {
+    static CFMutableDataRef emptyData = NULL;
+    static dispatch_once_t onceToken;
+
+    dispatch_once(&onceToken, ^{
+        emptyData = CFDataCreateMutable(kCFAllocatorDefault, 0);
+    });
+
+    return emptyData;
+}
+
+SecAccessControlRef SecAccessControlCreateWithFlags(CFAllocatorRef allocator, CFTypeRef protection,
+                                                    SecAccessControlCreateFlags flags, CFErrorRef *error) {
+    SecAccessControlRef access_control = NULL;
+    CFTypeRef constraint = NULL;
+    CFMutableArrayRef constraints = NULL;
+
+    require_quiet(access_control = SecAccessControlCreate(allocator, error), errOut);
+
+    if (!SecAccessControlSetProtection(access_control, protection, error))
+        goto errOut;
+
+    if (flags) {
+        bool or = (flags & kSecAccessControlOr) ? true : false;
+        bool and = (flags & kSecAccessControlAnd) ? true : false;
+
+        if (or && and) {
+            SecError(errSecParam, error, CFSTR("only one logical operation can be set"));
+            goto errOut;
+        }
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunguarded-availability-new"
+
+        SecAccessControlCreateFlags maskedFlags = flags & (kSecAccessControlBiometryAny | kSecAccessControlBiometryCurrentSet);
+        if (maskedFlags && maskedFlags != kSecAccessControlBiometryAny && maskedFlags != kSecAccessControlBiometryCurrentSet) {
+            SecError(errSecParam, error, CFSTR("only one bio constraint can be set"));
+            goto errOut;
+        }
+
+        if (flags & kSecAccessControlUserPresence && flags & ~(kSecAccessControlUserPresence | kSecAccessControlApplicationPassword | kSecAccessControlPrivateKeyUsage)) {
+            SecError(errSecParam, error, CFSTR("kSecAccessControlUserPresence can be combined only with kSecAccessControlApplicationPassword and kSecAccessControlPrivateKeyUsage"));
+            goto errOut;
+        }
+
+        constraints = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
+
+        if (flags & kSecAccessControlUserPresence) {
+            require_quiet(constraint = SecAccessConstraintCreatePolicy(allocator, CFSTR(kACMPolicyDeviceOwnerAuthentication), error), errOut);
+            CFArrayAppendValue(constraints, constraint);
+            CFReleaseNull(constraint);
+        }
+
+        if (flags & kSecAccessControlDevicePasscode) {
+            require_quiet(constraint = SecAccessConstraintCreatePasscode(allocator), errOut);
+            CFArrayAppendValue(constraints, constraint);
+            CFReleaseNull(constraint);
+        }
+
+        if (flags & kSecAccessControlBiometryAny) {
+            require_quiet(constraint = SecAccessConstraintCreateBiometryAny(allocator, _getEmptyData()), errOut);
+            CFArrayAppendValue(constraints, constraint);
+            CFReleaseNull(constraint);
+        }
+
+        if (flags & kSecAccessControlBiometryCurrentSet) {
+            require_quiet(constraint = SecAccessConstraintCreateBiometryCurrentSet(allocator, _getEmptyData(), _getEmptyData()), errOut);
+            CFArrayAppendValue(constraints, constraint);
+            CFReleaseNull(constraint);
+        }
+
+#pragma clang diagnostic pop
+
+        if (flags & kSecAccessControlApplicationPassword) {
+            SecAccessControlSetRequirePassword(access_control, true);
+        }
+
+        CFIndex constraints_count = CFArrayGetCount(constraints);
+        if (constraints_count > 1) {
+            require_quiet(constraint = SecAccessConstraintCreateValueOfKofN(allocator, or?1:constraints_count, constraints, error), errOut);
+            if (flags & kSecAccessControlPrivateKeyUsage) {
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpSign, constraint, error), errOut);
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpComputeKey, constraint, error), errOut);
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpAttest, kCFBooleanTrue, error), errOut);
+            }
+            else {
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDecrypt, constraint, error), errOut);
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpEncrypt, kCFBooleanTrue, error), errOut);
+            }
+            require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDelete, kCFBooleanTrue, error), errOut);
+            CFReleaseNull(constraint);
+        } else if (constraints_count == 1) {
+            if (flags & kSecAccessControlPrivateKeyUsage) {
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpSign, CFArrayGetValueAtIndex(constraints, 0), error), errOut);
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpComputeKey, CFArrayGetValueAtIndex(constraints, 0), error), errOut);
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpAttest, kCFBooleanTrue, error), errOut);
+            }
+            else {
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDecrypt, CFArrayGetValueAtIndex(constraints, 0), error), errOut);
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpEncrypt, kCFBooleanTrue, error), errOut);
+            }
+            require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDelete, kCFBooleanTrue, error), errOut);
+        } else {
+            if (flags & kSecAccessControlPrivateKeyUsage) {
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpSign, kCFBooleanTrue, error), errOut);
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpComputeKey, kCFBooleanTrue, error), errOut);
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpAttest, kCFBooleanTrue, error), errOut);
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDelete, kCFBooleanTrue, error), errOut);
+            }
+            else {
+                require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDefaultAcl, kCFBooleanTrue, error), errOut);
+            }
+        }
+
+        CFReleaseNull(constraints);
+    }
+    else {
+        require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDefaultAcl, kCFBooleanTrue, error), errOut);
+    }
+
+    return access_control;
+
+errOut:
+    CFReleaseSafe(access_control);
+    CFReleaseSafe(constraints);
+    CFReleaseSafe(constraint);
+    return NULL;
+}
+
+CFTypeRef SecAccessControlGetProtection(SecAccessControlRef access_control) {
+    return CFDictionaryGetValue(access_control->dict, kSecAccessControlKeyProtection);
+}
+
+static bool checkItemInArray(CFTypeRef item, const CFTypeRef *values, CFIndex count, CFStringRef errMessage, CFErrorRef *error) {
+    for (CFIndex i = 0; i < count; i++) {
+        if (CFEqualSafe(item, values[i])) {
+            return true;
+        }
+    }
+    return SecError(errSecParam, error, CFSTR("%@: %@"), errMessage, item);
+}
+
+#define CheckItemInArray(item, values, msg) \
+{ \
+    const CFTypeRef vals[] = values; \
+    if (!checkItemInArray(item, vals, sizeof(vals)/sizeof(*vals), msg, error)) { \
+        return false; \
+    } \
+}
+
+#define ItemArray(...) { __VA_ARGS__ }
+
+
+bool SecAccessControlSetProtection(SecAccessControlRef access_control, CFTypeRef protection, CFErrorRef *error) {
+    if (!protection || CFGetTypeID(protection) != CFDictionaryGetTypeID()) {
+        // Verify protection type.
+        CheckItemInArray(protection, ItemArray(kSecAttrAccessibleAlwaysPrivate, kSecAttrAccessibleAfterFirstUnlock,
+                                               kSecAttrAccessibleWhenUnlocked, kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate,
+                                               kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
+                                               kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
+                                               kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
+                                               kSecAttrAccessibleUntilReboot),
+                         CFSTR("SecAccessControl: invalid protection"));
+    }
+
+    // Protection valid, use it.
+    CFDictionarySetValue(access_control->dict, kSecAccessControlKeyProtection, protection);
+    return true;
+}
+
+SecAccessConstraintRef SecAccessConstraintCreatePolicy(CFAllocatorRef allocator, CFTypeRef policy, CFErrorRef *error) {
+    return CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintPolicy), policy, NULL);
+}
+
+SecAccessConstraintRef SecAccessConstraintCreatePasscode(CFAllocatorRef allocator) {
+    return CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintUserPasscode), kCFBooleanTrue, NULL);
+}
+
+SecAccessConstraintRef SecAccessConstraintCreateBiometryAny(CFAllocatorRef allocator, CFDataRef catacombUUID) {
+    CFMutableDictionaryRef bioDict = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclParamBioCatacombUUID), catacombUUID, NULL);
+    SecAccessConstraintRef constraint = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintBio), bioDict, NULL);
+    CFReleaseSafe(bioDict);
+    return constraint;
+}
+
+SecAccessConstraintRef SecAccessConstraintCreateTouchIDAny(CFAllocatorRef allocator, CFDataRef catacombUUID) {
+    return SecAccessConstraintCreateBiometryAny(allocator, catacombUUID);
+}
+
+SecAccessConstraintRef SecAccessConstraintCreateBiometryCurrentSet(CFAllocatorRef allocator, CFDataRef catacombUUID, CFDataRef bioDbHash) {
+    CFMutableDictionaryRef bioDict = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclParamBioCatacombUUID), catacombUUID, NULL);
+    CFDictionarySetValue(bioDict, CFSTR(kACMKeyAclParamBioDatabaseHash), bioDbHash);
+    SecAccessConstraintRef constraint = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintBio), bioDict, NULL);
+    CFReleaseSafe(bioDict);
+    return constraint;
+}
+
+SecAccessConstraintRef SecAccessConstraintCreateTouchIDCurrentSet(CFAllocatorRef allocator, CFDataRef catacombUUID, CFDataRef bioDbHash) {
+    return SecAccessConstraintCreateBiometryCurrentSet(allocator, catacombUUID, bioDbHash);
+}
+
+static SecAccessConstraintRef SecAccessConstraintCreateValueOfKofN(CFAllocatorRef allocator, size_t numRequired, CFArrayRef constraints, CFErrorRef *error) {
+    CFNumberRef k = CFNumberCreateWithCFIndex(allocator, numRequired);
+    CFMutableDictionaryRef kofn = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclParamKofN), k, NULL);
+    CFRelease(k);
+
+    /* Populate kofn dictionary with constraint keys from the array. note that for now we just ignore any additional
+       constraint parameters, but we might err-out if some parameter is found, since we cannot propagate parameteres
+       into k-of-n dictionary. */
+    const CFTypeRef keysToCopy[] = { CFSTR(kACMKeyAclConstraintBio), CFSTR(kACMKeyAclConstraintPolicy),
+        CFSTR(kACMKeyAclConstraintUserPasscode) };
+    SecAccessConstraintRef constraint;
+    CFArrayForEachC(constraints, constraint) {
+        require_quiet(isDictionary(constraint), errOut);
+        bool found = false;
+        for (CFIndex i = 0; i < (CFIndex)(sizeof(keysToCopy) / sizeof(keysToCopy[0])); i++) {
+            CFTypeRef value = CFDictionaryGetValue(constraint, keysToCopy[i]);
+            if (value) {
+                CFDictionarySetValue(kofn, keysToCopy[i], value);
+                found = true;
+                break;
+            }
+        }
+        require_quiet(found, errOut);
+    }
+
+    return kofn;
+
+errOut:
+    SecError(errSecParam, error, CFSTR("SecAccessControl: invalid constraint for k-of-n"));
+    CFReleaseSafe(kofn);
+    return NULL;
+}
+
+SecAccessConstraintRef SecAccessConstraintCreateKofN(CFAllocatorRef allocator, size_t numRequired, CFArrayRef constraints, CFErrorRef *error) {
+    SecAccessConstraintRef valueOfKofN =  SecAccessConstraintCreateValueOfKofN(allocator, numRequired, constraints, error);
+    require_quiet(valueOfKofN, errOut);
+
+    SecAccessConstraintRef constraint = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintKofN), valueOfKofN, NULL);
+    CFReleaseSafe(valueOfKofN);
+    return constraint;
+
+errOut:
+    return NULL;
+}
+
+bool SecAccessControlAddConstraintForOperation(SecAccessControlRef access_control, CFTypeRef operation, CFTypeRef constraint, CFErrorRef *error) {
+    if (!isDictionary(constraint) && !CFEqual(constraint, kCFBooleanTrue) && !CFEqual(constraint, kCFBooleanFalse) ) {
+        return SecError(errSecParam, error, CFSTR("invalid constraint"));
+    }
+
+    CFMutableDictionaryRef constraints = SecAccessControlGetMutableConstraints(access_control);
+    CFDictionarySetValue(constraints, operation, constraint);
+    return true;
+}
+
+SecAccessConstraintRef SecAccessControlGetConstraint(SecAccessControlRef access_control, CFTypeRef operation) {
+    CFMutableDictionaryRef ops = (CFMutableDictionaryRef)CFDictionaryGetValue(access_control->dict, kAKSKeyAcl);
+    if (!ops || CFDictionaryGetCount(ops) == 0)
+        // No ACL is present, this means that everything is allowed.
+        return kCFBooleanTrue;
+
+    SecAccessConstraintRef constraint = CFDictionaryGetValue(ops, operation);
+    if (!constraint) {
+        constraint = CFDictionaryGetValue(ops, kAKSKeyOpDefaultAcl);
+    }
+    return constraint;
+}
+
+CFDataRef SecAccessControlCopyConstraintData(SecAccessControlRef access_control, CFTypeRef operation) {
+    SecAccessConstraintRef constraint = SecAccessControlGetConstraint(access_control, operation);
+
+    size_t len = der_sizeof_plist(constraint, NULL);
+    CFMutableDataRef encoded = CFDataCreateMutable(0, len);
+    CFDataSetLength(encoded, len);
+    uint8_t *der_end = CFDataGetMutableBytePtr(encoded);
+    const uint8_t *der = der_end;
+    der_end += len;
+    der_end = der_encode_plist(constraint, NULL, der, der_end);
+    if (!der_end) {
+        CFReleaseNull(encoded);
+    }
+    return encoded;
+}
+
+CFDictionaryRef SecAccessControlGetConstraints(SecAccessControlRef access_control) {
+    return CFDictionaryGetValue(access_control->dict, kAKSKeyAcl);
+}
+
+void SecAccessControlSetConstraints(SecAccessControlRef access_control, CFDictionaryRef constraints) {
+    CFMutableDictionaryRef mutableConstraints = CFDictionaryCreateMutableCopy(CFGetAllocator(access_control), 0, constraints);
+    CFDictionarySetValue(access_control->dict, kAKSKeyAcl, mutableConstraints);
+    CFReleaseSafe(mutableConstraints);
+}
+
+void SecAccessControlSetRequirePassword(SecAccessControlRef access_control, bool require) {
+    CFMutableDictionaryRef constraints = SecAccessControlGetMutableConstraints(access_control);
+    CFDictionarySetValue(constraints, kAKSKeyAclParamRequirePasscode, require?kCFBooleanTrue:kCFBooleanFalse);
+}
+
+bool SecAccessControlGetRequirePassword(SecAccessControlRef access_control) {
+    CFMutableDictionaryRef acl = (CFMutableDictionaryRef)CFDictionaryGetValue(access_control->dict, kAKSKeyAcl);
+    if (acl) {
+        return CFEqualSafe(CFDictionaryGetValue(acl, kAKSKeyAclParamRequirePasscode), kCFBooleanTrue);
+    }
+
+    return false;
+}
+
+void SecAccessControlSetBound(SecAccessControlRef access_control, bool bound) {
+    CFDictionarySetValue(access_control->dict, kSecAccessControlKeyBound, bound ? kCFBooleanTrue : kCFBooleanFalse);
+}
+
+bool SecAccessControlIsBound(SecAccessControlRef access_control) {
+    CFTypeRef bound = CFDictionaryGetValue(access_control->dict, kSecAccessControlKeyBound);
+    return bound != NULL && CFEqualSafe(bound, kCFBooleanTrue);
+}
+
+CFDataRef SecAccessControlCopyData(SecAccessControlRef access_control) {
+    size_t len = der_sizeof_plist(access_control->dict, NULL);
+    CFMutableDataRef encoded = CFDataCreateMutable(0, len);
+    CFDataSetLength(encoded, len);
+    uint8_t *der_end = CFDataGetMutableBytePtr(encoded);
+    const uint8_t *der = der_end;
+    der_end += len;
+    der_end = der_encode_plist(access_control->dict, NULL, der, der_end);
+    if (!der_end) {
+        CFReleaseNull(encoded);
+    }
+    return encoded;
+}
+
+SecAccessControlRef SecAccessControlCreateFromData(CFAllocatorRef allocator, CFDataRef data, CFErrorRef *error) {
+    SecAccessControlRef access_control;
+    require_quiet(access_control = SecAccessControlCreate(allocator, error), errOut);
+
+    CFPropertyListRef plist;
+    const uint8_t *der = CFDataGetBytePtr(data);
+    const uint8_t *der_end = der + CFDataGetLength(data);
+    require_quiet(der = der_decode_plist(0, kCFPropertyListMutableContainers, &plist, error, der, der_end), errOut);
+    if (der != der_end) {
+        SecError(errSecDecode, error, CFSTR("trailing garbage at end of SecAccessControl data"));
+        goto errOut;
+    }
+
+    CFReleaseSafe(access_control->dict);
+    access_control->dict = (CFMutableDictionaryRef)plist;
+    return access_control;
+
+errOut:
+    CFReleaseSafe(access_control);
+    return NULL;
+}
index fc35e4ccc481b101a6a7468344570a03a4df3661..44e1dd81bfc6116366b37c9a4d4ff428b7516acd 100644 (file)
@@ -73,7 +73,8 @@ static CFIndex SecCTKGetAlgorithmID(SecKeyRef key) {
 
 static SecItemAuthResult SecCTKProcessError(CFStringRef operation, TKTokenRef token, CFDataRef object_id, CFArrayRef *ac_pairs, CFErrorRef *error) {
     if (CFEqualSafe(CFErrorGetDomain(*error), CFSTR(kTKErrorDomain)) &&
 
 static SecItemAuthResult SecCTKProcessError(CFStringRef operation, TKTokenRef token, CFDataRef object_id, CFArrayRef *ac_pairs, CFErrorRef *error) {
     if (CFEqualSafe(CFErrorGetDomain(*error), CFSTR(kTKErrorDomain)) &&
-        CFErrorGetCode(*error) == kTKErrorCodeAuthenticationFailed) {
+        CFErrorGetCode(*error) == kTKErrorCodeAuthenticationFailed &&
+        operation != NULL) {
         CFDataRef access_control = TKTokenCopyObjectAccessControl(token, object_id, error);
         if (access_control != NULL) {
             CFArrayRef ac_pair = CFArrayCreateForCFTypes(NULL, access_control, operation, NULL);
         CFDataRef access_control = TKTokenCopyObjectAccessControl(token, object_id, error);
         if (access_control != NULL) {
             CFArrayRef ac_pair = CFArrayCreateForCFTypes(NULL, access_control, operation, NULL);
@@ -88,12 +89,6 @@ static SecItemAuthResult SecCTKProcessError(CFStringRef operation, TKTokenRef to
     return kSecItemAuthResultError;
 }
 
     return kSecItemAuthResultError;
 }
 
-static const CFTypeRef *aclOperations[] = {
-    [kSecKeyOperationTypeSign] = &kAKSKeyOpSign,
-    [kSecKeyOperationTypeDecrypt] = &kAKSKeyOpDecrypt,
-    [kSecKeyOperationTypeKeyExchange] = &kAKSKeyOpComputeKey,
-};
-
 static TKTokenRef SecCTKKeyCreateToken(SecKeyRef key, CFDictionaryRef auth_params, CFDictionaryRef *last_params, CFErrorRef *error) {
     TKTokenRef token = NULL;
     SecCTKKeyData *kd = key->key;
 static TKTokenRef SecCTKKeyCreateToken(SecKeyRef key, CFDictionaryRef auth_params, CFDictionaryRef *last_params, CFErrorRef *error) {
     TKTokenRef token = NULL;
     SecCTKKeyData *kd = key->key;
@@ -161,8 +156,31 @@ static CFTypeRef SecCTKKeyCopyOperationResult(SecKeyRef key, SecKeyOperationType
         if (CFEqualSafe(result, kCFBooleanTrue)) {
             result = TKTokenCopyOperationResult(token, kd->object_id, operation, algorithms, mode, in1, in2, error);
         }
         if (CFEqualSafe(result, kCFBooleanTrue)) {
             result = TKTokenCopyOperationResult(token, kd->object_id, operation, algorithms, mode, in1, in2, error);
         }
-        return (result != NULL) ? kSecItemAuthResultOK : SecCTKProcessError(*aclOperations[operation], token,
-                                                                            kd->object_id, ac_pairs, error);
+
+        if (result != NULL) {
+            return kSecItemAuthResultOK;
+        }
+
+        CFStringRef AKSOperation = NULL;
+        switch (operation) {
+            case kSecKeyOperationTypeSign:
+                AKSOperation = kAKSKeyOpSign;
+                break;
+            case kSecKeyOperationTypeDecrypt: {
+                AKSOperation = kAKSKeyOpDecrypt;
+                if (in2 != NULL && CFGetTypeID(in2) == CFDictionaryGetTypeID() && CFDictionaryGetValue(in2, kSecKeyEncryptionParameterRecryptCertificate) != NULL) {
+                    // This is actually recrypt operation, which is special separate AKS operation.
+                    AKSOperation = kAKSKeyOpECIESTranscode;
+                }
+                break;
+            }
+            case kSecKeyOperationTypeKeyExchange:
+                AKSOperation = kAKSKeyOpComputeKey;
+                break;
+            default:
+                break;;
+        }
+        return SecCTKProcessError(AKSOperation, token, kd->object_id, ac_pairs, error);
     }, ^{
         CFAssignRetained(token, SecCTKKeyCreateToken(key, auth_params.dictionary, &last_params, NULL));
     });
     }, ^{
         CFAssignRetained(token, SecCTKKeyCreateToken(key, auth_params.dictionary, &last_params, NULL));
     });
@@ -570,11 +588,6 @@ out:
     return attestationData;
 }
 
     return attestationData;
 }
 
-#if TKTOKEN_CLIENT_INTERFACE_VERSION < 4
-#define kTKTokenControlAttribLifetimeControlKey "lifetimeControlKey"
-#define kTKTokenControlAttribLifetimeType "lifetimeType"
-#endif
-
 Boolean SecKeyControlLifetime(SecKeyRef key, SecKeyControlLifetimeType type, CFErrorRef *error) {
     NSError *localError;
     __block id token;
 Boolean SecKeyControlLifetime(SecKeyRef key, SecKeyControlLifetimeType type, CFErrorRef *error) {
     NSError *localError;
     __block id token;
@@ -605,3 +618,19 @@ Boolean SecKeyControlLifetime(SecKeyRef key, SecKeyControlLifetimeType type, CFE
         return outputAttributes ? kSecItemAuthResultOK : kSecItemAuthResultError;
     }, NULL);
 }
         return outputAttributes ? kSecItemAuthResultOK : kSecItemAuthResultError;
     }, NULL);
 }
+
+#if TKTOKEN_CLIENT_INTERFACE_VERSION < 5
+#define kTKTokenCreateAttributeTestMode "testmode"
+#endif
+
+void SecCTKKeySetTestMode(CFStringRef tokenID, CFTypeRef enable) {
+    CFErrorRef error = NULL;
+    CFDictionaryRef options = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, kSecAttrTokenID, tokenID, @kTKTokenCreateAttributeTestMode, enable, nil);
+    TKTokenRef token = TKTokenCreate(options, &error);
+    if (token == NULL) {
+        secerror("Failed to set token attributes %@: error %@", options, error);
+    }
+    CFReleaseNull(options);
+    CFReleaseNull(error);
+    CFReleaseNull(token);
+}
index 660a008047752b41278961d81dedbc85485719a9..be40b1789774d525d9c0eafa2d34eaa88ad18ec6 100644 (file)
@@ -34,6 +34,7 @@ extern const CFStringRef kSecUseToken;
 OSStatus SecCTKKeyGeneratePair(CFDictionaryRef parameters,
                                SecKeyRef *rsaPublicKey, SecKeyRef *rsaPrivateKey);
 SecKeyRef SecKeyCreateCTKKey(CFAllocatorRef allocator, CFDictionaryRef refAttributes, CFErrorRef *error);
 OSStatus SecCTKKeyGeneratePair(CFDictionaryRef parameters,
                                SecKeyRef *rsaPublicKey, SecKeyRef *rsaPrivateKey);
 SecKeyRef SecKeyCreateCTKKey(CFAllocatorRef allocator, CFDictionaryRef refAttributes, CFErrorRef *error);
+void SecCTKKeySetTestMode(CFStringRef tokenID, CFTypeRef enable);
 
 __END_DECLS
 
 
 __END_DECLS
 
index 8f243e706c653dc752e38f224517ab9dda698f4b..2c5d15377185cef5c9c0ea1fa15af530db9eeeff 100644 (file)
@@ -1078,10 +1078,12 @@ _SecKeyCopyPublicKeyHash
 _SecKeyCreate
 _SecKeyCreateAttestation
 _SecKeyCreateDecryptedData
 _SecKeyCreate
 _SecKeyCreateAttestation
 _SecKeyCreateDecryptedData
+_SecKeyCreateDecryptedDataWithParameters
 _SecKeyCreateDuplicate
 _SecKeyCreateECPrivateKey
 _SecKeyCreateECPublicKey
 _SecKeyCreateEncryptedData
 _SecKeyCreateDuplicate
 _SecKeyCreateECPrivateKey
 _SecKeyCreateECPublicKey
 _SecKeyCreateEncryptedData
+_SecKeyCreateEncryptedDataWithParameters
 _SecKeyCreateFromAttributeDictionary
 
 #if TARGET_OS_OSX
 _SecKeyCreateFromAttributeDictionary
 
 #if TARGET_OS_OSX
@@ -1248,9 +1250,14 @@ _kSecKeyAlgorithmRSASignatureRawCCUnit
 #if TARGET_OS_OSX
 _kSecKeyAttributeName
 #endif /* TARGET_OS_OSX */
 #if TARGET_OS_OSX
 _kSecKeyAttributeName
 #endif /* TARGET_OS_OSX */
+_kSecKeyEncryptionParameterRecryptParameters
+_kSecKeyEncryptionParameterRecryptCertificate
+_kSecKeyEncryptionParameterSymmetricAAD
+_kSecKeyEncryptionParameterSymmetricKeySizeInBits
 _kSecKeyKeyExchangeParameterRequestedSize
 _kSecKeyKeyExchangeParameterSharedInfo
 _kSecKeyParameterSETokenAttestationNonce
 _kSecKeyKeyExchangeParameterRequestedSize
 _kSecKeyKeyExchangeParameterSharedInfo
 _kSecKeyParameterSETokenAttestationNonce
+_kSecKeyApplePayEnabled
 _kSecPrivateKeyAttrs
 _kSecPublicKeyAttrs
 
 _kSecPrivateKeyAttrs
 _kSecPublicKeyAttrs
 
index 10943094c74e2de66479bf10b5de231e7c79f4dd..5f86dd330e1a1f9035f8cc6d8c1fb564bb95b934 100644 (file)
@@ -291,7 +291,7 @@ __BEGIN_DECLS
 #define SEC_TRUST_ERROR_IntermediateEKU             SecStringWithDefaultValue("Extended key usage does not match pinned value", "Trust", 0, "Extended key usage does not match pinned value", "Error for intermediate extended key usage pin")
 #define SEC_TRUST_ERROR_IntermediateMarkerOid       SecStringWithDefaultValue("Missing issuer-specific extension OID", "Trust", 0, "Missing issuer-specific extension OID", "Error for intermediate marker OID")
 #define SEC_TRUST_ERROR_IntermediateOrganization    SecStringWithDefaultValue("Organization does not match expected name", "Trust", 0, "Organization does not match expected name", "Error for issuer organization mismatch")
 #define SEC_TRUST_ERROR_IntermediateEKU             SecStringWithDefaultValue("Extended key usage does not match pinned value", "Trust", 0, "Extended key usage does not match pinned value", "Error for intermediate extended key usage pin")
 #define SEC_TRUST_ERROR_IntermediateMarkerOid       SecStringWithDefaultValue("Missing issuer-specific extension OID", "Trust", 0, "Missing issuer-specific extension OID", "Error for intermediate marker OID")
 #define SEC_TRUST_ERROR_IntermediateOrganization    SecStringWithDefaultValue("Organization does not match expected name", "Trust", 0, "Organization does not match expected name", "Error for issuer organization mismatch")
-#define SEC_TRUST_ERROR_IntermediateCountry         SecStringWithDefaultValue("Country does not match expected name", "Trust", 0, "Country does not match expected name", "Error for issuer country mismatch")
+#define SEC_TRUST_ERROR_IntermediateCountry         SecStringWithDefaultValue("Country or Region does not match expected name", "Trust", 0, "Country or Region does not match expected name", "Error for issuer country mismatch")
 #define SEC_TRUST_ERROR_AnchorSHA1                  SecStringWithDefaultValue("Anchor does not match pinned fingerprint", "Trust", 0, "Anchor does not match pinned fingerprint", "Error for anchor SHA-1 fingerprint pin")
 #define SEC_TRUST_ERROR_AnchorSHA256                SecStringWithDefaultValue("Anchor does not match pinned fingerprint", "Trust", 0, "Anchor does not match pinned fingerprint", "Error for anchor SHA-256 fingerprint pin")
 #define SEC_TRUST_ERROR_AnchorTrusted               SecStringWithDefaultValue("Root is not trusted", "Trust", 0, "Root is not trusted", "Error for untrusted root")
 #define SEC_TRUST_ERROR_AnchorSHA1                  SecStringWithDefaultValue("Anchor does not match pinned fingerprint", "Trust", 0, "Anchor does not match pinned fingerprint", "Error for anchor SHA-1 fingerprint pin")
 #define SEC_TRUST_ERROR_AnchorSHA256                SecStringWithDefaultValue("Anchor does not match pinned fingerprint", "Trust", 0, "Anchor does not match pinned fingerprint", "Error for anchor SHA-256 fingerprint pin")
 #define SEC_TRUST_ERROR_AnchorTrusted               SecStringWithDefaultValue("Root is not trusted", "Trust", 0, "Root is not trusted", "Error for untrusted root")
index 6d3b595c0ae8176f9cbb447c551ac5afa56fed9e..a5028e0d0788f2bba9e1846e6af16af835f06261 100644 (file)
@@ -828,6 +828,7 @@ TKTokenRef SecTokenCreate(CFStringRef token_id, SecCFDictionaryCOW *auth_params,
         if (ctx == nil) {
             ctx = LACreateNewContextWithACMContext(NULL, error);
             if (!ctx) {
         if (ctx == nil) {
             ctx = LACreateNewContextWithACMContext(NULL, error);
             if (!ctx) {
+                os_unfair_lock_unlock(&lock);
                 secerror("Failed to create authentication context %@", *error);
                 return token;
             }
                 secerror("Failed to create authentication context %@", *error);
                 return token;
             }
@@ -1542,9 +1543,7 @@ static bool SecTokenProcessError(CFStringRef operation, TKTokenRef token, CFType
         // Replace error with the one which is augmented with access control and operation which failed,
         // which will cause SecItemDoWithAuth to throw UI.
         // Create array containing tuple (array) with error and requested operation.
         // Replace error with the one which is augmented with access control and operation which failed,
         // which will cause SecItemDoWithAuth to throw UI.
         // Create array containing tuple (array) with error and requested operation.
-        CFDataRef access_control = (CFGetTypeID(object_or_attrs) == CFDataGetTypeID()) ?
-            TKTokenCopyObjectAccessControl(token, object_or_attrs, error) :
-            TKTokenCopyObjectCreationAccessControl(token, object_or_attrs, error);
+        CFDataRef access_control = TKTokenCopyObjectAccessControl(token, object_or_attrs, error);
         if (access_control != NULL) {
             SecTokenCreateAccessControlError(operation, access_control, error);
             CFRelease(access_control);
         if (access_control != NULL) {
             SecTokenCreateAccessControlError(operation, access_control, error);
             CFRelease(access_control);
index 3231cbc307bd25ad1400f0ea8daa06f1e5862aca..929a66a55a03a9f5adbb2d24cd863d029fe45c42 100644 (file)
@@ -242,6 +242,7 @@ SEC_CONST_DECL (kSecAttrSynchronizableAny, "syna");
    any SecItem apis directly. */
 SEC_CONST_DECL (kSecPrivateKeyAttrs, "private");
 SEC_CONST_DECL (kSecPublicKeyAttrs, "public");
    any SecItem apis directly. */
 SEC_CONST_DECL (kSecPrivateKeyAttrs, "private");
 SEC_CONST_DECL (kSecPublicKeyAttrs, "public");
+SEC_CONST_DECL (kSecKeyApplePayEnabled, "applepay");
 
 /* This is here only temporarily until MobileActivation starts using kSecAttrTokenOID instead of this specific attribute. */
 SEC_CONST_DECL (kSecAttrSecureEnclaveKeyBlob, "toid");
 
 /* This is here only temporarily until MobileActivation starts using kSecAttrTokenOID instead of this specific attribute. */
 SEC_CONST_DECL (kSecAttrSecureEnclaveKeyBlob, "toid");
index 3a49b7c498e7c107b4873f66330530674844637e..545900fae8b312d53f9fd8ea2784285a676efad8 100644 (file)
@@ -31,6 +31,7 @@
 #include <Security/SecItemPriv.h>
 #include <Security/SecItemShim.h>
 #include <Security/SecFramework.h>
 #include <Security/SecItemPriv.h>
 #include <Security/SecItemShim.h>
 #include <Security/SecFramework.h>
+#include <Security/SecCertificate.h>
 
 #include <utilities/SecIOFormat.h>
 
 
 #include <utilities/SecIOFormat.h>
 
@@ -1376,7 +1377,10 @@ SecKeyRef SecKeyCreateDuplicate(SecKeyRef key) {
 }
 
 Boolean SecKeySetParameter(SecKeyRef key, CFStringRef name, CFPropertyListRef value, CFErrorRef *error) {
 }
 
 Boolean SecKeySetParameter(SecKeyRef key, CFStringRef name, CFPropertyListRef value, CFErrorRef *error) {
-    if (key->key_class->version >= 4 && key->key_class->setParameter) {
+    if (key == NULL) {
+        SecCTKKeySetTestMode(name, value);
+        return true;
+    } else if (key->key_class->version >= 4 && key->key_class->setParameter) {
         CFErrorRef localError = NULL;
         Boolean result = key->key_class->setParameter(key, name, value, &localError);
         SecKeyErrorPropagate(result, localError, error);
         CFErrorRef localError = NULL;
         Boolean result = key->key_class->setParameter(key, name, value, &localError);
         SecKeyErrorPropagate(result, localError, error);
@@ -1560,22 +1564,32 @@ Boolean SecKeyVerifySignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRe
     return result;
 }
 
     return result;
 }
 
-CFDataRef SecKeyCreateEncryptedData(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef plainText, CFErrorRef *error) {
+CFDataRef SecKeyCreateEncryptedDataWithParameters(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef plaintext,
+                                                  CFDictionaryRef parameters, CFErrorRef *error) {
     CFErrorRef localError = NULL;
     SecKeyOperationContext context = { key, kSecKeyOperationTypeEncrypt, SecKeyCreateAlgorithmArray(algorithm) };
     CFErrorRef localError = NULL;
     SecKeyOperationContext context = { key, kSecKeyOperationTypeEncrypt, SecKeyCreateAlgorithmArray(algorithm) };
-    CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, plainText, NULL, &localError);
+    CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, plaintext, parameters, &localError);
     SecKeyOperationContextDestroy(&context);
     SecKeyErrorPropagate(result, localError, error);
     return result;
 }
 
     SecKeyOperationContextDestroy(&context);
     SecKeyErrorPropagate(result, localError, error);
     return result;
 }
 
-CFDataRef SecKeyCreateDecryptedData(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef cipherText, CFErrorRef *error) {
+CFDataRef SecKeyCreateEncryptedData(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef plaintext, CFErrorRef *error) {
+    return SecKeyCreateEncryptedDataWithParameters(key, algorithm, plaintext, NULL, error);
+}
+
+CFDataRef SecKeyCreateDecryptedDataWithParameters(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef ciphertext,
+                                                  CFDictionaryRef parameters, CFErrorRef *error) {
     SecKeyOperationContext context = { key, kSecKeyOperationTypeDecrypt, SecKeyCreateAlgorithmArray(algorithm) };
     SecKeyOperationContext context = { key, kSecKeyOperationTypeDecrypt, SecKeyCreateAlgorithmArray(algorithm) };
-    CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, cipherText, NULL, error);
+    CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, ciphertext, parameters, error);
     SecKeyOperationContextDestroy(&context);
     return result;
 }
 
     SecKeyOperationContextDestroy(&context);
     return result;
 }
 
+CFDataRef SecKeyCreateDecryptedData(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef ciphertext, CFErrorRef *error) {
+    return SecKeyCreateDecryptedDataWithParameters(key, algorithm, ciphertext, NULL, error);
+}
+
 CFDataRef SecKeyCopyKeyExchangeResult(SecKeyRef key, SecKeyAlgorithm algorithm, SecKeyRef publicKey,
                                       CFDictionaryRef parameters, CFErrorRef *error) {
     CFErrorRef localError = NULL;
 CFDataRef SecKeyCopyKeyExchangeResult(SecKeyRef key, SecKeyAlgorithm algorithm, SecKeyRef publicKey,
                                       CFDictionaryRef parameters, CFErrorRef *error) {
     CFErrorRef localError = NULL;
index 4c36959159f66986004f10684c3c0dbebbfd975d..d2bfc63799a41294d777ee9621ba76b5bdb04ea1 100644 (file)
@@ -583,6 +583,11 @@ RSA_OAEP_CRYPT_ADAPTOR(SHA512, ccsha512_di());
 const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterRequestedSize = CFSTR("requestedSize");
 const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterSharedInfo = CFSTR("sharedInfo");
 
 const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterRequestedSize = CFSTR("requestedSize");
 const SecKeyKeyExchangeParameter kSecKeyKeyExchangeParameterSharedInfo = CFSTR("sharedInfo");
 
+const CFStringRef kSecKeyEncryptionParameterSymmetricKeySizeInBits = CFSTR("symKeySize");
+const CFStringRef kSecKeyEncryptionParameterSymmetricAAD = CFSTR("aad");
+const CFStringRef kSecKeyEncryptionParameterRecryptParameters = CFSTR("recryptParams");
+const CFStringRef kSecKeyEncryptionParameterRecryptCertificate = CFSTR("recryptCert");
+
 static CFTypeRef SecKeyECDHCopyX963Result(SecKeyOperationContext *context, const struct ccdigest_info *di,
                                           CFTypeRef in1, CFTypeRef params, CFErrorRef *error) {
     CFTypeRef result = NULL;
 static CFTypeRef SecKeyECDHCopyX963Result(SecKeyOperationContext *context, const struct ccdigest_info *di,
                                           CFTypeRef in1, CFTypeRef params, CFErrorRef *error) {
     CFTypeRef result = NULL;
@@ -648,9 +653,9 @@ static CFIndex SecKeyGetCFIndexFromRef(CFTypeRef ref) {
     return result;
 }
 
     return result;
 }
 
-typedef CFDataRef (*SecKeyECIESKeyExchangeCopyResult)(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm, bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV, CFErrorRef *error);
-typedef Boolean (*SecKeyECIESEncryptCopyResult)(CFDataRef keyExchangeResult, CFDataRef inData, CFMutableDataRef result, CFErrorRef *error);
-typedef CFDataRef SecKeyECIESDecryptCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error);
+typedef CFDataRef (*SecKeyECIESKeyExchangeCopyResult)(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm, bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV, CFDictionaryRef inParams, CFErrorRef *error);
+typedef Boolean (*SecKeyECIESEncryptCopyResult)(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams, CFMutableDataRef result, CFErrorRef *error);
+typedef CFDataRef SecKeyECIESDecryptCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams, CFErrorRef *error);
 
 static CFTypeRef SecKeyECIESCopyEncryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
                                               SecKeyECIESKeyExchangeCopyResult keyExchangeCopyResult,
 
 static CFTypeRef SecKeyECIESCopyEncryptedData(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
                                               SecKeyECIESKeyExchangeCopyResult keyExchangeCopyResult,
@@ -681,11 +686,11 @@ static CFTypeRef SecKeyECIESCopyEncryptedData(SecKeyOperationContext *context, S
 
     context->key = ephemeralPrivateKey;
     require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, true,
 
     context->key = ephemeralPrivateKey;
     require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, true,
-                                                            ephemeralPubKeyData, pubKeyData, variableIV, error), out);
+                                                            ephemeralPubKeyData, pubKeyData, variableIV, in2, error), out);
     if (context->mode == kSecKeyOperationModePerform) {
         // Encrypt input data using AES-GCM.
         ciphertext = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, ephemeralPubKeyData);
     if (context->mode == kSecKeyOperationModePerform) {
         // Encrypt input data using AES-GCM.
         ciphertext = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, ephemeralPubKeyData);
-        require_quiet(encryptCopyResult(keyExchangeResult, in1, ciphertext, error), out);
+        require_quiet(encryptCopyResult(keyExchangeResult, in1, in2, ciphertext, error), out);
         result = CFRetain(ciphertext);
     } else {
         result = CFRetain(keyExchangeResult);
         result = CFRetain(ciphertext);
     } else {
         result = CFRetain(keyExchangeResult);
@@ -736,12 +741,12 @@ static CFTypeRef SecKeyECIESCopyDecryptedData(SecKeyOperationContext *context, S
 
     // Perform keyExchange operation.
     require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, false,
 
     // Perform keyExchange operation.
     require_quiet(keyExchangeResult = keyExchangeCopyResult(context, keyExchangeAlgorithm, false,
-                                                            ephemeralPubKeyData, pubKeyData, variableIV, error), out);
+                                                            ephemeralPubKeyData, pubKeyData, variableIV, in2, error), out);
     if (context->mode == kSecKeyOperationModePerform) {
         // Decrypt ciphertext using AES-GCM.
         ciphertext = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ciphertextBuffer, CFDataGetLength(in1) - (keySize * 2 + 1),
                                                  kCFAllocatorNull);
     if (context->mode == kSecKeyOperationModePerform) {
         // Decrypt ciphertext using AES-GCM.
         ciphertext = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ciphertextBuffer, CFDataGetLength(in1) - (keySize * 2 + 1),
                                                  kCFAllocatorNull);
-        require_quiet(result = decryptCopyResult(keyExchangeResult, ciphertext, error), out);
+        require_quiet(result = decryptCopyResult(keyExchangeResult, ciphertext, in2, error), out);
     } else {
         result = CFRetain(keyExchangeResult);
     }
     } else {
         result = CFRetain(keyExchangeResult);
     }
@@ -761,45 +766,55 @@ static const UInt8 kSecKeyIESIV[16] = { 0 };
 
 static CFDataRef SecKeyECIESKeyExchangeKDFX963CopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
                                                          bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV,
 
 static CFDataRef SecKeyECIESKeyExchangeKDFX963CopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
                                                          bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV,
-                                                         CFErrorRef *error) {
-    CFDictionaryRef parameters = NULL;
-    CFNumberRef keySizeRef = NULL;
-    CFDataRef result = NULL;
+                                                         CFDictionaryRef inParams, CFErrorRef *error) {
+    NSDictionary *parametersForKeyExchange, *inputParameters = (__bridge NSDictionary *)inParams;
+    NSData *result;
+    NSMutableData *sharedInfoForKeyExchange;
 
     CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
     context->operation = kSecKeyOperationTypeKeyExchange;
 
     if (context->mode == kSecKeyOperationModePerform) {
 
     CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
     context->operation = kSecKeyOperationTypeKeyExchange;
 
     if (context->mode == kSecKeyOperationModePerform) {
-        // Use 128bit AES for EC keys <= 256bit, 256bit AES for larger keys.
-        CFIndex keySize = ((CFDataGetLength(pubKey) - 1) / 2) * 8;
-        keySize = (keySize > 256) ? (256 / 8) : (128 / 8);
+        NSInteger keySize = 0;
+        NSNumber *keySizeObject = inputParameters[(__bridge id)kSecKeyEncryptionParameterSymmetricKeySizeInBits];
+        if (keySizeObject != nil) {
+            if (![keySizeObject isKindOfClass:NSNumber.class]) {
+                SecError(errSecParam, error, CFSTR("Bad requested kSecKeyEncryptionParameterSymmetricKeySizeInBits: %@"), keySizeObject);
+                return NULL;
+            }
+            keySize = keySizeObject.integerValue / 8;
+        } else {
+            // Use 128bit AES for EC keys <= 256bit, 256bit AES for larger keys.
+            keySize = ((CFDataGetLength(pubKey) - 1) / 2) * 8;
+            keySize = (keySize > 256) ? (256 / 8) : (128 / 8);
+        }
 
         if (variableIV) {
             keySize += sizeof(kSecKeyIESIV);
         }
 
         // Generate shared secret using KDF.
 
         if (variableIV) {
             keySize += sizeof(kSecKeyIESIV);
         }
 
         // Generate shared secret using KDF.
-        keySizeRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &keySize);
-        parameters = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
-                                                  kSecKeyKeyExchangeParameterSharedInfo, ephemeralPubKey,
-                                                  kSecKeyKeyExchangeParameterRequestedSize, keySizeRef,
-                                                  NULL);
+        sharedInfoForKeyExchange = ((__bridge NSData *)ephemeralPubKey).mutableCopy;
+        NSData *sharedInfo = inputParameters[(__bridge id)kSecKeyKeyExchangeParameterSharedInfo];
+        if (sharedInfo != nil) {
+            [sharedInfoForKeyExchange appendData:sharedInfo];
+        }
+        parametersForKeyExchange = @{ (__bridge id)kSecKeyKeyExchangeParameterSharedInfo: sharedInfoForKeyExchange,
+                                      (__bridge id)kSecKeyKeyExchangeParameterRequestedSize: @(keySize) };
     }
 
     }
 
-    result = SecKeyRunAlgorithmAndCopyResult(context, encrypt ? pubKey : ephemeralPubKey, parameters, error);
+    result = CFBridgingRelease(SecKeyRunAlgorithmAndCopyResult(context, encrypt ? pubKey : ephemeralPubKey, (__bridge CFDictionaryRef)parametersForKeyExchange, error));
     if (context->mode == kSecKeyOperationModePerform && !variableIV && result != NULL) {
         // Append all-zero IV to the result.
     if (context->mode == kSecKeyOperationModePerform && !variableIV && result != NULL) {
         // Append all-zero IV to the result.
-        CFMutableDataRef data = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, result);
-        CFDataAppendBytes(data, kSecKeyIESIV, sizeof(kSecKeyIESIV));
-        CFAssignRetained(result, data);
+        NSMutableData *data = result.mutableCopy;
+        [data appendBytes:kSecKeyIESIV length:sizeof(kSecKeyIESIV)];
+        result = [NSData dataWithData:data];
     }
     }
-    CFReleaseSafe(parameters);
-    CFReleaseSafe(keySizeRef);
-    return result;
+    return CFBridgingRetain(result);
 }
 
 }
 
-static Boolean SecKeyECIESEncryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFMutableDataRef result,
-                                                  CFErrorRef *error) {
+static Boolean SecKeyECIESEncryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams,
+                                                  CFMutableDataRef result, CFErrorRef *error) {
     Boolean res = FALSE;
     CFIndex prefix = CFDataGetLength(result);
     CFDataSetLength(result, prefix + CFDataGetLength(inData) + kSecKeyIESTagLength);
     Boolean res = FALSE;
     CFIndex prefix = CFDataGetLength(result);
     CFDataSetLength(result, prefix + CFDataGetLength(inData) + kSecKeyIESTagLength);
@@ -807,10 +822,11 @@ static Boolean SecKeyECIESEncryptAESGCMCopyResult(CFDataRef keyExchangeResult, C
     UInt8 *tagBuffer = resultBuffer + CFDataGetLength(inData);
     CFIndex aesKeySize = CFDataGetLength(keyExchangeResult) - sizeof(kSecKeyIESIV);
     const UInt8 *ivBuffer = CFDataGetBytePtr(keyExchangeResult) + aesKeySize;
     UInt8 *tagBuffer = resultBuffer + CFDataGetLength(inData);
     CFIndex aesKeySize = CFDataGetLength(keyExchangeResult) - sizeof(kSecKeyIESIV);
     const UInt8 *ivBuffer = CFDataGetBytePtr(keyExchangeResult) + aesKeySize;
+    CFDataRef aad = inParams ? CFDictionaryGetValue(inParams, kSecKeyEncryptionParameterSymmetricAAD) : NULL;
     require_action_quiet(ccgcm_one_shot(ccaes_gcm_encrypt_mode(),
                                         aesKeySize, CFDataGetBytePtr(keyExchangeResult),
                                         sizeof(kSecKeyIESIV), ivBuffer,
     require_action_quiet(ccgcm_one_shot(ccaes_gcm_encrypt_mode(),
                                         aesKeySize, CFDataGetBytePtr(keyExchangeResult),
                                         sizeof(kSecKeyIESIV), ivBuffer,
-                                        0, NULL,
+                                        aad ? CFDataGetLength(aad) : 0, aad ? CFDataGetBytePtr(aad) : NULL,
                                         CFDataGetLength(inData), CFDataGetBytePtr(inData),
                                         resultBuffer, kSecKeyIESTagLength, tagBuffer) == 0, out,
                          SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm encrypt data")));
                                         CFDataGetLength(inData), CFDataGetBytePtr(inData),
                                         resultBuffer, kSecKeyIESTagLength, tagBuffer) == 0, out,
                          SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm encrypt data")));
@@ -819,7 +835,8 @@ out:
     return res;
 }
 
     return res;
 }
 
-static CFDataRef SecKeyECIESDecryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error) {
+static CFDataRef SecKeyECIESDecryptAESGCMCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams,
+                                                    CFErrorRef *error) {
     CFDataRef result = NULL;
     CFMutableDataRef plaintext = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData) - kSecKeyIESTagLength);
     CFMutableDataRef tag = CFDataCreateMutableWithScratch(SecCFAllocatorZeroize(), kSecKeyIESTagLength);
     CFDataRef result = NULL;
     CFMutableDataRef plaintext = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData) - kSecKeyIESTagLength);
     CFMutableDataRef tag = CFDataCreateMutableWithScratch(SecCFAllocatorZeroize(), kSecKeyIESTagLength);
@@ -827,10 +844,11 @@ static CFDataRef SecKeyECIESDecryptAESGCMCopyResult(CFDataRef keyExchangeResult,
                    CFDataGetMutableBytePtr(tag));
     CFIndex aesKeySize = CFDataGetLength(keyExchangeResult) - sizeof(kSecKeyIESIV);
     const UInt8 *ivBuffer = CFDataGetBytePtr(keyExchangeResult) + aesKeySize;
                    CFDataGetMutableBytePtr(tag));
     CFIndex aesKeySize = CFDataGetLength(keyExchangeResult) - sizeof(kSecKeyIESIV);
     const UInt8 *ivBuffer = CFDataGetBytePtr(keyExchangeResult) + aesKeySize;
+    CFDataRef aad = inParams ? CFDictionaryGetValue(inParams, kSecKeyEncryptionParameterSymmetricAAD) : NULL;
     require_action_quiet(ccgcm_one_shot(ccaes_gcm_decrypt_mode(),
                                         aesKeySize, CFDataGetBytePtr(keyExchangeResult),
                                         sizeof(kSecKeyIESIV), ivBuffer,
     require_action_quiet(ccgcm_one_shot(ccaes_gcm_decrypt_mode(),
                                         aesKeySize, CFDataGetBytePtr(keyExchangeResult),
                                         sizeof(kSecKeyIESIV), ivBuffer,
-                                        0, NULL,
+                                        aad ? CFDataGetLength(aad) : 0, aad ? CFDataGetBytePtr(aad) : NULL,
                                         CFDataGetLength(plaintext), CFDataGetBytePtr(inData), CFDataGetMutableBytePtr(plaintext),
                                         kSecKeyIESTagLength, CFDataGetMutableBytePtr(tag)) == 0, out,
                          SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm decrypt data")));
                                         CFDataGetLength(plaintext), CFDataGetBytePtr(inData), CFDataGetMutableBytePtr(plaintext),
                                         kSecKeyIESTagLength, CFDataGetMutableBytePtr(tag)) == 0, out,
                          SecError(errSecParam, error, CFSTR("ECIES: Failed to aes-gcm decrypt data")));
@@ -877,7 +895,7 @@ ECIES_X963_ADAPTOR(SHA512, Cofactor, VariableIVX963, true)
 
 static CFDataRef SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
                                                                 bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV,
 
 static CFDataRef SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult(SecKeyOperationContext *context, SecKeyAlgorithm keyExchangeAlgorithm,
                                                                 bool encrypt, CFDataRef ephemeralPubKey, CFDataRef pubKey, bool variableIV,
-                                                                CFErrorRef *error) {
+                                                                CFDictionaryRef inParams, CFErrorRef *error) {
     CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
     context->operation = kSecKeyOperationTypeKeyExchange;
     CFMutableDataRef result = (CFMutableDataRef)SecKeyRunAlgorithmAndCopyResult(context, ephemeralPubKey, NULL, error);
     CFArrayAppendValue(context->algorithm, keyExchangeAlgorithm);
     context->operation = kSecKeyOperationTypeKeyExchange;
     CFMutableDataRef result = (CFMutableDataRef)SecKeyRunAlgorithmAndCopyResult(context, ephemeralPubKey, NULL, error);
@@ -894,7 +912,8 @@ static CFDataRef SecKeyECIESKeyExchangeSHA2562PubKeysCopyResult(SecKeyOperationC
     return result;
 }
 
     return result;
 }
 
-static CFDataRef SecKeyECIESDecryptAESCBCCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFErrorRef *error) {
+static CFDataRef SecKeyECIESDecryptAESCBCCopyResult(CFDataRef keyExchangeResult, CFDataRef inData, CFDictionaryRef inParams,
+                                                    CFErrorRef *error) {
     CFMutableDataRef result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData));
     cccbc_one_shot(ccaes_cbc_decrypt_mode(),
                    CFDataGetLength(keyExchangeResult), CFDataGetBytePtr(keyExchangeResult),
     CFMutableDataRef result = CFDataCreateMutableWithScratch(kCFAllocatorDefault, CFDataGetLength(inData));
     cccbc_one_shot(ccaes_cbc_decrypt_mode(),
                    CFDataGetLength(keyExchangeResult), CFDataGetBytePtr(keyExchangeResult),
index 774536a5062fcfbd9400306c27f55ab58cf48a1b..f04a136ea4e5aea5c9d1c4d83a0787395b26d633 100644 (file)
@@ -547,7 +547,7 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error)
         @autoreleasepool {
             os_transaction_t transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.download");
             if (result != MADownloadSucceesful) {
         @autoreleasepool {
             os_transaction_t transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.download");
             if (result != MADownloadSucceesful) {
-                MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MADownLoadResult", result,
+                MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MADownLoadResult", (OSStatus)result,
                                   @"failed to download catalog: %ld", (long)result);
                 if (result == MADownloadDaemonNotReady) {
                     /* mobileassetd has to wait for first unlock to downalod. trustd usually launches before first unlock. */
                                   @"failed to download catalog: %ld", (long)result);
                 if (result == MADownloadDaemonNotReady) {
                     /* mobileassetd has to wait for first unlock to downalod. trustd usually launches before first unlock. */
@@ -561,7 +561,7 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error)
             secnotice("OTATrust", "begin MobileAsset metadata sync request");
             MAQueryResult queryResult = [query queryMetaDataSync];
             if (queryResult != MAQuerySucceesful) {
             secnotice("OTATrust", "begin MobileAsset metadata sync request");
             MAQueryResult queryResult = [query queryMetaDataSync];
             if (queryResult != MAQuerySucceesful) {
-                MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MAQueryResult", queryResult,
+                MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MAQueryResult", (OSStatus)queryResult,
                                   @"failed to query MobileAsset metadata: %ld", (long)queryResult);
                 return;
             }
                                   @"failed to query MobileAsset metadata: %ld", (long)queryResult);
                 return;
             }
@@ -609,7 +609,7 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error)
                         updated_version = UpdateAndPurgeAsset(asset, asset_version, &ma_error);
                         break;
                     case MAUnknown:
                         updated_version = UpdateAndPurgeAsset(asset, asset_version, &ma_error);
                         break;
                     case MAUnknown:
-                        MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MAAssetState", asset.state,
+                        MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MAAssetState", (OSStatus)asset.state,
                                           @"asset is unknown");
                         continue;
                     case MADownloading:
                                           @"asset is unknown");
                         continue;
                     case MADownloading:
@@ -622,7 +622,7 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error)
                             @autoreleasepool {
                                 os_transaction_t inner_transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.downloadAsset");
                                 if (downloadResult != MADownloadSucceesful) {
                             @autoreleasepool {
                                 os_transaction_t inner_transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.downloadAsset");
                                 if (downloadResult != MADownloadSucceesful) {
-                                    MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MADownLoadResult", downloadResult,
+                                    MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MADownLoadResult", (OSStatus)downloadResult,
                                                       @"failed to download asset: %ld", (long)downloadResult);
                                     return;
                                 }
                                                       @"failed to download asset: %ld", (long)downloadResult);
                                     return;
                                 }
index 991f5a80278eb07569b740923fd1b3ea892b17aa..f7422fc26455697ceb1cff2277d446882d57230d 100644 (file)
@@ -554,23 +554,6 @@ static void test_key_sign(void) {
             return acData;
         };
 
             return acData;
         };
 
-        blocks->copyObjectOperationAlgorithms = ^CFSetRef(CFDataRef oid, CFIndex operation, CFErrorRef *error) {
-            static NSSet *ops[] = {
-                [kSecKeyOperationTypeSign] = NULL,
-                [kSecKeyOperationTypeDecrypt] = NULL,
-                [kSecKeyOperationTypeKeyExchange] = NULL,
-            };
-
-            static dispatch_once_t onceToken;
-            dispatch_once(&onceToken, ^{
-                ops[kSecKeyOperationTypeSign] = [NSSet setWithArray:@[(id)kSecKeyAlgorithmECDSASignatureDigestX962]];
-                ops[kSecKeyOperationTypeDecrypt] = [NSSet setWithArray:@[(id)kSecKeyAlgorithmRSAEncryptionRaw]];
-                ops[kSecKeyOperationTypeKeyExchange] = [NSSet setWithArray:@[(id)kSecKeyAlgorithmECDHKeyExchangeCofactor]];
-            });
-
-            return CFBridgingRetain(ops[operation]);
-        };
-
         blocks->copyOperationResult = ^CFTypeRef(CFDataRef objectID, CFIndex operation, CFArrayRef algorithms, CFIndex secKeyOperationMode, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
             SecKeyAlgorithm algorithm = CFArrayGetValueAtIndex(algorithms, CFArrayGetCount(algorithms) - 1);
             phase++;
         blocks->copyOperationResult = ^CFTypeRef(CFDataRef objectID, CFIndex operation, CFArrayRef algorithms, CFIndex secKeyOperationMode, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) {
             SecKeyAlgorithm algorithm = CFArrayGetValueAtIndex(algorithms, CFArrayGetCount(algorithms) - 1);
             phase++;
index f747bf4567084c5a4530c95e66d954fab15ffb0c..b53cd556f59b5f54c0a48ba29307c9181888c9b9 100644 (file)
@@ -936,23 +936,19 @@ static void SecPolicyCheckBasicCertificateProcessing(SecPVCRef pvc,
            chain (root). */
         n--;
     } else {
            chain (root). */
         n--;
     } else {
-        /* trust may be restored for a path with an untrusted root that matches the allow list.
-           (isAllowlisted is set by revocation check, which is performed prior to path checks) */
-        if (!SecCertificatePathVCIsAllowlisted(path)) {
-            Boolean isSelfSigned = false;
-            (void) SecCertificateIsSelfSigned(SecCertificatePathVCGetCertificateAtIndex(path, n - 1), &isSelfSigned);
-            if (isSelfSigned) {
-                /* Add a detail for the root not being trusted. */
-                if (!SecPVCSetResultForced(pvc, kSecPolicyCheckAnchorTrusted,
-                                           n - 1, kCFBooleanFalse, true)) {
-                    return;
-                }
-            } else {
-                /* Add a detail for the missing intermediate. */
-                if (!SecPVCSetResultForced(pvc, kSecPolicyCheckMissingIntermediate,
-                                           n - 1, kCFBooleanFalse, true)) {
-                    return;
-                }
+        Boolean isSelfSigned = false;
+        (void) SecCertificateIsSelfSigned(SecCertificatePathVCGetCertificateAtIndex(path, n - 1), &isSelfSigned);
+        if (isSelfSigned) {
+            /* Add a detail for the root not being trusted. */
+            if (!SecPVCSetResultForced(pvc, kSecPolicyCheckAnchorTrusted,
+                                       n - 1, kCFBooleanFalse, true)) {
+                return;
+            }
+        } else {
+            /* Add a detail for the missing intermediate. */
+            if (!SecPVCSetResultForced(pvc, kSecPolicyCheckMissingIntermediate,
+                                       n - 1, kCFBooleanFalse, true)) {
+                return;
             }
         }
     }
             }
         }
     }
@@ -2312,9 +2308,10 @@ static void SecPolicyCheckSystemTrustedCTRequired(SecPVCRef pvc) {
      *     Or the caller passed in the trusted log list. */
     require_quiet(SecOTAPKIAssetStalenessLessThanSeconds(otaref, kSecOTAPKIAssetStalenessDisable) || trustedLogs, out);
 
      *     Or the caller passed in the trusted log list. */
     require_quiet(SecOTAPKIAssetStalenessLessThanSeconds(otaref, kSecOTAPKIAssetStalenessDisable) || trustedLogs, out);
 
-    /*  2. Leaf issuance date is on or after 16 Oct 2018 at 00:00:00 AM UTC */
+    /*  2. Leaf issuance date is on or after 16 Oct 2018 at 00:00:00 AM UTC and not expired. */
     SecCertificateRef leaf = SecPVCGetCertificateAtIndex(pvc, 0);
     SecCertificateRef leaf = SecPVCGetCertificateAtIndex(pvc, 0);
-    require_quiet(SecCertificateNotValidBefore(leaf) >= 561340800.0, out);
+    require_quiet(SecCertificateNotValidBefore(leaf) >= 561340800.0 &&
+                  SecCertificateIsValid(leaf, SecPVCGetVerifyTime(pvc)), out);
 
     /*  3. Chain is anchored with root in the system anchor source but not the Apple anchor source */
     CFIndex count = SecPVCGetCertificateCount(pvc);
 
     /*  3. Chain is anchored with root in the system anchor source but not the Apple anchor source */
     CFIndex count = SecPVCGetCertificateCount(pvc);
index 09eec204a15c9bb14fa8fdaf717d2b208a5bcdf6..d12695b2e337eba4b576fd4a85c7e951e0cf90af 100644 (file)
@@ -314,6 +314,8 @@ static ValidUpdateRequest *request = nil;
         config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: @"com.apple.trustd.networking.background"];
         config.networkServiceType = NSURLNetworkServiceTypeBackground;
         config.discretionary = YES;
         config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: @"com.apple.trustd.networking.background"];
         config.networkServiceType = NSURLNetworkServiceTypeBackground;
         config.discretionary = YES;
+        config._requiresPowerPluggedIn = YES;
+        config.allowsCellularAccess = (!updateOnWiFiOnly) ? YES : NO;
     } else {
         config = [NSURLSessionConfiguration ephemeralSessionConfiguration]; // no cookies or data storage
         config.networkServiceType = NSURLNetworkServiceTypeDefault;
     } else {
         config = [NSURLSessionConfiguration ephemeralSessionConfiguration]; // no cookies or data storage
         config.networkServiceType = NSURLNetworkServiceTypeDefault;
@@ -327,10 +329,6 @@ static ValidUpdateRequest *request = nil;
     config.TLSMinimumSupportedProtocol = kTLSProtocol12;
     config.TLSMaximumSupportedProtocol = kTLSProtocol13;
 
     config.TLSMinimumSupportedProtocol = kTLSProtocol12;
     config.TLSMaximumSupportedProtocol = kTLSProtocol13;
 
-    config._requiresPowerPluggedIn = YES;
-
-    config.allowsCellularAccess = (!updateOnWiFiOnly) ? YES : NO;
-
     return config;
 }
 
     return config;
 }
 
diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA2G1-Baltimore.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA2G1-Baltimore.cer
new file mode 100644 (file)
index 0000000..9e2b0a6
Binary files /dev/null and b/OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA2G1-Baltimore.cer differ
diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA8G1-Baltimore.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA8G1-Baltimore.cer
new file mode 100644 (file)
index 0000000..06cb8e5
Binary files /dev/null and b/OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA8G1-Baltimore.cer differ
diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA8G1-DigiCert.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA8G1-DigiCert.cer
new file mode 100644 (file)
index 0000000..3384c19
Binary files /dev/null and b/OSX/shared_regressions/si-20-sectrust-policies-data/AppleISTCA8G1-DigiCert.cer differ
diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/BaltimoreCyberTrustRoot.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/BaltimoreCyberTrustRoot.cer
new file mode 100644 (file)
index 0000000..da96dbb
Binary files /dev/null and b/OSX/shared_regressions/si-20-sectrust-policies-data/BaltimoreCyberTrustRoot.cer differ
diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/DigiCertGlobalRootG3.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/DigiCertGlobalRootG3.cer
new file mode 100644 (file)
index 0000000..6dda6a3
Binary files /dev/null and b/OSX/shared_regressions/si-20-sectrust-policies-data/DigiCertGlobalRootG3.cer differ
index 9b6326acb2aeef36bb6c4755be024dd72f66303f..ea40b6d8496c6895262d1e6c06d5ea815c672a85 100644 (file)
                        <key>Properties</key>
                        <dict>
                                <key>SecPolicyName</key>
                        <key>Properties</key>
                        <dict>
                                <key>SecPolicyName</key>
-                               <string>p04-fmip.icloud.com</string>
+                               <string>bbasile-test.scv.apple.com</string>
                        </dict>
                </dict>
                <key>Leaf</key>
                        </dict>
                </dict>
                <key>Leaf</key>
-               <string>fmip</string>
+               <string>generic_apple_server</string>
                <key>Intermediates</key>
                <string>AppleServerAuthentication</string>
                <key>Anchors</key>
                <string>AppleRootCA</string>
                <key>VerifyDate</key>
                <key>Intermediates</key>
                <string>AppleServerAuthentication</string>
                <key>Anchors</key>
                <string>AppleRootCA</string>
                <key>VerifyDate</key>
-               <date>2016-04-18T19:00:00Z</date>
+               <date>2019-04-18T19:00:00Z</date>
                <key>ExpectedResult</key>
                <integer>5</integer>
        </dict>
                <key>ExpectedResult</key>
                <integer>5</integer>
        </dict>
                <key>Anchors</key>
                <string>AppleRootCA</string>
                <key>VerifyDate</key>
                <key>Anchors</key>
                <string>AppleRootCA</string>
                <key>VerifyDate</key>
-               <date>2014-07-20T19:00:00Z</date>
+               <date>2019-07-20T19:00:00Z</date>
                <key>ExpectedResult</key>
                <integer>4</integer>
                <key>ChainLength</key>
                <key>ExpectedResult</key>
                <integer>4</integer>
                <key>ChainLength</key>
                <key>ExpectedResult</key>
                <integer>5</integer>
        </dict>
                <key>ExpectedResult</key>
                <integer>5</integer>
        </dict>
+       <dict>
+               <key>MajorTestName</key>
+               <string>ISTCrossSignPinning</string>
+               <key>MinorTestName</key>
+               <string>PositiveTest</string>
+               <key>Policies</key>
+               <dict>
+                       <key>PolicyIdentifier</key>
+                       <string>1.2.840.113635.100.1.74</string>
+                       <key>Properties</key>
+                       <dict>
+                               <key>SecPolicyName</key>
+                               <string>caldav.icloud.com</string>
+                       </dict>
+               </dict>
+               <key>Leaf</key>
+               <string>caldav</string>
+               <key>Intermediates</key>
+               <string>AppleISTCA2G1-Baltimore</string>
+               <key>Anchors</key>
+               <string>BaltimoreCyberTrustRoot</string>
+               <key>ExpectedResult</key>
+               <integer>4</integer>
+               <key>VerifyDate</key>
+               <date>2019-10-04T19:00:00Z</date>
+               <key>ChainLength</key>
+               <integer>3</integer>
+       </dict>
+       <dict>
+               <key>MajorTestName</key>
+               <string>ISTCrossSignPinning</string>
+               <key>MinorTestName</key>
+               <string>BothPositiveTest</string>
+               <key>Policies</key>
+               <dict>
+                       <key>PolicyIdentifier</key>
+                       <string>1.2.840.113635.100.1.74</string>
+                       <key>Properties</key>
+                       <dict>
+                               <key>SecPolicyName</key>
+                               <string>caldav.icloud.com</string>
+                       </dict>
+               </dict>
+               <key>Leaf</key>
+               <string>caldav</string>
+               <key>Intermediates</key>
+               <array>
+                       <string>AppleISTCA2G1</string>
+                       <string>AppleISTCA2G1-Baltimore</string>
+               </array>
+               <key>Anchors</key>
+               <string>BaltimoreCyberTrustRoot</string>
+               <key>ExpectedResult</key>
+               <integer>4</integer>
+               <key>VerifyDate</key>
+               <date>2019-10-04T19:00:00Z</date>
+               <key>ChainLength</key>
+               <integer>3</integer>
+       </dict>
+       <dict>
+               <key>MajorTestName</key>
+               <string>ISTCrossSignPinning</string>
+               <key>MinorTestName</key>
+               <string>BothPositiveTest</string>
+               <key>Policies</key>
+               <dict>
+                       <key>PolicyIdentifier</key>
+                       <string>1.2.840.113635.100.1.74</string>
+                       <key>Properties</key>
+                       <dict>
+                               <key>SecPolicyName</key>
+                               <string>caldav.icloud.com</string>
+                       </dict>
+               </dict>
+               <key>Leaf</key>
+               <string>caldav</string>
+               <key>Intermediates</key>
+               <array>
+                       <string>AppleISTCA2G1</string>
+                       <string>AppleISTCA2G1-Baltimore</string>
+               </array>
+               <key>Anchors</key>
+               <string>GeoTrustGlobalCA</string>
+               <key>ExpectedResult</key>
+               <integer>4</integer>
+               <key>VerifyDate</key>
+               <date>2019-10-04T19:00:00Z</date>
+               <key>ChainLength</key>
+               <integer>3</integer>
+       </dict>
+       <dict>
+               <key>MajorTestName</key>
+               <string>ISTCrossSign</string>
+               <key>MinorTestName</key>
+               <string>PositiveTest</string>
+               <key>Policies</key>
+               <dict>
+                       <key>PolicyIdentifier</key>
+                       <string>1.2.840.113635.100.1.3</string>
+                       <key>Properties</key>
+                       <dict>
+                               <key>SecPolicyName</key>
+                               <string>caldav.icloud.com</string>
+                       </dict>
+               </dict>
+               <key>Leaf</key>
+               <string>caldav</string>
+               <key>Intermediates</key>
+               <string>AppleISTCA2G1-Baltimore</string>
+               <key>Anchors</key>
+               <string>BaltimoreCyberTrustRoot</string>
+               <key>ExpectedResult</key>
+               <integer>4</integer>
+               <key>VerifyDate</key>
+               <date>2019-10-04T19:00:00Z</date>
+               <key>ChainLength</key>
+               <integer>3</integer>
+       </dict>
+       <dict>
+               <key>MajorTestName</key>
+               <string>ISTCrossSignCA8Baltimore</string>
+               <key>MinorTestName</key>
+               <string>PositiveTest</string>
+               <key>Policies</key>
+               <dict>
+                       <key>PolicyIdentifier</key>
+                       <string>1.2.840.113635.100.1.3</string>
+                       <key>Properties</key>
+                       <dict>
+                               <key>SecPolicyName</key>
+                               <string>hls-svod.itunes.apple.com</string>
+                       </dict>
+               </dict>
+               <key>Leaf</key>
+               <string>itunes</string>
+               <key>Intermediates</key>
+               <string>AppleISTCA8G1-Baltimore</string>
+               <key>Anchors</key>
+               <string>BaltimoreCyberTrustRoot</string>
+               <key>ExpectedResult</key>
+               <integer>4</integer>
+               <key>VerifyDate</key>
+               <date>2019-10-04T19:00:00Z</date>
+               <key>ChainLength</key>
+               <integer>3</integer>
+       </dict>
+       <dict>
+               <key>MajorTestName</key>
+               <string>ISTCrossSignCA8DigiCert</string>
+               <key>MinorTestName</key>
+               <string>PositiveTest</string>
+               <key>Policies</key>
+               <dict>
+                       <key>PolicyIdentifier</key>
+                       <string>1.2.840.113635.100.1.3</string>
+                       <key>Properties</key>
+                       <dict>
+                               <key>SecPolicyName</key>
+                               <string>hls-svod.itunes.apple.com</string>
+                       </dict>
+               </dict>
+               <key>Leaf</key>
+               <string>itunes</string>
+               <key>Intermediates</key>
+               <string>AppleISTCA8G1-DigiCert</string>
+               <key>Anchors</key>
+               <string>DigiCertGlobalRootG3</string>
+               <key>ExpectedResult</key>
+               <integer>4</integer>
+               <key>VerifyDate</key>
+               <date>2019-10-04T19:00:00Z</date>
+       </dict>
+       <dict>
+               <key>MajorTestName</key>
+               <string>ISTCrossSign</string>
+               <key>MinorTestName</key>
+               <string>BothPositiveTest</string>
+               <key>Policies</key>
+               <dict>
+                       <key>PolicyIdentifier</key>
+                       <string>1.2.840.113635.100.1.3</string>
+                       <key>Properties</key>
+                       <dict>
+                               <key>SecPolicyName</key>
+                               <string>caldav.icloud.com</string>
+                       </dict>
+               </dict>
+               <key>Leaf</key>
+               <string>caldav</string>
+               <key>Intermediates</key>
+               <array>
+                       <string>AppleISTCA2G1-Baltimore</string>
+                       <string>AppleISTCA2G1</string>
+               </array>
+               <key>ExpectedResult</key>
+               <integer>4</integer>
+               <key>Anchors</key>
+               <string>GeoTrustGlobalCA</string>
+               <key>VerifyDate</key>
+               <date>2019-10-04T19:00:00Z</date>
+               <key>ChainLength</key>
+               <integer>3</integer>
+       </dict>
+       <dict>
+               <key>MajorTestName</key>
+               <string>ISTCrossSign</string>
+               <key>MinorTestName</key>
+               <string>BothPositiveTest</string>
+               <key>Policies</key>
+               <dict>
+                       <key>PolicyIdentifier</key>
+                       <string>1.2.840.113635.100.1.3</string>
+                       <key>Properties</key>
+                       <dict>
+                               <key>SecPolicyName</key>
+                               <string>caldav.icloud.com</string>
+                       </dict>
+               </dict>
+               <key>Leaf</key>
+               <string>caldav</string>
+               <key>Intermediates</key>
+               <array>
+                       <string>AppleISTCA2G1-Baltimore</string>
+                       <string>AppleISTCA2G1</string>
+               </array>
+               <key>ExpectedResult</key>
+               <integer>4</integer>
+               <key>Anchors</key>
+               <string>BaltimoreCyberTrustRoot</string>
+               <key>VerifyDate</key>
+               <date>2019-10-04T19:00:00Z</date>
+               <key>ChainLength</key>
+               <integer>3</integer>
+       </dict>
+       <dict>
+               <key>MajorTestName</key>
+               <string>ISTCrossSignOldPin</string>
+               <key>MinorTestName</key>
+               <string>PositiveTest</string>
+               <key>Policies</key>
+               <dict>
+                       <key>PolicyIdentifier</key>
+                       <string>1.2.840.113635.100.1.74</string>
+                       <key>Properties</key>
+                       <dict>
+                               <key>SecPolicyName</key>
+                               <string>caldav.icloud.com</string>
+                               <key>SecPolicyPolicyName</key>
+                               <string>no-system-pinning-rules</string>
+                       </dict>
+               </dict>
+               <key>Leaf</key>
+               <string>caldav</string>
+               <key>Intermediates</key>
+               <array>
+                       <string>AppleISTCA2G1-Baltimore</string>
+                       <string>AppleISTCA2G1</string>
+               </array>
+               <key>Anchors</key>
+               <string>GeoTrustGlobalCA</string>
+               <key>ExpectedResult</key>
+               <integer>4</integer>
+               <key>VerifyDate</key>
+               <date>2019-10-04T19:00:00Z</date>
+               <key>ChainLength</key>
+               <integer>3</integer>
+       </dict>
+       <dict>
+               <key>MajorTestName</key>
+               <string>ISTCrossSignOldPin</string>
+               <key>MinorTestName</key>
+               <string>PositiveTest</string>
+               <key>Policies</key>
+               <dict>
+                       <key>PolicyIdentifier</key>
+                       <string>1.2.840.113635.100.1.74</string>
+                       <key>Properties</key>
+                       <dict>
+                               <key>SecPolicyName</key>
+                               <string>caldav.icloud.com</string>
+                               <key>SecPolicyPolicyName</key>
+                               <string>no-system-pinning-rules</string>
+                       </dict>
+               </dict>
+               <key>Leaf</key>
+               <string>caldav</string>
+               <key>Intermediates</key>
+               <array>
+                       <string>AppleISTCA2G1-Baltimore</string>
+                       <string>AppleISTCA2G1</string>
+               </array>
+               <key>Anchors</key>
+               <string>BaltimoreCyberTrustRoot</string>
+               <key>ExpectedResult</key>
+               <integer>5</integer>
+               <key>VerifyDate</key>
+               <date>2019-10-04T19:00:00Z</date>
+               <key>ChainLength</key>
+               <integer>3</integer>
+       </dict>
 </array>
 </plist>
 </array>
 </plist>
diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/caldav.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/caldav.cer
new file mode 100644 (file)
index 0000000..35b92cc
Binary files /dev/null and b/OSX/shared_regressions/si-20-sectrust-policies-data/caldav.cer differ
index d38700210e7a9d85632f24e1654b1a489b6b518c..f91a14eb1ee7e29cada1cc1ed77e338420d38cab 100644 (file)
Binary files a/OSX/shared_regressions/si-20-sectrust-policies-data/generic_apple_server.cer and b/OSX/shared_regressions/si-20-sectrust-policies-data/generic_apple_server.cer differ
diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/itunes.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/itunes.cer
new file mode 100644 (file)
index 0000000..c1681b6
Binary files /dev/null and b/OSX/shared_regressions/si-20-sectrust-policies-data/itunes.cer differ
index a6568eea6279815aecbe6879ce6071640f40898a..16632ba6fd27031b0e11b02bfedbf787d85112a1 100644 (file)
@@ -6,6 +6,8 @@
 #import <Security/Security.h>
 #import <Security/SecItemPriv.h>
 #import <Security/SecKeyPriv.h>
 #import <Security/Security.h>
 #import <Security/SecItemPriv.h>
 #import <Security/SecKeyPriv.h>
+#import <Security/SecAccessControlPriv.h>
+#import <libaks_acl_cf_keys.h>
 #if !TARGET_OS_OSX
 #import "MobileGestalt.h"
 #else
 #if !TARGET_OS_OSX
 #import "MobileGestalt.h"
 #else
 
 #import "shared_regressions.h"
 
 
 #import "shared_regressions.h"
 
-static id generateKey(id keyType, CFStringRef protection) {
-    id accessControl = (__bridge_transfer id)SecAccessControlCreateWithFlags(NULL, protection, kSecAccessControlPrivateKeyUsage, NULL);
+static id generateKey(id keyType, CFStringRef protection, BOOL noACL) {
+    id accessControl;
+    if (noACL) {
+        accessControl = CFBridgingRelease(SecAccessControlCreate(kCFAllocatorDefault, NULL));
+        SecAccessControlSetProtection((__bridge SecAccessControlRef)accessControl, protection, NULL);
+    } else {
+        accessControl = CFBridgingRelease(SecAccessControlCreateWithFlags(NULL, protection, kSecAccessControlPrivateKeyUsage, NULL));
+    }
     NSDictionary *keyAttributes = @{ (id)kSecAttrTokenID : (id)kSecAttrTokenIDAppleKeyStore,
                                      (id)kSecAttrKeyType : keyType,
                                      (id)kSecAttrAccessControl : accessControl,
     NSDictionary *keyAttributes = @{ (id)kSecAttrTokenID : (id)kSecAttrTokenIDAppleKeyStore,
                                      (id)kSecAttrKeyType : keyType,
                                      (id)kSecAttrAccessControl : accessControl,
@@ -33,8 +41,9 @@ static void secKeySepTest(BOOL testPKA) {
     } else {
         keyTypes = @[(id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeyTypeSecureEnclaveAttestation];
     }
     } else {
         keyTypes = @[(id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeyTypeSecureEnclaveAttestation];
     }
+    BOOL noACL = YES;
     for (id keyType in keyTypes) {
     for (id keyType in keyTypes) {
-        id privateKey = generateKey((id)keyType, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly);
+        id privateKey = generateKey((id)keyType, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, (noACL = !noACL));
         ok(privateKey, "failed to create key '%@'", keyType);
         id publicKey = (__bridge_transfer id)SecKeyCopyPublicKey((SecKeyRef)privateKey);
 
         ok(privateKey, "failed to create key '%@'", keyType);
         id publicKey = (__bridge_transfer id)SecKeyCopyPublicKey((SecKeyRef)privateKey);
 
@@ -83,10 +92,10 @@ static void secKeySepTest(BOOL testPKA) {
     }
 }
 
     }
 }
 
-static void attestationTest(CFStringRef protection) {
+static void attestationTest(CFStringRef protection, BOOL noACL) {
     NSError *error;
     NSError *error;
-    id privKey = generateKey((id)kSecAttrKeyTypeECSECPrimeRandom, protection);
-    id uik = generateKey((id)kSecAttrKeyTypeSecureEnclaveAttestation, protection);
+    id privKey = generateKey((id)kSecAttrKeyTypeECSECPrimeRandom, protection, noACL);
+    id uik = generateKey((id)kSecAttrKeyTypeSecureEnclaveAttestation, protection, noACL);
     id sik = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeSIK, (void *)&error));
     ok(sik != nil, "get SIK key: %@", error);
 
     id sik = CFBridgingRelease(SecKeyCopyAttestationKey(kSecKeyAttestationKeyTypeSIK, (void *)&error));
     ok(sik != nil, "get SIK key: %@", error);
 
@@ -178,6 +187,215 @@ static void attestationTest(CFStringRef protection) {
     }
 }
 
     }
 }
 
+static const uint8_t satori_pub[] = {
+    0x04, 0xe4, 0xef, 0x00, 0x27, 0xcb, 0xa6, 0x46, 0x0d, 0xa6, 0xbd, 0x77, 0x14, 0x65, 0xe5, 0x5a,
+    0x14, 0xc9, 0xf8, 0xd8, 0xdd, 0x4c, 0x70, 0x44, 0x50, 0x49, 0xe4, 0xfa, 0x24, 0x71, 0xaa, 0x4c,
+    0xe2, 0x74, 0x3b, 0xfd, 0x23, 0xda, 0x6f, 0x92, 0x04, 0x4c, 0x93, 0x6c, 0xea, 0x8a, 0xac, 0x22,
+    0x99, 0xd9, 0x6e, 0x3f, 0xed, 0x20, 0xfd, 0xdd, 0x95, 0xe2, 0x32, 0xa0, 0xeb, 0x23, 0xa2, 0xd2,
+    0x8b
+};
+
+static const uint8_t satori_priv[] = {
+    0x04, 0xe4, 0xef, 0x00, 0x27, 0xcb, 0xa6, 0x46,
+    0x0d, 0xa6, 0xbd, 0x77, 0x14, 0x65, 0xe5, 0x5a, 0x14, 0xc9, 0xf8, 0xd8, 0xdd, 0x4c, 0x70, 0x44,
+    0x50, 0x49, 0xe4, 0xfa, 0x24, 0x71, 0xaa, 0x4c, 0xe2, 0x74, 0x3b, 0xfd, 0x23, 0xda, 0x6f, 0x92,
+    0x04, 0x4c, 0x93, 0x6c, 0xea, 0x8a, 0xac, 0x22, 0x99, 0xd9, 0x6e, 0x3f, 0xed, 0x20, 0xfd, 0xdd,
+    0x95, 0xe2, 0x32, 0xa0, 0xeb, 0x23, 0xa2, 0xd2, 0x8b, 0x23, 0xcf, 0x74, 0xb4, 0x76, 0x93, 0xdf,
+    0x6d, 0x31, 0x63, 0xc9, 0x87, 0x85, 0x3f, 0x44, 0x09, 0x1f, 0x0d, 0xe2, 0x9a, 0x94, 0x29, 0x03,
+    0x70, 0xbf, 0x87, 0x2a, 0x7e, 0xac, 0xa8, 0x8d, 0x11,
+};
+
+static const uint8_t satori_test_cert[] = {
+    0x30, 0x82, 0x03, 0xf2, 0x30, 0x82, 0x03, 0x98, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x75,
+    0x0e, 0x97, 0x07, 0xb3, 0x6e, 0x48, 0xe9, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+    0x04, 0x03, 0x02, 0x30, 0x7f, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2a,
+    0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69,
+    0x6f, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03,
+    0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
+    0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+    0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70,
+    0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06,
+    0x13, 0x02, 0x55, 0x53, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x39, 0x32, 0x37, 0x31, 0x38,
+    0x33, 0x31, 0x30, 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x31, 0x30, 0x32, 0x36, 0x31, 0x38, 0x33,
+    0x31, 0x30, 0x37, 0x5a, 0x30, 0x73, 0x31, 0x17, 0x30, 0x15, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89,
+    0x93, 0xf2, 0x2c, 0x64, 0x01, 0x01, 0x0c, 0x07, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x31,
+    0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53,
+    0x50, 0x20, 0x4c, 0x65, 0x61, 0x66, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
+    0x19, 0x31, 0x2e, 0x32, 0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x31, 0x33, 0x36, 0x33, 0x35, 0x2e,
+    0x31, 0x30, 0x30, 0x2e, 0x36, 0x2e, 0x36, 0x34, 0x2e, 0x33, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03,
+    0x55, 0x04, 0x0a, 0x0c, 0x07, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x50, 0x31, 0x0b, 0x30, 0x09,
+    0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a,
+    0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
+    0x03, 0x42, 0x00, 0x04, 0xe4, 0xef, 0x00, 0x27, 0xcb, 0xa6, 0x46, 0x0d, 0xa6, 0xbd, 0x77, 0x14,
+    0x65, 0xe5, 0x5a, 0x14, 0xc9, 0xf8, 0xd8, 0xdd, 0x4c, 0x70, 0x44, 0x50, 0x49, 0xe4, 0xfa, 0x24,
+    0x71, 0xaa, 0x4c, 0xe2, 0x74, 0x3b, 0xfd, 0x23, 0xda, 0x6f, 0x92, 0x04, 0x4c, 0x93, 0x6c, 0xea,
+    0x8a, 0xac, 0x22, 0x99, 0xd9, 0x6e, 0x3f, 0xed, 0x20, 0xfd, 0xdd, 0x95, 0xe2, 0x32, 0xa0, 0xeb,
+    0x23, 0xa2, 0xd2, 0x8b, 0xa3, 0x82, 0x02, 0x08, 0x30, 0x82, 0x02, 0x04, 0x30, 0x0c, 0x06, 0x03,
+    0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+    0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb9, 0x04, 0x1a, 0x95, 0x5b, 0x6b, 0x91, 0x04, 0x39,
+    0xea, 0x70, 0x2a, 0x47, 0xb7, 0xa8, 0x49, 0x36, 0xe4, 0x4d, 0xdb, 0x30, 0x4d, 0x06, 0x08, 0x2b,
+    0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x41, 0x30, 0x3f, 0x30, 0x3d, 0x06, 0x08, 0x2b,
+    0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+    0x6f, 0x63, 0x73, 0x70, 0x2d, 0x75, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x61, 0x70,
+    0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x33, 0x2d, 0x74,
+    0x73, 0x61, 0x61, 0x69, 0x63, 0x61, 0x67, 0x33, 0x31, 0x30, 0x30, 0x82, 0x01, 0x03, 0x06, 0x03,
+    0x55, 0x1d, 0x20, 0x04, 0x81, 0xfb, 0x30, 0x81, 0xf8, 0x30, 0x81, 0xf5, 0x06, 0x09, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x63, 0x64, 0x05, 0x01, 0x30, 0x81, 0xe7, 0x30, 0x81, 0xac, 0x06, 0x08, 0x2b,
+    0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x81, 0x9f, 0x0c, 0x81, 0x9c, 0x52, 0x65, 0x6c,
+    0x69, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x62, 0x79, 0x20, 0x61, 0x6e, 0x79,
+    0x20, 0x70, 0x61, 0x72, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63,
+    0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x65, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2c, 0x20, 0x43, 0x65, 0x72,
+    0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x72, 0x61, 0x63, 0x74,
+    0x69, 0x63, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61,
+    0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x20,
+    0x61, 0x6e, 0x79, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61,
+    0x67, 0x72, 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x30, 0x36, 0x06, 0x08, 0x2b, 0x06, 0x01,
+    0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77,
+    0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74,
+    0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+    0x2f, 0x30, 0x3c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x35, 0x30, 0x33, 0x30, 0x31, 0xa0, 0x2f,
+    0xa0, 0x2d, 0x86, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2d, 0x75,
+    0x61, 0x74, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+    0x6d, 0x2f, 0x74, 0x73, 0x61, 0x61, 0x69, 0x63, 0x61, 0x67, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30,
+    0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa0, 0xe6, 0xdf, 0x03, 0xb1, 0x2a,
+    0x53, 0x40, 0x35, 0xc4, 0x01, 0x4b, 0x6a, 0xbd, 0x35, 0x8f, 0x6d, 0x28, 0x63, 0xba, 0x30, 0x0e,
+    0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x03, 0x28, 0x30, 0x10,
+    0x06, 0x0a, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x40, 0x03, 0x04, 0x02, 0x05, 0x00,
+    0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30,
+    0x45, 0x02, 0x20, 0x6a, 0x7e, 0xf1, 0x0b, 0x60, 0xba, 0x4c, 0x3c, 0x83, 0xd5, 0xbd, 0x4a, 0xb1,
+    0x62, 0x2f, 0x52, 0x92, 0xba, 0xb9, 0x64, 0xcd, 0xaa, 0x63, 0x96, 0xa6, 0xd8, 0x6d, 0x3a, 0xf3,
+    0x83, 0x81, 0xb9, 0x02, 0x21, 0x00, 0xc2, 0x37, 0x2d, 0x3a, 0xb7, 0x03, 0x81, 0x2f, 0x3e, 0xf1,
+    0x32, 0x98, 0x43, 0x27, 0xbb, 0x64, 0xbf, 0xfb, 0xb9, 0x9a, 0x0c, 0xad, 0x9a, 0x98, 0x6f, 0xbc,
+    0x87, 0x30, 0xfe, 0xfe, 0x3c, 0x2e, 0x30, 0x82, 0x03, 0x17, 0x30, 0x82, 0x02, 0x9e, 0xa0, 0x03,
+    0x02, 0x01, 0x02, 0x02, 0x08, 0x5b, 0x7d, 0xce, 0x90, 0x32, 0x77, 0x34, 0xd6, 0x30, 0x0a, 0x06,
+    0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03, 0x30, 0x6c, 0x31, 0x20, 0x30, 0x1e, 0x06,
+    0x03, 0x55, 0x04, 0x03, 0x0c, 0x17, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65,
+    0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x31, 0x26, 0x30,
+    0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65,
+    0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68,
+    0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a,
+    0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+    0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x35, 0x33,
+    0x30, 0x32, 0x31, 0x33, 0x35, 0x35, 0x35, 0x5a, 0x17, 0x0d, 0x33, 0x32, 0x30, 0x35, 0x32, 0x36,
+    0x32, 0x31, 0x33, 0x35, 0x35, 0x35, 0x5a, 0x30, 0x7f, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55,
+    0x04, 0x03, 0x0c, 0x2a, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x41,
+    0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x67,
+    0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x31, 0x26,
+    0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43,
+    0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+    0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
+    0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06,
+    0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
+    0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
+    0x42, 0x00, 0x04, 0xfa, 0xdc, 0xcc, 0x11, 0x10, 0x74, 0x7b, 0x30, 0xc4, 0x69, 0xdd, 0x65, 0xc3,
+    0xda, 0xa1, 0x55, 0xdf, 0xeb, 0x09, 0x5c, 0x29, 0xd0, 0x50, 0x3e, 0x1c, 0x0a, 0x34, 0xfa, 0x83,
+    0xb1, 0x79, 0x49, 0x4d, 0x9d, 0xb3, 0xb9, 0x46, 0xa1, 0xc9, 0x43, 0x67, 0xb3, 0x03, 0x45, 0xd3,
+    0xa4, 0x01, 0x60, 0xc3, 0x58, 0xdb, 0x98, 0x83, 0x19, 0x32, 0xce, 0xc5, 0xa3, 0x68, 0x38, 0xb6,
+    0xca, 0x4d, 0x63, 0xa3, 0x82, 0x01, 0x15, 0x30, 0x82, 0x01, 0x11, 0x30, 0x53, 0x06, 0x08, 0x2b,
+    0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x47, 0x30, 0x45, 0x30, 0x43, 0x06, 0x08, 0x2b,
+    0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x37, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
+    0x6f, 0x63, 0x73, 0x70, 0x2d, 0x75, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x61, 0x70,
+    0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x34, 0x2d, 0x74,
+    0x65, 0x73, 0x74, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, 0x67, 0x33,
+    0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb9, 0x04, 0x1a, 0x95, 0x5b,
+    0x6b, 0x91, 0x04, 0x39, 0xea, 0x70, 0x2a, 0x47, 0xb7, 0xa8, 0x49, 0x36, 0xe4, 0x4d, 0xdb, 0x30,
+    0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff,
+    0x02, 0x01, 0x00, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+    0xfc, 0x46, 0xd8, 0x83, 0x6c, 0x1f, 0xe6, 0xf2, 0xdc, 0xdf, 0xa7, 0x99, 0x17, 0xae, 0x0b, 0x44,
+    0x67, 0x17, 0x1b, 0x46, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30,
+    0x39, 0xa0, 0x37, 0xa0, 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72,
+    0x6c, 0x2d, 0x75, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65,
+    0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x72, 0x6f,
+    0x6f, 0x74, 0x63, 0x61, 0x67, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
+    0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x10, 0x06, 0x0a, 0x2a, 0x86,
+    0x48, 0x86, 0xf7, 0x63, 0x64, 0x06, 0x02, 0x0e, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0a, 0x06, 0x08,
+    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03, 0x03, 0x67, 0x00, 0x30, 0x64, 0x02, 0x30, 0x6a,
+    0x26, 0x0d, 0x2a, 0x80, 0xcd, 0x69, 0x33, 0xef, 0x50, 0xbb, 0x78, 0xbc, 0x17, 0x4c, 0xcd, 0xa6,
+    0x6b, 0x86, 0xe2, 0x86, 0xd3, 0xe7, 0x3d, 0xc3, 0x8f, 0x01, 0xd8, 0x83, 0xe6, 0xc8, 0x1c, 0x7d,
+    0xe7, 0x78, 0xca, 0xfd, 0x29, 0xd5, 0xfa, 0x32, 0x63, 0x98, 0xdb, 0x65, 0x17, 0x2e, 0x05, 0x02,
+    0x30, 0x4d, 0xd7, 0x31, 0x32, 0xfa, 0x17, 0x73, 0x50, 0x9c, 0xb6, 0x04, 0x1d, 0xca, 0xa6, 0x1f,
+    0x60, 0x0a, 0x72, 0x59, 0x6d, 0x7f, 0xc9, 0x5b, 0x93, 0x4a, 0x13, 0x40, 0x60, 0xae, 0x6c, 0x13,
+    0x43, 0xd2, 0x71, 0xc2, 0xdd, 0x32, 0xaa, 0x90, 0xa9, 0xc5, 0xe2, 0xdd, 0x32, 0x23, 0x2f, 0xaa,
+    0xda, 0x30, 0x82, 0x02, 0x4c, 0x30, 0x82, 0x01, 0xd3, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08,
+    0x78, 0x36, 0x0b, 0xf4, 0xb7, 0xc8, 0xb6, 0xb0, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
+    0x3d, 0x04, 0x03, 0x03, 0x30, 0x6c, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
+    0x17, 0x54, 0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74,
+    0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04,
+    0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79,
+    0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65,
+    0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
+    0x55, 0x53, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x34, 0x32, 0x32, 0x30, 0x33, 0x31, 0x37,
+    0x34, 0x34, 0x5a, 0x17, 0x0d, 0x34, 0x30, 0x31, 0x32, 0x32, 0x36, 0x30, 0x33, 0x31, 0x33, 0x33,
+    0x37, 0x5a, 0x30, 0x6c, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x17, 0x54,
+    0x65, 0x73, 0x74, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43,
+    0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c,
+    0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+    0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13,
+    0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
+    0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
+    0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b,
+    0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00, 0x04, 0xa9, 0x1a, 0x63, 0x34, 0xef, 0xbc, 0xa6, 0x8a,
+    0xd6, 0x2a, 0x6a, 0x38, 0x22, 0xe9, 0x25, 0xad, 0xda, 0x28, 0xa0, 0x49, 0xc5, 0x64, 0xfe, 0x5d,
+    0x91, 0xc3, 0x6c, 0xf7, 0x99, 0xe4, 0xba, 0xe4, 0x2a, 0x5f, 0x61, 0xd2, 0xbf, 0x3b, 0x6c, 0xa8,
+    0x61, 0x11, 0xb5, 0xe0, 0x66, 0xf7, 0x22, 0x11, 0x86, 0x97, 0x5d, 0xc3, 0xba, 0x1b, 0x6d, 0x55,
+    0x7f, 0xd0, 0xf9, 0x80, 0xe0, 0xff, 0xd9, 0x05, 0xad, 0x5a, 0x5b, 0xbf, 0x3a, 0x7a, 0xa7, 0x09,
+    0x52, 0x1a, 0x31, 0x7f, 0x0c, 0xa2, 0xe8, 0x10, 0xf5, 0x36, 0xd3, 0xc8, 0xea, 0xa0, 0x5b, 0x0a,
+    0x28, 0x85, 0x30, 0x28, 0x5f, 0x94, 0xf6, 0x94, 0xa3, 0x42, 0x30, 0x40, 0x30, 0x1d, 0x06, 0x03,
+    0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xfc, 0x46, 0xd8, 0x83, 0x6c, 0x1f, 0xe6, 0xf2, 0xdc,
+    0xdf, 0xa7, 0x99, 0x17, 0xae, 0x0b, 0x44, 0x67, 0x17, 0x1b, 0x46, 0x30, 0x0f, 0x06, 0x03, 0x55,
+    0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03,
+    0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08,
+    0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03, 0x03, 0x67, 0x00, 0x30, 0x64, 0x02, 0x30, 0x1a,
+    0x14, 0x38, 0x24, 0xff, 0xb4, 0x08, 0xcb, 0xea, 0xc9, 0x3b, 0xda, 0xcc, 0x82, 0xf3, 0xd9, 0x0d,
+    0xd1, 0x2b, 0x6e, 0xbf, 0x1f, 0xc4, 0x15, 0x14, 0x44, 0xdf, 0x98, 0x9b, 0xd7, 0xdd, 0xba, 0x1b,
+    0xbe, 0x4f, 0x9f, 0x17, 0xa4, 0xd2, 0x02, 0x75, 0x90, 0x7d, 0x76, 0xcc, 0x93, 0x16, 0x2f, 0x02,
+    0x30, 0x02, 0xd7, 0xda, 0x0b, 0xbe, 0xdd, 0x3d, 0xed, 0xf9, 0xa3, 0x06, 0x90, 0xa9, 0x58, 0xbd,
+    0x6b, 0x7c, 0x7c, 0xe5, 0xc5, 0x4e, 0x0e, 0x44, 0xa2, 0x94, 0x2f, 0xb4, 0x04, 0x9a, 0xcd, 0x9b,
+    0x69, 0x8d, 0x2a, 0xc6, 0x1d, 0x58, 0xff, 0xe3, 0x32, 0xb6, 0xdb, 0x3e, 0x34, 0xff, 0x67, 0x70,
+    0xf1
+};
+
+static void rewrapTest(void) {
+    id accessControl;
+    accessControl = CFBridgingRelease(SecAccessControlCreate(kCFAllocatorDefault, NULL));
+    SecAccessControlSetProtection((__bridge SecAccessControlRef)accessControl, kSecAttrAccessibleWhenUnlocked, NULL);
+    SecAccessControlSetConstraints((__bridge SecAccessControlRef)accessControl, (__bridge CFDictionaryRef)@{(id)kAKSKeyOpECIESTranscode: @YES});
+
+    NSDictionary *keyAttributes = @{ (id)kSecAttrTokenID : (id)kSecAttrTokenIDAppleKeyStore,
+                                     (id)kSecAttrKeyType : (id)kSecAttrKeyTypeECSECPrimeRandom,
+                                     (id)kSecKeyApplePayEnabled: @YES,
+                                     (id)kSecAttrAccessControl : accessControl,
+                                     (id)kSecAttrIsPermanent : @NO };
+    NSError *error;
+    id key = (__bridge_transfer id)SecKeyCreateRandomKey((CFDictionaryRef)keyAttributes, (void *)&error);
+    ok(key, "failed to create random key %@", error);
+
+    // Encrypt message with SEP key.
+    NSData *message = [@"message" dataUsingEncoding:NSUTF8StringEncoding];
+    id pubKey = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)key));
+    NSData *encrypted = CFBridgingRelease(SecKeyCreateEncryptedDataWithParameters((__bridge SecKeyRef)pubKey, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM, (__bridge CFDataRef)message, (__bridge CFDictionaryRef)@{(id)kSecKeyEncryptionParameterSymmetricKeySizeInBits: @256}, (void *)&error));
+    ok(encrypted, "failed to encrypt with public key, %@", error);
+    NSData *cert = [NSData dataWithBytes:satori_test_cert length:sizeof(satori_test_cert)];
+    NSDictionary *recryptParams = @{
+                                    (id)kSecKeyEncryptionParameterRecryptCertificate: cert,
+                                    (id)kSecKeyEncryptionParameterSymmetricKeySizeInBits: @256,
+                                    (id)kSecKeyEncryptionParameterRecryptParameters: @{
+                                            (id)kSecKeyEncryptionParameterSymmetricKeySizeInBits: @256
+                                            },
+                                    };
+    NSData *recrypted = CFBridgingRelease(SecKeyCreateDecryptedDataWithParameters((__bridge SecKeyRef)key, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM, (__bridge CFDataRef)encrypted, (__bridge CFDictionaryRef)recryptParams, (void *)&error));
+    ok(recrypted, "failed to recrypt, %@", error);
+
+    id recryptKey = CFBridgingRelease(SecKeyCreateWithData((CFDataRef)[NSData dataWithBytes:satori_priv length:sizeof(satori_priv)], (CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate}, (void *)&error));
+    NSData *decrypted = CFBridgingRelease(SecKeyCreateDecryptedDataWithParameters((__bridge SecKeyRef)recryptKey, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM, (__bridge CFDataRef)recrypted, (__bridge CFDictionaryRef)@{(id)kSecKeyEncryptionParameterSymmetricKeySizeInBits: @256}, (void *)&error));
+    ok(decrypted, "failed to decrypt, %@", error);
+    ok([decrypted isEqualToData:message], "Decrypted data differs: %@ vs %@", decrypted, message);
+}
+
 int si_44_seckey_aks(int argc, char *const *argv) {
     @autoreleasepool {
         BOOL testPKA = YES;
 int si_44_seckey_aks(int argc, char *const *argv) {
     @autoreleasepool {
         BOOL testPKA = YES;
@@ -196,10 +414,16 @@ int si_44_seckey_aks(int argc, char *const *argv) {
 
         testPKA = NO;
 #endif
 
         testPKA = NO;
 #endif
-        plan_tests(testPKA ? 95 : 80);
+        plan_tests(testPKA ? 100 : 85);
+
+        // Put SEP keys into test-keybag mode. Available only when running in direct-mode, not with extension.
+        SecKeySetParameter(NULL, kSecAttrTokenIDAppleKeyStore, kCFBooleanTrue, NULL);
+        rewrapTest();
+        SecKeySetParameter(NULL, kSecAttrTokenIDAppleKeyStore, kCFBooleanFalse, NULL);
+
         secKeySepTest(testPKA);
         secKeySepTest(testPKA);
-        attestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly);
-        attestationTest(kSecAttrAccessibleUntilReboot);
+        attestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, NO);
+        attestationTest(kSecAttrAccessibleUntilReboot, YES);
         return 0;
     }
 }
         return 0;
     }
 }
index 27980924832f1b905a11b0c14c5208ad9fd250ae..cb47776913519d584f6b23e4c7bd386ef70bf16f 100644 (file)
@@ -24,6 +24,7 @@
 
 #import <Foundation/Foundation.h>
 #import <Security/SecItemPriv.h>
 
 #import <Foundation/Foundation.h>
 #import <Security/SecItemPriv.h>
+#import <Security/SecKeyPriv.h>
 
 #import <corecrypto/ccrng.h>
 #import <corecrypto/ccsha1.h>
 
 #import <corecrypto/ccrng.h>
 #import <corecrypto/ccsha1.h>
@@ -48,14 +49,19 @@ static void test_ies_run(id privateKey, SecKeyAlgorithm algorithm) {
        "%@ not supported for encryption - privKey", algorithm);
 
     NSData *message = [NSData dataWithBytes:"hello" length:5];
        "%@ not supported for encryption - privKey", algorithm);
 
     NSData *message = [NSData dataWithBytes:"hello" length:5];
+    NSDictionary *sharedInfo = @{(id)kSecKeyKeyExchangeParameterSharedInfo :[NSData dataWithBytes:"shared" length:6]};
     error = nil;
     NSData *encrypted = CFBridgingRelease(SecKeyCreateEncryptedData((SecKeyRef)publicKey, algorithm, (CFDataRef)message, (void *)&error));
     error = nil;
     NSData *encrypted = CFBridgingRelease(SecKeyCreateEncryptedData((SecKeyRef)publicKey, algorithm, (CFDataRef)message, (void *)&error));
+    NSData *encryptedSI = CFBridgingRelease(SecKeyCreateEncryptedDataWithParameters((__bridge SecKeyRef)publicKey, algorithm, (__bridge CFDataRef)message, (__bridge CFDictionaryRef)sharedInfo, (void *)&error));
     ok(encrypted, "message encrypted");
 
     error = nil;
     NSData *decrypted = CFBridgingRelease(SecKeyCreateDecryptedData((SecKeyRef)privateKey, algorithm, (CFDataRef)encrypted, (void *)&error));
     ok(decrypted, "encrypted message decrypted");
     ok([decrypted isEqual:message], "decrypted message is equal as original one (original:%@ decrypted:%@)", message, decrypted);
     ok(encrypted, "message encrypted");
 
     error = nil;
     NSData *decrypted = CFBridgingRelease(SecKeyCreateDecryptedData((SecKeyRef)privateKey, algorithm, (CFDataRef)encrypted, (void *)&error));
     ok(decrypted, "encrypted message decrypted");
     ok([decrypted isEqual:message], "decrypted message is equal as original one (original:%@ decrypted:%@)", message, decrypted);
+    NSData *decryptedSI = CFBridgingRelease(SecKeyCreateDecryptedDataWithParameters((__bridge SecKeyRef)privateKey, algorithm, (__bridge CFDataRef)encryptedSI, (__bridge CFDictionaryRef)sharedInfo, (void *)&error));
+    ok(decryptedSI, "encrypted-with-sharedinfo message decrypted: %@", error);
+    ok([decryptedSI isEqual:message], "decrypted-with-sharedinfo message is equal as original one (original:%@ decrypted:%@)", message, decryptedSI);
 
     // Modify encrypted message and verify that it cannot be decrypted.
     NSMutableData *badEncrypted = [NSMutableData dataWithData:encrypted];
 
     // Modify encrypted message and verify that it cannot be decrypted.
     NSMutableData *badEncrypted = [NSMutableData dataWithData:encrypted];
@@ -90,7 +96,7 @@ static void test_ies_run(id privateKey, SecKeyAlgorithm algorithm) {
     decrypted = CFBridgingRelease(SecKeyCreateDecryptedData((SecKeyRef)privateKey, algorithm, (CFDataRef)badEncrypted, (void *)&error));
     ok(decrypted == nil, "broken encrypted message failed to decrypt (pubkey data breakage)");
 }
     decrypted = CFBridgingRelease(SecKeyCreateDecryptedData((SecKeyRef)privateKey, algorithm, (CFDataRef)badEncrypted, (void *)&error));
     ok(decrypted == nil, "broken encrypted message failed to decrypt (pubkey data breakage)");
 }
-static const int TestCountIESRun = 12;
+static const int TestCountIESRun = 14;
 
 static void test_ecies() {
     NSError *error;
 
 static void test_ecies() {
     NSError *error;
@@ -170,6 +176,30 @@ static void test_ies_against_corecrypto(id privKey, ccec_const_cp_t cp, const st
     // SecKey encrypt -> cc decrypt.
     static const UInt8 knownPlaintext[] = "KNOWN PLAINTEXT";
     NSData *plaintext = [NSData dataWithBytes:knownPlaintext length:sizeof(knownPlaintext)];
     // SecKey encrypt -> cc decrypt.
     static const UInt8 knownPlaintext[] = "KNOWN PLAINTEXT";
     NSData *plaintext = [NSData dataWithBytes:knownPlaintext length:sizeof(knownPlaintext)];
+    static const UInt8 knownSharedInfo[] = "SHARED INFO";
+    NSData *sharedInfo = [NSData dataWithBytes:knownSharedInfo length:sizeof(knownSharedInfo)];
+    static const UInt8 knownSharedInfo2[] = "2SHARED INFO2";
+    NSData *sharedInfo2 = [NSData dataWithBytes:knownSharedInfo2 length:sizeof(knownSharedInfo2)];
+    NSMutableDictionary *parameters = @{(id)kSecKeyKeyExchangeParameterSharedInfo: sharedInfo,
+                                        (id)kSecKeyEncryptionParameterSymmetricAAD: sharedInfo2,
+                                        }.mutableCopy;
+
+    static int keyCounter = 0;
+    keyCounter++;
+    uint32_t ccKeySizeSI = ccKeySize;
+    switch (keyCounter % 3) {
+        case 0:
+            break;
+        case 1:
+            ccKeySizeSI = 16;
+            parameters[(id)kSecKeyEncryptionParameterSymmetricKeySizeInBits] = @(ccKeySizeSI * 8);
+            break;
+        case 2:
+            ccKeySizeSI = 32;
+            parameters[(id)kSecKeyEncryptionParameterSymmetricKeySizeInBits] = @(ccKeySizeSI * 8);
+            break;
+    }
+
     error = nil;
     id publicKey = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)privKey));
     NSData *ciphertext = CFBridgingRelease(SecKeyCreateEncryptedData((SecKeyRef)publicKey, algorithm, (CFDataRef)plaintext, (void *)&error));
     error = nil;
     id publicKey = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)privKey));
     NSData *ciphertext = CFBridgingRelease(SecKeyCreateEncryptedData((SecKeyRef)publicKey, algorithm, (CFDataRef)plaintext, (void *)&error));
@@ -179,13 +209,22 @@ static void test_ies_against_corecrypto(id privKey, ccec_const_cp_t cp, const st
                               ECIES_EPH_PUBKEY_IN_SHAREDINFO1 | ECIES_EXPORT_PUB_STANDARD | (secureIV ? 0 : ECIES_LEGACY_IV));
     size_t decryptedLength = plaintext.length;
     NSMutableData *decrypted = [NSMutableData dataWithLength:decryptedLength];
                               ECIES_EPH_PUBKEY_IN_SHAREDINFO1 | ECIES_EXPORT_PUB_STANDARD | (secureIV ? 0 : ECIES_LEGACY_IV));
     size_t decryptedLength = plaintext.length;
     NSMutableData *decrypted = [NSMutableData dataWithLength:decryptedLength];
-    if (ciphertext != nil) {
-        ok(ccecies_decrypt_gcm(fullkey, &ecies_dec, ciphertext.length, ciphertext.bytes, 0, NULL, 0, NULL,
-                               &decryptedLength, decrypted.mutableBytes) == 0, "decrypt data with cc failed");
-    }
+    ok(ccecies_decrypt_gcm(fullkey, &ecies_dec, ciphertext.length, ciphertext.bytes, 0, NULL, 0, NULL,
+                           &decryptedLength, decrypted.mutableBytes) == 0, "decrypt data with cc failed");
     ok(decryptedLength = plaintext.length);
     ok([plaintext isEqualToData:decrypted], "cc decrypted data are the same");
 
     ok(decryptedLength = plaintext.length);
     ok([plaintext isEqualToData:decrypted], "cc decrypted data are the same");
 
+    NSData *ciphertextSI = CFBridgingRelease(SecKeyCreateEncryptedDataWithParameters((__bridge SecKeyRef)publicKey, algorithm, (__bridge CFDataRef)plaintext, (__bridge CFDictionaryRef)parameters, (void *)&error));
+    ok(ciphertextSI != nil, "encrypt-with-sharedinfo data with SecKey (error %@)", error);
+    struct ccecies_gcm ecies_dec_SI;
+    ccecies_decrypt_gcm_setup(&ecies_dec_SI, di, ccaes_gcm_decrypt_mode(), ccKeySizeSI, 16,
+                              ECIES_EPH_PUBKEY_AND_SHAREDINFO1 | ECIES_EXPORT_PUB_STANDARD | (secureIV ? 0 : ECIES_LEGACY_IV));
+    NSMutableData *decryptedSI = [NSMutableData dataWithLength:decryptedLength];
+    ok(ccecies_decrypt_gcm(fullkey, &ecies_dec_SI, ciphertextSI.length, ciphertextSI.bytes, sizeof(knownSharedInfo), knownSharedInfo,
+                           sizeof(knownSharedInfo2), knownSharedInfo2, &decryptedLength, decryptedSI.mutableBytes) == 0, "decrypt-with-sharedinfo data with cc failed");
+    ok(decryptedLength = plaintext.length);
+    ok([plaintext isEqualToData:decryptedSI], "cc decrypted-with-sharedinfo data are the same");
+
     // cc encrypt -> SecKey decrypt
     struct ccecies_gcm ecies_enc;
     ccecies_encrypt_gcm_setup(&ecies_enc, di, ccrng(NULL), ccaes_gcm_encrypt_mode(), ccKeySize, 16,
     // cc encrypt -> SecKey decrypt
     struct ccecies_gcm ecies_enc;
     ccecies_encrypt_gcm_setup(&ecies_enc, di, ccrng(NULL), ccaes_gcm_encrypt_mode(), ccKeySize, 16,
@@ -197,8 +236,17 @@ static void test_ies_against_corecrypto(id privKey, ccec_const_cp_t cp, const st
     NSData *decryptedPlaintext = CFBridgingRelease(SecKeyCreateDecryptedData((SecKeyRef)privKey, algorithm, (CFDataRef)encrypted, (void *)&error));
     ok(decryptedPlaintext != nil, "decrypt data with SecKey (error %@)", error);
     ok([plaintext isEqualToData:decryptedPlaintext], "SecKey decrypted data are the same");
     NSData *decryptedPlaintext = CFBridgingRelease(SecKeyCreateDecryptedData((SecKeyRef)privKey, algorithm, (CFDataRef)encrypted, (void *)&error));
     ok(decryptedPlaintext != nil, "decrypt data with SecKey (error %@)", error);
     ok([plaintext isEqualToData:decryptedPlaintext], "SecKey decrypted data are the same");
+
+    struct ccecies_gcm ecies_enc_SI;
+    ccecies_encrypt_gcm_setup(&ecies_enc_SI, di, ccrng(NULL), ccaes_gcm_encrypt_mode(), ccKeySizeSI, 16,
+                              ECIES_EPH_PUBKEY_AND_SHAREDINFO1 | ECIES_EXPORT_PUB_STANDARD | (secureIV ? 0 : ECIES_LEGACY_IV));
+    NSMutableData *encryptedSI = [NSMutableData dataWithLength:encryptedLength];
+    ok(ccecies_encrypt_gcm(ccec_ctx_pub(fullkey), &ecies_enc_SI, sizeof(knownPlaintext), knownPlaintext, sizeof(knownSharedInfo), knownSharedInfo, sizeof(knownSharedInfo2), knownSharedInfo2, &encryptedLength, encryptedSI.mutableBytes) == 0, "encrypt-with-sharedinfo data with cc failed");
+    NSData *decryptedPlaintextSI = CFBridgingRelease(SecKeyCreateDecryptedDataWithParameters((__bridge SecKeyRef)privKey, algorithm, (__bridge CFDataRef)encryptedSI, (__bridge CFDictionaryRef)parameters, (void *)&error));
+    ok(decryptedPlaintextSI != nil, "decrypt-with-sharedinfo data with SecKey (error %@)", error);
+    ok([plaintext isEqualToData:decryptedPlaintextSI], "SecKey decrypted-with-sharedinfo data are the same");
 }
 }
-static const int TestCountIESAgainstCoreCryptoRun = 9;
+static const int TestCountIESAgainstCoreCryptoRun = 16;
 
 static void test_against_corecrypto() {
     id privKey;
 
 static void test_against_corecrypto() {
     id privKey;
index 355148964c06a9c8bb965ec63a0925e3f09ef36f..10ae842412409c1ac08e282365d3ffc29a594dc8 100644 (file)
@@ -674,6 +674,7 @@ static void test_enforcement(void) {
     SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
     NSArray *anchors = nil, *keychain_certs = nil;
     NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
     SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com"));
     NSArray *anchors = nil, *keychain_certs = nil;
     NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT
+    NSDate *expiredDate = [NSDate dateWithTimeIntervalSinceReferenceDate:570000000.0]; // January 24, 2019 at 12:20:00 AM EST
     CFErrorRef error = nil;
     CFDataRef exceptions = nil;
 
     CFErrorRef error = nil;
     CFDataRef exceptions = nil;
 
@@ -713,6 +714,11 @@ static void test_enforcement(void) {
         fail("expected trust evaluation to fail and it did not.");
     }
 
         fail("expected trust evaluation to fail and it did not.");
     }
 
+    // test expired system cert after date without CT passes with only expiration error
+    require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)expiredDate), errOut, fail("failed to set verify date"));
+    ok(SecTrustIsExpiredOnly(trust), "expired system post-flag-date non-CT cert had non-expiration errors");
+    require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date"));
+
     // test exceptions for failing cert passes
     exceptions = SecTrustCopyExceptions(trust);
     ok(SecTrustSetExceptions(trust, exceptions), "failed to set exceptions for failing non-CT cert");
     // test exceptions for failing cert passes
     exceptions = SecTrustCopyExceptions(trust);
     ok(SecTrustSetExceptions(trust, exceptions), "failed to set exceptions for failing non-CT cert");
@@ -1421,7 +1427,7 @@ static void test_ct_exceptions(void) {
 
 int si_82_sectrust_ct(int argc, char *const *argv)
 {
 
 int si_82_sectrust_ct(int argc, char *const *argv)
 {
-       plan_tests(432);
+       plan_tests(433);
 
        tests();
     test_sct_serialization();
 
        tests();
     test_sct_serialization();
index f19f5413548b7078540110c3647cacc47ada2d08..4260ed2107393e5abdd6593baf5f7c8dc89cfcc8 100644 (file)
@@ -795,7 +795,7 @@ static sqlite3 *_SecDbOpenV2(const char *path,
     } else if (SQLITE_OPEN_READWRITE == (flags & SQLITE_OPEN_READWRITE)) {
         if (useRobotVacuum) {
 #define SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL 2
     } else if (SQLITE_OPEN_READWRITE == (flags & SQLITE_OPEN_READWRITE)) {
         if (useRobotVacuum) {
 #define SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL 2
-            sqlite3_stmt *stmt;
+            sqlite3_stmt *stmt = NULL;
             int vacuumMode = -1;
 
             /*
             int vacuumMode = -1;
 
             /*
@@ -812,6 +812,7 @@ static sqlite3 *_SecDbOpenV2(const char *path,
                 }
                 sqlite3_reset(stmt);
             }
                 }
                 sqlite3_reset(stmt);
             }
+            sqlite3_finalize(stmt);
 
             if (vacuumMode != SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL) {
                 (void)sqlite3_exec(handle, "PRAGMA auto_vacuum = incremental", NULL, NULL, NULL);
 
             if (vacuumMode != SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL) {
                 (void)sqlite3_exec(handle, "PRAGMA auto_vacuum = incremental", NULL, NULL, NULL);
@@ -1284,7 +1285,10 @@ SecDbConnectionDestroy(CFTypeRef value)
 {
     SecDbConnectionRef dbconn = (SecDbConnectionRef)value;
     if (dbconn->handle) {
 {
     SecDbConnectionRef dbconn = (SecDbConnectionRef)value;
     if (dbconn->handle) {
-        sqlite3_close(dbconn->handle);
+        int s3e = sqlite3_close(dbconn->handle);
+        if (s3e != SQLITE_OK) {
+            secerror("failed to close database connection (%d) for %@: %s", s3e, dbconn->db->db_path, sqlite3_errmsg(dbconn->handle));
+        }
     }
     dbconn->db = NULL;
     CFReleaseNull(dbconn->changes);
     }
     dbconn->db = NULL;
     CFReleaseNull(dbconn->changes);
index 8490084d2d27a7ea761bb2d788ded47dcb6f75ee..dd545ec2c1c1296e31c2aad5b2cbc83e9a9c5f61 100644 (file)
@@ -108,41 +108,20 @@ static bool OSX_AddKeyValuePairToKeychainLoggingTransaction(void *token, CFStrin
        msgtracer_msg_t msg = instance->message;
        
        // Fix up the key
        msgtracer_msg_t msg = instance->message;
        
        // Fix up the key
-       CFStringRef real_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s%@"), gMessageTracerSetPrefix, key);
+       __block char *real_key = NULL;
+       CFStringPerformWithCString(key, ^(const char *key_utf8) {
+               asprintf(&real_key, "%s%s", gMessageTracerSetPrefix, key_utf8);
+       });
        if (NULL == real_key)
        {
                return false;
        }
        
        if (NULL == real_key)
        {
                return false;
        }
        
-       CFIndex key_length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(real_key), kCFStringEncodingUTF8);
-    key_length += 1; // For null
-    char key_buffer[key_length];
-    memset(key_buffer, 0, key_length);
-    if (!CFStringGetCString(real_key, key_buffer, key_length, kCFStringEncodingUTF8))
-    {
-        CFRelease(real_key);
-        return false;
-    }
-       CFRelease(real_key);
-       
-       CFStringRef value_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%lld"), value);
-    if (NULL == value_str)
-    {
-        return false;
-    }
+       char value_buffer[32];
+       snprintf(value_buffer, sizeof(value_buffer), "%lld", value);
 
 
-    CFIndex value_str_numBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value_str), kCFStringEncodingUTF8);
-    value_str_numBytes += 1; // For null
-    char value_buffer[value_str_numBytes];
-    memset(value_buffer, 0, value_str_numBytes);
-    if (!CFStringGetCString(value_str, value_buffer, value_str_numBytes, kCFStringEncodingUTF8))
-    {
-        CFRelease(value_str);
-        return false;
-    }
-    CFRelease(value_str);
-
-    msgtracer_set(msg, key_buffer, value_buffer);
+       msgtracer_set(msg, real_key, value_buffer);
+       free(real_key);
        return true;    
 }
 
        return true;    
 }
 
@@ -198,47 +177,23 @@ static bool OSX_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value)
     }
 
     // Fix up the key
     }
 
     // Fix up the key
-       CFStringRef real_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s%@"), gMessageTracerSetPrefix, key);
+       __block char *real_key = NULL;
+       CFStringPerformWithCString(key, ^(const char *key_utf8) {
+               asprintf(&real_key, "%s%s", gMessageTracerSetPrefix, key_utf8);
+       });
        if (NULL == real_key)
        {
                return false;
        }
        
        if (NULL == real_key)
        {
                return false;
        }
        
-       CFIndex key_length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(real_key), kCFStringEncodingUTF8);
-    key_length += 1; // For null
-    char key_buffer[key_length];
-    memset(key_buffer, 0,key_length);
-    if (!CFStringGetCString(real_key, key_buffer, key_length, kCFStringEncodingUTF8))
-    {
-        CFRelease(real_key);
-        return false;
-    }
-       CFRelease(real_key);
-       
-       
-       CFStringRef value_str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%lld"), value);
-    if (NULL == value_str)
-    {
-        msgtracer_msg_free(message);
-        return result;
-    }
-   
-    CFIndex value_str_numBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value_str), kCFStringEncodingUTF8);
-    value_str_numBytes += 1; // For null
-    char value_buffer[value_str_numBytes];
-    memset(value_buffer, 0, value_str_numBytes);
-    if (!CFStringGetCString(value_str, value_buffer, value_str_numBytes, kCFStringEncodingUTF8))
-    {
-        msgtracer_msg_free(message);
-        CFRelease(value_str);
-        return result;
-    }
-    CFRelease(value_str);
+       char value_buffer[32];
+       snprintf(value_buffer, sizeof(value_buffer), "%lld", value);
 
 
-    msgtracer_set(message, key_buffer, value_buffer);
-       msgtracer_log(message, ASL_LEVEL_NOTICE, "%s is %lld", key_buffer, value);
+    msgtracer_set(message, real_key, value_buffer);
+       msgtracer_log(message, ASL_LEVEL_NOTICE, "%s is %lld", real_key, value);
     msgtracer_msg_free(message);
     msgtracer_domain_free(domain);
     msgtracer_msg_free(message);
     msgtracer_domain_free(domain);
+    free(real_key);
        return true;
        
 }
        return true;
        
 }
index 9ffdcdaab3b9325f1fcf2bf87e98c8febf7a6930..b4dab54e45809ab8c6f7656eefc59e21b4e07892 100644 (file)
@@ -355,6 +355,7 @@ _SecPKCS12Import
 _SecRandomCopyBytes
 _SecSHA1DigestCreate
 _SecTaskCopySigningIdentifier
 _SecRandomCopyBytes
 _SecSHA1DigestCreate
 _SecTaskCopySigningIdentifier
+_SecTaskCopyTeamIdentifier
 _SecTaskCopyValueForEntitlement
 _SecTaskCopyValuesForEntitlements
 _SecTaskCreateFromSelf
 _SecTaskCopyValueForEntitlement
 _SecTaskCopyValuesForEntitlements
 _SecTaskCreateFromSelf
@@ -1474,6 +1475,7 @@ _SecCodeSetStatus
 _SecCodeCopyStaticCode
 _SecCodeCopyHost
 _SecCodeCopyGuestWithAttributes
 _SecCodeCopyStaticCode
 _SecCodeCopyHost
 _SecCodeCopyGuestWithAttributes
+_SecCodeCreateWithAuditToken
 _SecCodeCreateWithPID
 _SecCodeCheckValidity
 _SecCodeCheckValidityWithErrors
 _SecCodeCreateWithPID
 _SecCodeCheckValidity
 _SecCodeCheckValidityWithErrors
@@ -1524,6 +1526,9 @@ _kSecCodeSignerApplicationData
 _kSecCodeSignerDetached
 _kSecCodeSignerDigestAlgorithm
 _kSecCodeSignerDryRun
 _kSecCodeSignerDetached
 _kSecCodeSignerDigestAlgorithm
 _kSecCodeSignerDryRun
+_kSecCodeSignerEditCMS
+_kSecCodeSignerEditCpuSubtype
+_kSecCodeSignerEditCpuType
 _kSecCodeSignerEntitlements
 _kSecCodeSignerFlags
 _kSecCodeSignerIdentifier
 _kSecCodeSignerEntitlements
 _kSecCodeSignerFlags
 _kSecCodeSignerIdentifier
@@ -1540,12 +1545,17 @@ _kSecCodeSignerTeamIdentifier
 _kSecCodeSignerPlatformIdentifier
 _kSecCodeSignerRuntimeVersion
 _kSecCodeSignerPreserveAFSC
 _kSecCodeSignerPlatformIdentifier
 _kSecCodeSignerRuntimeVersion
 _kSecCodeSignerPreserveAFSC
+_kSecCodeSignerOmitAdhocFlag
 _kSecCodeSignerTimestampServer
 _kSecCodeSignerTimestampAuthentication
 _kSecCodeSignerTimestampOmitCertificates
 _kSecCodeSignerTimestampServer
 _kSecCodeSignerTimestampAuthentication
 _kSecCodeSignerTimestampOmitCertificates
+_kSecCodeInfoCdHashes
+_kSecCodeInfoCdHashesFull
 _kSecCodeInfoCertificates
 _kSecCodeInfoChangedFiles
 _kSecCodeInfoCMS
 _kSecCodeInfoCertificates
 _kSecCodeInfoChangedFiles
 _kSecCodeInfoCMS
+_kSecCodeInfoCMSDigest
+_kSecCodeInfoCMSDigestHashType
 _kSecCodeInfoTime
 _kSecCodeInfoTimestamp
 _kSecCodeInfoDesignatedRequirement
 _kSecCodeInfoTime
 _kSecCodeInfoTimestamp
 _kSecCodeInfoDesignatedRequirement
@@ -1567,7 +1577,6 @@ _kSecCodeInfoStatus
 _kSecCodeInfoTeamIdentifier
 _kSecCodeInfoTrust
 _kSecCodeInfoUnique
 _kSecCodeInfoTeamIdentifier
 _kSecCodeInfoTrust
 _kSecCodeInfoUnique
-_kSecCodeInfoCdHashes
 _kSecCodeInfoRuntimeVersion
 _kSecCodeInfoCodeDirectory
 _kSecCodeInfoCodeOffset
 _kSecCodeInfoRuntimeVersion
 _kSecCodeInfoCodeDirectory
 _kSecCodeInfoCodeOffset
@@ -1706,7 +1715,10 @@ _kSecCodeAttributeArchitecture
 _kSecCodeAttributeBundleVersion
 _kSecCodeAttributeSubarchitecture
 _kSecCodeInfoCMS
 _kSecCodeAttributeBundleVersion
 _kSecCodeAttributeSubarchitecture
 _kSecCodeInfoCMS
+_kSecCodeInfoCMSDigest
+_kSecCodeInfoCMSDigestHashType
 _kSecCodeInfoCdHashes
 _kSecCodeInfoCdHashes
+_kSecCodeInfoCdHashesFull
 _kSecCodeInfoChangedFiles
 _kSecCodeInfoCodeDirectory
 _kSecCodeInfoCodeOffset
 _kSecCodeInfoChangedFiles
 _kSecCodeInfoCodeDirectory
 _kSecCodeInfoCodeOffset
index b3e41b60e886842db66447f8bd46e72dcbea787f..0f7c78848645df1d7c02009209d20dcbab67ef6c 100644 (file)
 /* Begin PBXBuildFile section */
                091B39732063B67700ECAB6F /* RemoteServiceDiscovery.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 091B396D2063B64A00ECAB6F /* RemoteServiceDiscovery.framework */; };
                0927FEBC1F81338600864E07 /* SecKeyProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */; };
 /* Begin PBXBuildFile section */
                091B39732063B67700ECAB6F /* RemoteServiceDiscovery.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 091B396D2063B64A00ECAB6F /* RemoteServiceDiscovery.framework */; };
                0927FEBC1F81338600864E07 /* SecKeyProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */; };
+               0940F6F82151316500C06F18 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; };
+               0940F6F92151316600C06F18 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; };
                096C647020AB1BC700D7B7D5 /* KeychainEntitlementsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */; };
                09A3B9D81F8267BB00C5C324 /* SecKeyProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
                09A3B9D91F8267BB00C5C324 /* SecKeyProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
                096C647020AB1BC700D7B7D5 /* KeychainEntitlementsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */; };
                09A3B9D81F8267BB00C5C324 /* SecKeyProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
                09A3B9D91F8267BB00C5C324 /* SecKeyProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
                09A3B9E21F838A3400C5C324 /* SecKeyProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */; };
                09BFE35C20A32E0E008511E9 /* KeychainEntitlementsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */; };
                09CB49701F2F64E300C8E4DE /* si-44-seckey-fv.m in Sources */ = {isa = PBXBuildFile; fileRef = 09CB496A1F2F64AF00C8E4DE /* si-44-seckey-fv.m */; };
                09A3B9E21F838A3400C5C324 /* SecKeyProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */; };
                09BFE35C20A32E0E008511E9 /* KeychainEntitlementsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */; };
                09CB49701F2F64E300C8E4DE /* si-44-seckey-fv.m in Sources */ = {isa = PBXBuildFile; fileRef = 09CB496A1F2F64AF00C8E4DE /* si-44-seckey-fv.m */; };
+               09EF431B21A5A8CC0066CF20 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
                0C0582AE20D9657800D7BD7A /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; };
                0C0582B820D9B70D00D7BD7A /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; };
                0C0BDB32175685B000BC1A7E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C0BDB31175685B000BC1A7E /* main.m */; };
                0C0582AE20D9657800D7BD7A /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; };
                0C0582B820D9B70D00D7BD7A /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; };
                0C0BDB32175685B000BC1A7E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C0BDB31175685B000BC1A7E /* main.m */; };
                0C85DFF61FB38BB6000343A7 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246CE1F9AEAE300D63882 /* libDER.a */; };
                0C85DFF71FB38BB6000343A7 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; };
                0C85DFF81FB38BB6000343A7 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
                0C85DFF61FB38BB6000343A7 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246CE1F9AEAE300D63882 /* libDER.a */; };
                0C85DFF71FB38BB6000343A7 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; };
                0C85DFF81FB38BB6000343A7 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
-               0C85DFF91FB38BB6000343A7 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
+               0C85DFF91FB38BB6000343A7 /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; };
                0C85DFFA1FB38BB6000343A7 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; };
                0C85DFFB1FB38BB6000343A7 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; };
                0C85DFFE1FB38BB6000343A7 /* OCMock.framework in Embed OCMock */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
                0C85DFFA1FB38BB6000343A7 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; };
                0C85DFFB1FB38BB6000343A7 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; };
                0C85DFFE1FB38BB6000343A7 /* OCMock.framework in Embed OCMock */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
                443381ED18A3D83100215606 /* SecAccessControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 443381D918A3D81400215606 /* SecAccessControl.h */; settings = {ATTRIBUTES = (Public, ); }; };
                443381EE18A3D83A00215606 /* SecAccessControlPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 443381DA18A3D81400215606 /* SecAccessControlPriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4469FBFF1AA0A4820021AA26 /* libctkclient_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDC1AA0A45C0021AA26 /* libctkclient_test.a */; };
                443381ED18A3D83100215606 /* SecAccessControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 443381D918A3D81400215606 /* SecAccessControl.h */; settings = {ATTRIBUTES = (Public, ); }; };
                443381EE18A3D83A00215606 /* SecAccessControlPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 443381DA18A3D81400215606 /* SecAccessControlPriv.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4469FBFF1AA0A4820021AA26 /* libctkclient_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDC1AA0A45C0021AA26 /* libctkclient_test.a */; };
-               44A655831AA4B4BB0059D185 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
-               44A655A51AA4B4C70059D185 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
-               44A655A61AA4B4C80059D185 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
+               44A655831AA4B4BB0059D185 /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; };
+               44A655A51AA4B4C70059D185 /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; };
+               44A655A61AA4B4C80059D185 /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; };
                470415DC1E5E1534001F3D95 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 470415DB1E5E1534001F3D95 /* main.m */; };
                470D96711FCDE55B0065FE90 /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; };
                470D96721FCDE55B0065FE90 /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; };
                470415DC1E5E1534001F3D95 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 470415DB1E5E1534001F3D95 /* main.m */; };
                470D96711FCDE55B0065FE90 /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; };
                470D96721FCDE55B0065FE90 /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; };
                6C9808571E788AEB00E70590 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
                6C9808581E788AEB00E70590 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; };
                6C9808591E788AEB00E70590 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
                6C9808571E788AEB00E70590 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
                6C9808581E788AEB00E70590 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; };
                6C9808591E788AEB00E70590 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
-               6C98085A1E788AEB00E70590 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
+               6C98085A1E788AEB00E70590 /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; };
                6C98085B1E788AEB00E70590 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; };
                6C98085C1E788AEB00E70590 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; };
                6C98087A1E788AFD00E70590 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; };
                6C98085B1E788AEB00E70590 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; };
                6C98085C1E788AEB00E70590 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; };
                6C98087A1E788AFD00E70590 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; };
                6C9808931E788AFD00E70590 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
                6C9808941E788AFD00E70590 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; };
                6C9808951E788AFD00E70590 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
                6C9808931E788AFD00E70590 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
                6C9808941E788AFD00E70590 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; };
                6C9808951E788AFD00E70590 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
-               6C9808961E788AFD00E70590 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
+               6C9808961E788AFD00E70590 /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; };
                6C9808971E788AFD00E70590 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; };
                6C9808981E788AFD00E70590 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; };
                6C9808A51E788CD100E70590 /* CKKSCloudKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CCDF7911E3C2D69003F2555 /* CKKSCloudKitTests.m */; };
                6C9808A61E788CD200E70590 /* CKKSCloudKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CCDF7911E3C2D69003F2555 /* CKKSCloudKitTests.m */; };
                6C9AA7A11F7C1D9000D08296 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C9AA7A01F7C1D9000D08296 /* main.m */; };
                6C9AA7A51F7C6F7F00D08296 /* SecArgParse.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5BCC461E5380EA00649140 /* SecArgParse.c */; };
                6C9808971E788AFD00E70590 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; };
                6C9808981E788AFD00E70590 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; };
                6C9808A51E788CD100E70590 /* CKKSCloudKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CCDF7911E3C2D69003F2555 /* CKKSCloudKitTests.m */; };
                6C9808A61E788CD200E70590 /* CKKSCloudKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CCDF7911E3C2D69003F2555 /* CKKSCloudKitTests.m */; };
                6C9AA7A11F7C1D9000D08296 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C9AA7A01F7C1D9000D08296 /* main.m */; };
                6C9AA7A51F7C6F7F00D08296 /* SecArgParse.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5BCC461E5380EA00649140 /* SecArgParse.c */; };
+               6CA837642210CA8A002770F1 /* kc-45-change-password.c in Sources */ = {isa = PBXBuildFile; fileRef = 6CA837612210C5E7002770F1 /* kc-45-change-password.c */; };
                6CAA8CDD1F82EDEF007B6E03 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; };
                6CAA8CEE1F83E417007B6E03 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; };
                6CAA8CEF1F83E65D007B6E03 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; };
                6CAA8CDD1F82EDEF007B6E03 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; };
                6CAA8CEE1F83E417007B6E03 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; };
                6CAA8CEF1F83E65D007B6E03 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; };
                DC1789251D7799CD00B50D50 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; };
                DC1789271D7799D400B50D50 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789261D7799D300B50D50 /* IOKit.framework */; };
                DC1789281D779A0F00B50D50 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
                DC1789251D7799CD00B50D50 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; };
                DC1789271D7799D400B50D50 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789261D7799D300B50D50 /* IOKit.framework */; };
                DC1789281D779A0F00B50D50 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
-               DC1789291D779A2800B50D50 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
+               DC1789291D779A2800B50D50 /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; };
                DC17892A1D779A3200B50D50 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
                DC1789471D779AAF00B50D50 /* libsecurity_smime.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1784491D77869A00B50D50 /* libsecurity_smime.a */; };
                DC1789A21D779DF400B50D50 /* SecBreadcrumb.c in Sources */ = {isa = PBXBuildFile; fileRef = DC1789A01D779DEE00B50D50 /* SecBreadcrumb.c */; };
                DC17892A1D779A3200B50D50 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
                DC1789471D779AAF00B50D50 /* libsecurity_smime.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1784491D77869A00B50D50 /* libsecurity_smime.a */; };
                DC1789A21D779DF400B50D50 /* SecBreadcrumb.c in Sources */ = {isa = PBXBuildFile; fileRef = DC1789A01D779DEE00B50D50 /* SecBreadcrumb.c */; };
                DC3502D31E02115200BC0587 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; };
                DC3502D61E02118000BC0587 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; };
                DC3502DF1E02129F00BC0587 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
                DC3502D31E02115200BC0587 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; };
                DC3502D61E02118000BC0587 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; };
                DC3502DF1E02129F00BC0587 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; };
-               DC3502E21E0212D100BC0587 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
+               DC3502E21E0212D100BC0587 /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; };
                DC3502E31E0212E600BC0587 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; };
                DC3502E41E02130600BC0587 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
                DC3502E71E0214C800BC0587 /* MockCloudKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502E61E0214C800BC0587 /* MockCloudKit.m */; };
                DC3502E31E0212E600BC0587 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; };
                DC3502E41E02130600BC0587 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
                DC3502E71E0214C800BC0587 /* MockCloudKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502E61E0214C800BC0587 /* MockCloudKit.m */; };
                DC52EE711D80D85F00B0A59C /* SecECKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.m */; };
                DC52EE721D80D86400B0A59C /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; };
                DC52EE731D80D86800B0A59C /* SecKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.c */; };
                DC52EE711D80D85F00B0A59C /* SecECKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.m */; };
                DC52EE721D80D86400B0A59C /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; };
                DC52EE731D80D86800B0A59C /* SecKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.c */; };
-               DC52EE741D80D86F00B0A59C /* SecAccessControl.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E301D8085FC00865A7C /* SecAccessControl.c */; };
+               DC52EE741D80D86F00B0A59C /* SecAccessControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E301D8085FC00865A7C /* SecAccessControl.m */; };
                DC52EE761D80D87F00B0A59C /* SecCTKKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.m */; };
                DC52EE771D80D88300B0A59C /* SecDH.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E461D8085FC00865A7C /* SecDH.c */; };
                DC52EE781D80D88800B0A59C /* SecRSAKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E851D8085FC00865A7C /* SecRSAKey.c */; };
                DC52EE761D80D87F00B0A59C /* SecCTKKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.m */; };
                DC52EE771D80D88300B0A59C /* SecDH.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E461D8085FC00865A7C /* SecDH.c */; };
                DC52EE781D80D88800B0A59C /* SecRSAKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E851D8085FC00865A7C /* SecRSAKey.c */; };
                DCC78EE31D808B1300865A7C /* SecCMS.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E421D8085FC00865A7C /* SecCMS.c */; };
                DCC78EE41D808B1B00865A7C /* SecCFAllocator.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E401D8085FC00865A7C /* SecCFAllocator.c */; };
                DCC78EE51D808B2100865A7C /* SecBase64.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E351D8085FC00865A7C /* SecBase64.c */; };
                DCC78EE31D808B1300865A7C /* SecCMS.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E421D8085FC00865A7C /* SecCMS.c */; };
                DCC78EE41D808B1B00865A7C /* SecCFAllocator.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E401D8085FC00865A7C /* SecCFAllocator.c */; };
                DCC78EE51D808B2100865A7C /* SecBase64.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E351D8085FC00865A7C /* SecBase64.c */; };
-               DCC78EE61D808B2A00865A7C /* SecAccessControl.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E301D8085FC00865A7C /* SecAccessControl.c */; };
+               DCC78EE61D808B2A00865A7C /* SecAccessControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E301D8085FC00865A7C /* SecAccessControl.m */; };
                DCC78EE71D808B2F00865A7C /* secViewDisplay.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D9E1D8085F200865A7C /* secViewDisplay.c */; };
                DCCA5E841E539EE7009EE93D /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCCA5E831E539EE7009EE93D /* AppKit.framework */; };
                DCCBFA1E1DBA95CD001DD54D /* kc-20-item-delete-stress.c in Sources */ = {isa = PBXBuildFile; fileRef = DCCBFA1D1DBA95CD001DD54D /* kc-20-item-delete-stress.c */; };
                DCC78EE71D808B2F00865A7C /* secViewDisplay.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D9E1D8085F200865A7C /* secViewDisplay.c */; };
                DCCA5E841E539EE7009EE93D /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCCA5E831E539EE7009EE93D /* AppKit.framework */; };
                DCCBFA1E1DBA95CD001DD54D /* kc-20-item-delete-stress.c in Sources */ = {isa = PBXBuildFile; fileRef = DCCBFA1D1DBA95CD001DD54D /* kc-20-item-delete-stress.c */; };
                DCE4E8121D7A4E4F00AFB96E /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789261D7799D300B50D50 /* IOKit.framework */; };
                DCE4E8131D7A4E5300AFB96E /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; };
                DCE4E81C1D7A4E8F00AFB96E /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E81B1D7A4E8F00AFB96E /* libsqlite3.0.dylib */; };
                DCE4E8121D7A4E4F00AFB96E /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789261D7799D300B50D50 /* IOKit.framework */; };
                DCE4E8131D7A4E5300AFB96E /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; };
                DCE4E81C1D7A4E8F00AFB96E /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E81B1D7A4E8F00AFB96E /* libsqlite3.0.dylib */; };
-               DCE4E81F1D7A4EA700AFB96E /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
+               DCE4E81F1D7A4EA700AFB96E /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; };
                DCE4E8201D7A4EAC00AFB96E /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
                DCE4E8231D7A4EC900AFB96E /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
                DCE4E8241D7A4ECD00AFB96E /* libaks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EB2CA4D81D2C28C800AB770F /* libaks.a */; };
                DCE4E8201D7A4EAC00AFB96E /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
                DCE4E8231D7A4EC900AFB96E /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
                DCE4E8241D7A4ECD00AFB96E /* libaks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EB2CA4D81D2C28C800AB770F /* libaks.a */; };
                EBCE16501FE6DE5A002E7CCC /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
                EBCE16511FE6DE5A002E7CCC /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; };
                EBCE16521FE6DE5A002E7CCC /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
                EBCE16501FE6DE5A002E7CCC /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; };
                EBCE16511FE6DE5A002E7CCC /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; };
                EBCE16521FE6DE5A002E7CCC /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; };
-               EBCE16531FE6DE5A002E7CCC /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; };
+               EBCE16531FE6DE5A002E7CCC /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; };
                EBCE16541FE6DE5A002E7CCC /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; };
                EBCE16551FE6DE5A002E7CCC /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; };
                EBCE16561FE6DE5A002E7CCC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; };
                EBCE16541FE6DE5A002E7CCC /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; };
                EBCE16551FE6DE5A002E7CCC /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; };
                EBCE16561FE6DE5A002E7CCC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; };
                443381D918A3D81400215606 /* SecAccessControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecAccessControl.h; path = ../../../keychain/SecAccessControl.h; sourceTree = "<group>"; };
                443381DA18A3D81400215606 /* SecAccessControlPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecAccessControlPriv.h; sourceTree = "<group>"; };
                4469FBDC1AA0A45C0021AA26 /* libctkclient_test.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libctkclient_test.a; path = usr/local/lib/libctkclient_test.a; sourceTree = SDKROOT; };
                443381D918A3D81400215606 /* SecAccessControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecAccessControl.h; path = ../../../keychain/SecAccessControl.h; sourceTree = "<group>"; };
                443381DA18A3D81400215606 /* SecAccessControlPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecAccessControlPriv.h; sourceTree = "<group>"; };
                4469FBDC1AA0A45C0021AA26 /* libctkclient_test.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libctkclient_test.a; path = usr/local/lib/libctkclient_test.a; sourceTree = SDKROOT; };
-               4469FBDD1AA0A45C0021AA26 /* libctkclient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libctkclient.a; path = usr/local/lib/libctkclient.a; sourceTree = SDKROOT; };
+               4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libctkclient_sep.a; path = usr/local/lib/libctkclient_sep.a; sourceTree = SDKROOT; };
                470415CF1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = seckeychainnetworkextensionstest; sourceTree = BUILT_PRODUCTS_DIR; };
                470415DB1E5E1534001F3D95 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RegressionTests/seckeychainnetworkextensionstest/main.m; sourceTree = SOURCE_ROOT; };
                470415DD1E5E15B3001F3D95 /* seckeychainnetworkextensionstest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = seckeychainnetworkextensionstest.entitlements; path = RegressionTests/seckeychainnetworkextensionstest/seckeychainnetworkextensionstest.entitlements; sourceTree = SOURCE_ROOT; };
                470415CF1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = seckeychainnetworkextensionstest; sourceTree = BUILT_PRODUCTS_DIR; };
                470415DB1E5E1534001F3D95 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RegressionTests/seckeychainnetworkextensionstest/main.m; sourceTree = SOURCE_ROOT; };
                470415DD1E5E15B3001F3D95 /* seckeychainnetworkextensionstest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = seckeychainnetworkextensionstest.entitlements; path = RegressionTests/seckeychainnetworkextensionstest/seckeychainnetworkextensionstest.entitlements; sourceTree = SOURCE_ROOT; };
                6C9AA79E1F7C1D8F00D08296 /* supdctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = supdctl; sourceTree = BUILT_PRODUCTS_DIR; };
                6C9AA7A01F7C1D9000D08296 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
                6CA2B9431E9F9F5700C43444 /* RateLimiter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RateLimiter.h; sourceTree = "<group>"; };
                6C9AA79E1F7C1D8F00D08296 /* supdctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = supdctl; sourceTree = BUILT_PRODUCTS_DIR; };
                6C9AA7A01F7C1D9000D08296 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
                6CA2B9431E9F9F5700C43444 /* RateLimiter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RateLimiter.h; sourceTree = "<group>"; };
+               6CA557FE219E214200993CF4 /* securityuploadd-sim.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "securityuploadd-sim.plist"; sourceTree = "<group>"; };
+               6CA837612210C5E7002770F1 /* kc-45-change-password.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "kc-45-change-password.c"; path = "regressions/kc-45-change-password.c"; sourceTree = "<group>"; };
                6CAA8D201F842FB3007B6E03 /* securityuploadd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = securityuploadd; sourceTree = BUILT_PRODUCTS_DIR; };
                6CB5F4751E4025AB00DBF3F0 /* CKKSCloudKitTestsInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = CKKSCloudKitTestsInfo.plist; sourceTree = "<group>"; };
                6CB5F4781E402E5700DBF3F0 /* KeychainCKKS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = KeychainCKKS.plist; path = testrunner/KeychainCKKS.plist; sourceTree = "<group>"; };
                6CAA8D201F842FB3007B6E03 /* securityuploadd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = securityuploadd; sourceTree = BUILT_PRODUCTS_DIR; };
                6CB5F4751E4025AB00DBF3F0 /* CKKSCloudKitTestsInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = CKKSCloudKitTestsInfo.plist; sourceTree = "<group>"; };
                6CB5F4781E402E5700DBF3F0 /* KeychainCKKS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = KeychainCKKS.plist; path = testrunner/KeychainCKKS.plist; sourceTree = "<group>"; };
                DC3A4B581D91E9FB00E46D4A /* com.apple.CodeSigningHelper.xpc */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = com.apple.CodeSigningHelper.xpc; sourceTree = BUILT_PRODUCTS_DIR; };
                DC3A4B5F1D91EAC500E46D4A /* CodeSigningHelper-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "CodeSigningHelper-Info.plist"; sourceTree = "<group>"; };
                DC3A4B601D91EAC500E46D4A /* com.apple.CodeSigningHelper.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.CodeSigningHelper.sb; sourceTree = "<group>"; };
                DC3A4B581D91E9FB00E46D4A /* com.apple.CodeSigningHelper.xpc */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = com.apple.CodeSigningHelper.xpc; sourceTree = BUILT_PRODUCTS_DIR; };
                DC3A4B5F1D91EAC500E46D4A /* CodeSigningHelper-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "CodeSigningHelper-Info.plist"; sourceTree = "<group>"; };
                DC3A4B601D91EAC500E46D4A /* com.apple.CodeSigningHelper.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.CodeSigningHelper.sb; sourceTree = "<group>"; };
-               DC3A4B621D91EAC500E46D4A /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
+               DC3A4B621D91EAC500E46D4A /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; usesTabs = 1; };
                DC3A81D41D99D567000C7419 /* libcoretls_cfhelpers.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcoretls_cfhelpers.dylib; path = usr/lib/libcoretls_cfhelpers.dylib; sourceTree = SDKROOT; };
                DC3D748A1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSLocalSynchronizeOperation.h; sourceTree = "<group>"; };
                DC3D748B1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSLocalSynchronizeOperation.m; sourceTree = "<group>"; };
                DC3A81D41D99D567000C7419 /* libcoretls_cfhelpers.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcoretls_cfhelpers.dylib; path = usr/lib/libcoretls_cfhelpers.dylib; sourceTree = SDKROOT; };
                DC3D748A1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSLocalSynchronizeOperation.h; sourceTree = "<group>"; };
                DC3D748B1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSLocalSynchronizeOperation.m; sourceTree = "<group>"; };
                DC5ABF7F1D83511A00CF422C /* key.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = key.h; sourceTree = "<group>"; };
                DC5ABF801D83511A00CF422C /* key.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = key.cpp; sourceTree = "<group>"; };
                DC5ABF811D83511A00CF422C /* process.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = process.h; sourceTree = "<group>"; };
                DC5ABF7F1D83511A00CF422C /* key.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = key.h; sourceTree = "<group>"; };
                DC5ABF801D83511A00CF422C /* key.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = key.cpp; sourceTree = "<group>"; };
                DC5ABF811D83511A00CF422C /* process.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = process.h; sourceTree = "<group>"; };
-               DC5ABF821D83511A00CF422C /* process.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = process.cpp; sourceTree = "<group>"; };
+               DC5ABF821D83511A00CF422C /* process.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = process.cpp; sourceTree = "<group>"; usesTabs = 1; };
                DC5ABF831D83511A00CF422C /* server.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = server.h; sourceTree = "<group>"; };
                DC5ABF841D83511A00CF422C /* server.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = server.cpp; sourceTree = "<group>"; };
                DC5ABF851D83511A00CF422C /* session.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session.h; sourceTree = "<group>"; };
                DC5ABF831D83511A00CF422C /* server.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = server.h; sourceTree = "<group>"; };
                DC5ABF841D83511A00CF422C /* server.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = server.cpp; sourceTree = "<group>"; };
                DC5ABF851D83511A00CF422C /* session.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = session.h; sourceTree = "<group>"; };
                DC5ABFB91D83511A00CF422C /* authhost.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = authhost.cpp; sourceTree = "<group>"; };
                DC5ABFBA1D83511A00CF422C /* credential.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = credential.h; sourceTree = "<group>"; };
                DC5ABFBB1D83511A00CF422C /* credential.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = credential.cpp; sourceTree = "<group>"; };
                DC5ABFB91D83511A00CF422C /* authhost.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = authhost.cpp; sourceTree = "<group>"; };
                DC5ABFBA1D83511A00CF422C /* credential.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = credential.h; sourceTree = "<group>"; };
                DC5ABFBB1D83511A00CF422C /* credential.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = credential.cpp; sourceTree = "<group>"; };
-               DC5ABFBD1D83511A00CF422C /* clientid.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = clientid.h; sourceTree = "<group>"; };
+               DC5ABFBD1D83511A00CF422C /* clientid.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = clientid.h; sourceTree = "<group>"; usesTabs = 1; };
                DC5ABFBE1D83511A00CF422C /* clientid.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = clientid.cpp; sourceTree = "<group>"; };
                DC5ABFBF1D83511A00CF422C /* codesigdb.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = codesigdb.h; sourceTree = "<group>"; };
                DC5ABFC01D83511A00CF422C /* codesigdb.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = codesigdb.cpp; sourceTree = "<group>"; };
                DC5ABFBE1D83511A00CF422C /* clientid.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = clientid.cpp; sourceTree = "<group>"; };
                DC5ABFBF1D83511A00CF422C /* codesigdb.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = codesigdb.h; sourceTree = "<group>"; };
                DC5ABFC01D83511A00CF422C /* codesigdb.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = codesigdb.cpp; sourceTree = "<group>"; };
                DCC78E2A1D8085FC00865A7C /* p12import.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = p12import.c; sourceTree = "<group>"; };
                DCC78E2C1D8085FC00865A7C /* p12pbegen.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = p12pbegen.c; sourceTree = "<group>"; };
                DCC78E2E1D8085FC00865A7C /* pbkdf2.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pbkdf2.c; sourceTree = "<group>"; };
                DCC78E2A1D8085FC00865A7C /* p12import.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = p12import.c; sourceTree = "<group>"; };
                DCC78E2C1D8085FC00865A7C /* p12pbegen.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = p12pbegen.c; sourceTree = "<group>"; };
                DCC78E2E1D8085FC00865A7C /* pbkdf2.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pbkdf2.c; sourceTree = "<group>"; };
-               DCC78E301D8085FC00865A7C /* SecAccessControl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecAccessControl.c; sourceTree = "<group>"; };
+               DCC78E301D8085FC00865A7C /* SecAccessControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecAccessControl.m; sourceTree = "<group>"; };
                DCC78E321D8085FC00865A7C /* SecAccessControlExports.exp-in */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SecAccessControlExports.exp-in"; sourceTree = "<group>"; };
                DCC78E351D8085FC00865A7C /* SecBase64.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecBase64.c; sourceTree = "<group>"; };
                DCC78E381D8085FC00865A7C /* SecCertificate.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCertificate.c; sourceTree = "<group>"; };
                DCC78E321D8085FC00865A7C /* SecAccessControlExports.exp-in */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SecAccessControlExports.exp-in"; sourceTree = "<group>"; };
                DCC78E351D8085FC00865A7C /* SecBase64.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecBase64.c; sourceTree = "<group>"; };
                DCC78E381D8085FC00865A7C /* SecCertificate.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCertificate.c; sourceTree = "<group>"; };
                DCD067DF1D8CDF7E007602F1 /* singlediskrep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = singlediskrep.cpp; sourceTree = "<group>"; };
                DCD067E01D8CDF7E007602F1 /* detachedrep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detachedrep.h; sourceTree = "<group>"; };
                DCD067E11D8CDF7E007602F1 /* detachedrep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detachedrep.cpp; sourceTree = "<group>"; };
                DCD067DF1D8CDF7E007602F1 /* singlediskrep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = singlediskrep.cpp; sourceTree = "<group>"; };
                DCD067E01D8CDF7E007602F1 /* detachedrep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = detachedrep.h; sourceTree = "<group>"; };
                DCD067E11D8CDF7E007602F1 /* detachedrep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detachedrep.cpp; sourceTree = "<group>"; };
-               DCD067E21D8CDF7E007602F1 /* piddiskrep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = piddiskrep.h; sourceTree = "<group>"; };
-               DCD067E31D8CDF7E007602F1 /* piddiskrep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = piddiskrep.cpp; sourceTree = "<group>"; };
+               DCD067E21D8CDF7E007602F1 /* piddiskrep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = piddiskrep.h; sourceTree = "<group>"; usesTabs = 0; };
+               DCD067E31D8CDF7E007602F1 /* piddiskrep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = piddiskrep.cpp; sourceTree = "<group>"; usesTabs = 1; };
                DCD067E71D8CDF7E007602F1 /* SecCodeHostLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCodeHostLib.h; sourceTree = "<group>"; };
                DCD067E81D8CDF7E007602F1 /* SecCodeHostLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCodeHostLib.c; sourceTree = "<group>"; };
                DCD067EA1D8CDF7E007602F1 /* sp-watch.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; name = "sp-watch.d"; path = "../dtrace/sp-watch.d"; sourceTree = "<group>"; };
                DCD067E71D8CDF7E007602F1 /* SecCodeHostLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCodeHostLib.h; sourceTree = "<group>"; };
                DCD067E81D8CDF7E007602F1 /* SecCodeHostLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCodeHostLib.c; sourceTree = "<group>"; };
                DCD067EA1D8CDF7E007602F1 /* sp-watch.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; name = "sp-watch.d"; path = "../dtrace/sp-watch.d"; sourceTree = "<group>"; };
                F6A0971F1E953ABD00B1E7D6 /* authdtests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = authdtests.m; path = OSX/authd/tests/authdtests.m; sourceTree = "<group>"; };
                F6A3CB0D1E7062BA00E7821F /* authd-Entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "authd-Entitlements.plist"; path = "OSX/authd/authd-Entitlements.plist"; sourceTree = "<group>"; };
                F93C493A1AB8FF530047E01A /* ckcdiagnose.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ckcdiagnose.sh; sourceTree = "<group>"; };
                F6A0971F1E953ABD00B1E7D6 /* authdtests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = authdtests.m; path = OSX/authd/tests/authdtests.m; sourceTree = "<group>"; };
                F6A3CB0D1E7062BA00E7821F /* authd-Entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "authd-Entitlements.plist"; path = "OSX/authd/authd-Entitlements.plist"; sourceTree = "<group>"; };
                F93C493A1AB8FF530047E01A /* ckcdiagnose.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ckcdiagnose.sh; sourceTree = "<group>"; };
+               F9B458272183E01100F6BCEB /* SignatureEditing.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = SignatureEditing.sh; path = OSX/codesign_tests/SignatureEditing.sh; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
                                0C85DFF71FB38BB6000343A7 /* libbsm.dylib in Frameworks */,
                                D491116E209559510066A1E4 /* CoreData.framework in Frameworks */,
                                0C85DFF81FB38BB6000343A7 /* libcoreauthd_client.a in Frameworks */,
                                0C85DFF71FB38BB6000343A7 /* libbsm.dylib in Frameworks */,
                                D491116E209559510066A1E4 /* CoreData.framework in Frameworks */,
                                0C85DFF81FB38BB6000343A7 /* libcoreauthd_client.a in Frameworks */,
-                               0C85DFF91FB38BB6000343A7 /* libctkclient.a in Frameworks */,
+                               0C85DFF91FB38BB6000343A7 /* libctkclient_sep.a in Frameworks */,
                                0C85DFFA1FB38BB6000343A7 /* libsqlite3.0.dylib in Frameworks */,
                                0C85DFFB1FB38BB6000343A7 /* libz.dylib in Frameworks */,
                        );
                                0C85DFFA1FB38BB6000343A7 /* libsqlite3.0.dylib in Frameworks */,
                                0C85DFFB1FB38BB6000343A7 /* libz.dylib in Frameworks */,
                        );
                                0C78F1D016A5E3EB00654E08 /* libbsm.dylib in Frameworks */,
                                D46246971F9AE2E400D63882 /* libDER.a in Frameworks */,
                                DCD22D771D8CC9CD001C9B81 /* libASN1_not_installed.a in Frameworks */,
                                0C78F1D016A5E3EB00654E08 /* libbsm.dylib in Frameworks */,
                                D46246971F9AE2E400D63882 /* libDER.a in Frameworks */,
                                DCD22D771D8CC9CD001C9B81 /* libASN1_not_installed.a in Frameworks */,
-                               44A655831AA4B4BB0059D185 /* libctkclient.a in Frameworks */,
+                               44A655831AA4B4BB0059D185 /* libctkclient_sep.a in Frameworks */,
                                DC59E9A41D91C6F0001BDDF5 /* libCMS.a in Frameworks */,
                                DCD22D781D8CC9D8001C9B81 /* libsecurity_ssl.a in Frameworks */,
                                CD791B3D1DFC9AB200F0E5DC /* libsqlite3.dylib in Frameworks */,
                                DC59E9A41D91C6F0001BDDF5 /* libCMS.a in Frameworks */,
                                DCD22D781D8CC9D8001C9B81 /* libsecurity_ssl.a in Frameworks */,
                                CD791B3D1DFC9AB200F0E5DC /* libsqlite3.dylib in Frameworks */,
                                4432AF8D1A01472C000958DC /* libaks_acl.a in Frameworks */,
                                438166ED1B4ECF9400C54D58 /* CoreFoundation.framework in Frameworks */,
                                4CAF67AC0F3A70220064A534 /* IOKit.framework in Frameworks */,
                                4432AF8D1A01472C000958DC /* libaks_acl.a in Frameworks */,
                                438166ED1B4ECF9400C54D58 /* CoreFoundation.framework in Frameworks */,
                                4CAF67AC0F3A70220064A534 /* IOKit.framework in Frameworks */,
+                               0940F6F82151316500C06F18 /* libACM.a in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                DCD22D9C1D8CCFD6001C9B81 /* libutilitiesRegressions.a in Frameworks */,
                                DC00ABB71D821E2F00513D74 /* libiOSSecurityRegressions.a in Frameworks */,
                                DC00ABB81D821E3300513D74 /* libiOSsecuritydRegressions.a in Frameworks */,
                                DCD22D9C1D8CCFD6001C9B81 /* libutilitiesRegressions.a in Frameworks */,
                                DC00ABB71D821E2F00513D74 /* libiOSSecurityRegressions.a in Frameworks */,
                                DC00ABB81D821E3300513D74 /* libiOSsecuritydRegressions.a in Frameworks */,
-                               44A655A61AA4B4C80059D185 /* libctkclient.a in Frameworks */,
+                               44A655A61AA4B4C80059D185 /* libctkclient_sep.a in Frameworks */,
                                DC00ABB91D821E3A00513D74 /* libSOSRegressions.a in Frameworks */,
                                4C711D6C13AFCD0900FE865D /* libsqlite3.dylib in Frameworks */,
                                BE405EE31DC2F11E00E227B1 /* libz.dylib in Frameworks */,
                                DC00ABB91D821E3A00513D74 /* libSOSRegressions.a in Frameworks */,
                                4C711D6C13AFCD0900FE865D /* libsqlite3.dylib in Frameworks */,
                                BE405EE31DC2F11E00E227B1 /* libz.dylib in Frameworks */,
                                6C9808571E788AEB00E70590 /* libaks_acl.a in Frameworks */,
                                6C9808581E788AEB00E70590 /* libbsm.dylib in Frameworks */,
                                6C9808591E788AEB00E70590 /* libcoreauthd_client.a in Frameworks */,
                                6C9808571E788AEB00E70590 /* libaks_acl.a in Frameworks */,
                                6C9808581E788AEB00E70590 /* libbsm.dylib in Frameworks */,
                                6C9808591E788AEB00E70590 /* libcoreauthd_client.a in Frameworks */,
-                               6C98085A1E788AEB00E70590 /* libctkclient.a in Frameworks */,
+                               6C98085A1E788AEB00E70590 /* libctkclient_sep.a in Frameworks */,
                                6C98085B1E788AEB00E70590 /* libsqlite3.0.dylib in Frameworks */,
                                6C98085C1E788AEB00E70590 /* libz.dylib in Frameworks */,
                        );
                                6C98085B1E788AEB00E70590 /* libsqlite3.0.dylib in Frameworks */,
                                6C98085C1E788AEB00E70590 /* libz.dylib in Frameworks */,
                        );
                                6C9808931E788AFD00E70590 /* libaks_acl.a in Frameworks */,
                                6C9808941E788AFD00E70590 /* libbsm.dylib in Frameworks */,
                                6C9808951E788AFD00E70590 /* libcoreauthd_client.a in Frameworks */,
                                6C9808931E788AFD00E70590 /* libaks_acl.a in Frameworks */,
                                6C9808941E788AFD00E70590 /* libbsm.dylib in Frameworks */,
                                6C9808951E788AFD00E70590 /* libcoreauthd_client.a in Frameworks */,
-                               6C9808961E788AFD00E70590 /* libctkclient.a in Frameworks */,
+                               6C9808961E788AFD00E70590 /* libctkclient_sep.a in Frameworks */,
                                6C9808971E788AFD00E70590 /* libsqlite3.0.dylib in Frameworks */,
                                6C9808981E788AFD00E70590 /* libz.dylib in Frameworks */,
                        );
                                6C9808971E788AFD00E70590 /* libsqlite3.0.dylib in Frameworks */,
                                6C9808981E788AFD00E70590 /* libz.dylib in Frameworks */,
                        );
                                DC17892A1D779A3200B50D50 /* libcoreauthd_client.a in Frameworks */,
                                DC3A81D61D99D57F000C7419 /* libcoretls.dylib in Frameworks */,
                                DC3A81D71D99D58A000C7419 /* libcoretls_cfhelpers.dylib in Frameworks */,
                                DC17892A1D779A3200B50D50 /* libcoreauthd_client.a in Frameworks */,
                                DC3A81D61D99D57F000C7419 /* libcoretls.dylib in Frameworks */,
                                DC3A81D71D99D58A000C7419 /* libcoretls_cfhelpers.dylib in Frameworks */,
-                               DC1789291D779A2800B50D50 /* libctkclient.a in Frameworks */,
+                               DC1789291D779A2800B50D50 /* libctkclient_sep.a in Frameworks */,
                                D46246C91F9AEA5300D63882 /* libDER.a in Frameworks */,
                                DC17891D1D77999700B50D50 /* libpam.dylib in Frameworks */,
                                DC17891F1D77999D00B50D50 /* libsqlite3.dylib in Frameworks */,
                                D46246C91F9AEA5300D63882 /* libDER.a in Frameworks */,
                                DC17891D1D77999700B50D50 /* libpam.dylib in Frameworks */,
                                DC17891F1D77999D00B50D50 /* libsqlite3.dylib in Frameworks */,
                                DC1789231D7799A600B50D50 /* libz.dylib in Frameworks */,
                                DC1789251D7799CD00B50D50 /* CoreFoundation.framework in Frameworks */,
                                DC1789271D7799D400B50D50 /* IOKit.framework in Frameworks */,
                                DC1789231D7799A600B50D50 /* libz.dylib in Frameworks */,
                                DC1789251D7799CD00B50D50 /* CoreFoundation.framework in Frameworks */,
                                DC1789271D7799D400B50D50 /* IOKit.framework in Frameworks */,
+                               0940F6F92151316600C06F18 /* libACM.a in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                DC0950411E38271300B2C8AC /* libaks_acl.a in Frameworks */,
                                DC222C361E02419B00B09171 /* libbsm.dylib in Frameworks */,
                                DC3502E41E02130600BC0587 /* libcoreauthd_client.a in Frameworks */,
                                DC0950411E38271300B2C8AC /* libaks_acl.a in Frameworks */,
                                DC222C361E02419B00B09171 /* libbsm.dylib in Frameworks */,
                                DC3502E41E02130600BC0587 /* libcoreauthd_client.a in Frameworks */,
-                               DC3502E21E0212D100BC0587 /* libctkclient.a in Frameworks */,
+                               DC3502E21E0212D100BC0587 /* libctkclient_sep.a in Frameworks */,
                                DC3502CA1E020DC100BC0587 /* libsqlite3.0.dylib in Frameworks */,
                                DC222C321E0240D300B09171 /* libz.dylib in Frameworks */,
                        );
                                DC3502CA1E020DC100BC0587 /* libsqlite3.0.dylib in Frameworks */,
                                DC222C321E0240D300B09171 /* libz.dylib in Frameworks */,
                        );
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
                        isa = PBXFrameworksBuildPhase;
                        buildActionMask = 2147483647;
                        files = (
+                               09EF431B21A5A8CC0066CF20 /* libaks_acl.a in Frameworks */,
                                D4C6C5CD1FB3B423007EA57E /* libarchive.tbd in Frameworks */,
                                D46246B71F9AE76500D63882 /* libDER.a in Frameworks */,
                                DC3A81EC1D99F568000C7419 /* libcoretls.dylib in Frameworks */,
                                D4C6C5CD1FB3B423007EA57E /* libarchive.tbd in Frameworks */,
                                D46246B71F9AE76500D63882 /* libDER.a in Frameworks */,
                                DC3A81EC1D99F568000C7419 /* libcoretls.dylib in Frameworks */,
                                DCE4E8231D7A4EC900AFB96E /* libaks_acl.a in Frameworks */,
                                DCD22D711D8CC78E001C9B81 /* libASN1_not_installed.a in Frameworks */,
                                DCE4E8201D7A4EAC00AFB96E /* libcoreauthd_client.a in Frameworks */,
                                DCE4E8231D7A4EC900AFB96E /* libaks_acl.a in Frameworks */,
                                DCD22D711D8CC78E001C9B81 /* libASN1_not_installed.a in Frameworks */,
                                DCE4E8201D7A4EAC00AFB96E /* libcoreauthd_client.a in Frameworks */,
-                               DCE4E81F1D7A4EA700AFB96E /* libctkclient.a in Frameworks */,
+                               DCE4E81F1D7A4EA700AFB96E /* libctkclient_sep.a in Frameworks */,
                                DCE4E81C1D7A4E8F00AFB96E /* libsqlite3.0.dylib in Frameworks */,
                                DCD8A2041E09FB0D00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */,
                                DC00AB7A1D821C6B00513D74 /* libSecureObjectSyncServer.a in Frameworks */,
                                DCE4E81C1D7A4E8F00AFB96E /* libsqlite3.0.dylib in Frameworks */,
                                DCD8A2041E09FB0D00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */,
                                DC00AB7A1D821C6B00513D74 /* libSecureObjectSyncServer.a in Frameworks */,
                                DCD22D951D8CCE5E001C9B81 /* libutilitiesRegressions.a in Frameworks */,
                                DC00ABC41D821ED900513D74 /* libiOSSecurityRegressions.a in Frameworks */,
                                DC00ABC51D821EDC00513D74 /* libiOSsecuritydRegressions.a in Frameworks */,
                                DCD22D951D8CCE5E001C9B81 /* libutilitiesRegressions.a in Frameworks */,
                                DC00ABC41D821ED900513D74 /* libiOSSecurityRegressions.a in Frameworks */,
                                DC00ABC51D821EDC00513D74 /* libiOSsecuritydRegressions.a in Frameworks */,
-                               44A655A51AA4B4C70059D185 /* libctkclient.a in Frameworks */,
+                               44A655A51AA4B4C70059D185 /* libctkclient_sep.a in Frameworks */,
                                DC00ABC61D821EE500513D74 /* libSOSRegressions.a in Frameworks */,
                                4432B1601A014D85000958DC /* libcoreauthd_client.a in Frameworks */,
                                4432B1611A014D85000958DC /* libaks_acl.a in Frameworks */,
                                DC00ABC61D821EE500513D74 /* libSOSRegressions.a in Frameworks */,
                                4432B1601A014D85000958DC /* libcoreauthd_client.a in Frameworks */,
                                4432B1611A014D85000958DC /* libaks_acl.a in Frameworks */,
                                EBCE16501FE6DE5A002E7CCC /* libaks_acl.a in Frameworks */,
                                EBCE16511FE6DE5A002E7CCC /* libbsm.dylib in Frameworks */,
                                EBCE16521FE6DE5A002E7CCC /* libcoreauthd_client.a in Frameworks */,
                                EBCE16501FE6DE5A002E7CCC /* libaks_acl.a in Frameworks */,
                                EBCE16511FE6DE5A002E7CCC /* libbsm.dylib in Frameworks */,
                                EBCE16521FE6DE5A002E7CCC /* libcoreauthd_client.a in Frameworks */,
-                               EBCE16531FE6DE5A002E7CCC /* libctkclient.a in Frameworks */,
+                               EBCE16531FE6DE5A002E7CCC /* libctkclient_sep.a in Frameworks */,
                                EBCE16541FE6DE5A002E7CCC /* libprequelite.tbd in Frameworks */,
                                EBCE16551FE6DE5A002E7CCC /* libsqlite3.0.dylib in Frameworks */,
                                D4911171209559620066A1E4 /* CoreData.framework in Frameworks */,
                                EBCE16541FE6DE5A002E7CCC /* libprequelite.tbd in Frameworks */,
                                EBCE16551FE6DE5A002E7CCC /* libsqlite3.0.dylib in Frameworks */,
                                D4911171209559620066A1E4 /* CoreData.framework in Frameworks */,
                                4432AF6A1A01458F000958DC /* libcoreauthd_client.a */,
                                5E8B53A41AA0B8A600345E7B /* libcoreauthd_test_client.a */,
                                E7AAB5F415929493005C8BCC /* libcorecrypto.dylib */,
                                4432AF6A1A01458F000958DC /* libcoreauthd_client.a */,
                                5E8B53A41AA0B8A600345E7B /* libcoreauthd_test_client.a */,
                                E7AAB5F415929493005C8BCC /* libcorecrypto.dylib */,
-                               4469FBDD1AA0A45C0021AA26 /* libctkclient.a */,
+                               4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */,
                                4469FBDC1AA0A45C0021AA26 /* libctkclient_test.a */,
                                4CB740680A4749C800D641BB /* libsqlite3.dylib */,
                        );
                                4469FBDC1AA0A45C0021AA26 /* libctkclient_test.a */,
                                4CB740680A4749C800D641BB /* libsqlite3.dylib */,
                        );
                        children = (
                                DCC78E281D8085FC00865A7C /* AppleBaselineEscrowCertificates.h */,
                                D41149A01E7C935D00C078C7 /* AppleiPhoneDeviceCACertificates.h */,
                        children = (
                                DCC78E281D8085FC00865A7C /* AppleBaselineEscrowCertificates.h */,
                                D41149A01E7C935D00C078C7 /* AppleiPhoneDeviceCACertificates.h */,
-                               DCC78E301D8085FC00865A7C /* SecAccessControl.c */,
+                               DCC78E301D8085FC00865A7C /* SecAccessControl.m */,
                                443381D918A3D81400215606 /* SecAccessControl.h */,
                                443381DA18A3D81400215606 /* SecAccessControlPriv.h */,
                                DCC78E351D8085FC00865A7C /* SecBase64.c */,
                                443381D918A3D81400215606 /* SecAccessControl.h */,
                                443381DA18A3D81400215606 /* SecAccessControlPriv.h */,
                                DCC78E351D8085FC00865A7C /* SecBase64.c */,
                        isa = PBXGroup;
                        children = (
                                DC610A671D78FA76002223DE /* teamid.sh */,
                        isa = PBXGroup;
                        children = (
                                DC610A671D78FA76002223DE /* teamid.sh */,
+                               F9B458272183E01100F6BCEB /* SignatureEditing.sh */,
                                DC610A631D78FA54002223DE /* CaspianTests */,
                                DC610A641D78FA54002223DE /* LocalCaspianTestRun.sh */,
                                DC610A681D78FA87002223DE /* validation.sh */,
                                DC610A631D78FA54002223DE /* CaspianTests */,
                                DC610A641D78FA54002223DE /* LocalCaspianTestRun.sh */,
                                DC610A681D78FA87002223DE /* validation.sh */,
                                DCB3446D1D8A35270054D16E /* kc-43-seckey-interop.m */,
                                DCB3446E1D8A35270054D16E /* kc-42-trust-revocation.c */,
                                24CBF8731E9D4E4500F09F0E /* kc-44-secrecoverypassword.c */,
                                DCB3446D1D8A35270054D16E /* kc-43-seckey-interop.m */,
                                DCB3446E1D8A35270054D16E /* kc-42-trust-revocation.c */,
                                24CBF8731E9D4E4500F09F0E /* kc-44-secrecoverypassword.c */,
+                               6CA837612210C5E7002770F1 /* kc-45-change-password.c */,
                                DCB3446F1D8A35270054D16E /* si-20-sectrust-provisioning.c */,
                                DCB344701D8A35270054D16E /* si-20-sectrust-provisioning.h */,
                                DCB344711D8A35270054D16E /* si-33-keychain-backup.c */,
                                DCB3446F1D8A35270054D16E /* si-20-sectrust-provisioning.c */,
                                DCB344701D8A35270054D16E /* si-20-sectrust-provisioning.h */,
                                DCB344711D8A35270054D16E /* si-33-keychain-backup.c */,
                                09A3B9E21F838A3400C5C324 /* SecKeyProxy.m in Sources */,
                                DC52EE771D80D88300B0A59C /* SecDH.c in Sources */,
                                DC52EE761D80D87F00B0A59C /* SecCTKKey.m in Sources */,
                                09A3B9E21F838A3400C5C324 /* SecKeyProxy.m in Sources */,
                                DC52EE771D80D88300B0A59C /* SecDH.c in Sources */,
                                DC52EE761D80D87F00B0A59C /* SecCTKKey.m in Sources */,
-                               DC52EE741D80D86F00B0A59C /* SecAccessControl.c in Sources */,
+                               DC52EE741D80D86F00B0A59C /* SecAccessControl.m in Sources */,
                                DC52EE731D80D86800B0A59C /* SecKey.c in Sources */,
                                DC52EE721D80D86400B0A59C /* SecuritydXPC.c in Sources */,
                                DC52EE711D80D85F00B0A59C /* SecECKey.m in Sources */,
                                DC52EE731D80D86800B0A59C /* SecKey.c in Sources */,
                                DC52EE721D80D86400B0A59C /* SecuritydXPC.c in Sources */,
                                DC52EE711D80D85F00B0A59C /* SecECKey.m in Sources */,
                                DCB344971D8A35270054D16E /* kc-26-key-import-public.m in Sources */,
                                DCB344981D8A35270054D16E /* kc-27-key-non-extractable.c in Sources */,
                                DCB3449A1D8A35270054D16E /* kc-28-cert-sign.c in Sources */,
                                DCB344971D8A35270054D16E /* kc-26-key-import-public.m in Sources */,
                                DCB344981D8A35270054D16E /* kc-27-key-non-extractable.c in Sources */,
                                DCB3449A1D8A35270054D16E /* kc-28-cert-sign.c in Sources */,
+                               6CA837642210CA8A002770F1 /* kc-45-change-password.c in Sources */,
                                DCB344991D8A35270054D16E /* kc-28-p12-import.m in Sources */,
                                DCB3449B1D8A35270054D16E /* kc-30-xara.c in Sources */,
                                DCB344A01D8A35270054D16E /* kc-40-seckey.m in Sources */,
                                DCB344991D8A35270054D16E /* kc-28-p12-import.m in Sources */,
                                DCB3449B1D8A35270054D16E /* kc-30-xara.c in Sources */,
                                DCB344A01D8A35270054D16E /* kc-40-seckey.m in Sources */,
                                0CAD1E581E1C5C6C00537693 /* SOSCloudCircle.m in Sources */,
                                DC5B391A20C08B70005B09F6 /* SecBase.c in Sources */,
                                DCC78EE71D808B2F00865A7C /* secViewDisplay.c in Sources */,
                                0CAD1E581E1C5C6C00537693 /* SOSCloudCircle.m in Sources */,
                                DC5B391A20C08B70005B09F6 /* SecBase.c in Sources */,
                                DCC78EE71D808B2F00865A7C /* secViewDisplay.c in Sources */,
-                               DCC78EE61D808B2A00865A7C /* SecAccessControl.c in Sources */,
+                               DCC78EE61D808B2A00865A7C /* SecAccessControl.m in Sources */,
                                DCC78EE51D808B2100865A7C /* SecBase64.c in Sources */,
                                DCC78EE41D808B1B00865A7C /* SecCFAllocator.c in Sources */,
                                DCC78EE31D808B1300865A7C /* SecCMS.c in Sources */,
                                DCC78EE51D808B2100865A7C /* SecBase64.c in Sources */,
                                DCC78EE41D808B1B00865A7C /* SecCFAllocator.c in Sources */,
                                DCC78EE31D808B1300865A7C /* SecCMS.c in Sources */,
index dc5def770c1173b74b7ceebed198513dc5a4acbe..a44c8e8ea840b8eca3d968e82ca7b42461c4ccc6 100644 (file)
@@ -10,6 +10,8 @@
        <true/>
        <key>com.apple.keystore.access-keychain-keys</key>
        <true/>
        <true/>
        <key>com.apple.keystore.access-keychain-keys</key>
        <true/>
+       <key>com.apple.keystore.sik.access</key>
+       <true/>
        <key>com.apple.keystore.lockassertion</key>
        <true/>
        <key>com.apple.keystore.device</key>
        <key>com.apple.keystore.lockassertion</key>
        <true/>
        <key>com.apple.keystore.device</key>
index 188619f0b5a4d0d582da7a53a8a2c94b1db59e15..608e577cdb9d0a5d7ee64e601f3c1a0eb85fe777 100644 (file)
@@ -37,6 +37,7 @@
 #include <Security/SecKeychainSearch.h>
 #include <Security/SecIdentitySearch.h>
 #include <Security/SecKey.h>
 #include <Security/SecKeychainSearch.h>
 #include <Security/SecIdentitySearch.h>
 #include <Security/SecKey.h>
+#include <Security/SecKeyPriv.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecCertificatePriv.h>
 #include <Security/SecItem.h>
 #include <Security/SecCertificate.h>
 #include <Security/SecCertificatePriv.h>
 #include <Security/SecItem.h>
@@ -559,7 +560,7 @@ ctk_obj_to_str(CFTypeRef obj, char *buf, int bufLen, Boolean key)
 
 typedef struct {
     int i;
 
 typedef struct {
     int i;
-    const char *name;
+    NSString *name;
 } ctk_print_context;
 
 OSStatus
 } ctk_print_context;
 
 OSStatus
@@ -581,7 +582,7 @@ static void
 ctk_dump_item_header(ctk_print_context *ctx)
 {
     printf("\n");
 ctk_dump_item_header(ctk_print_context *ctx)
 {
     printf("\n");
-    printf("==== %s #%d\n", ctx->name, ctx->i);
+    printf("==== %s #%d\n", ctx->name.UTF8String, ctx->i);
 }
 
 static void
 }
 
 static void
@@ -610,7 +611,7 @@ ctk_dump_item(CFTypeRef item, ctk_print_context *ctx)
 }
 
 static OSStatus
 }
 
 static OSStatus
-ctk_dump_items(CFArrayRef items, CFTypeRef secClass, const char *name)
+ctk_dump_items(CFArrayRef items, id secClass, NSString *name)
 {
     OSStatus stat = errSecSuccess;
 
 {
     OSStatus stat = errSecSuccess;
 
@@ -629,17 +630,33 @@ ctk_dump_items(CFArrayRef items, CFTypeRef secClass, const char *name)
     return stat;
 }
 
     return stat;
 }
 
+static void
+exportData(NSData *dataToExport, NSString *fileName, NSString *exportPath, NSString *elementName) {
+    NSMutableString *pem = [NSMutableString new];
+    [pem appendString:[NSString stringWithFormat:@"-----BEGIN %@-----\n", elementName]];
+    NSString *base64Cert = [dataToExport base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength | NSDataBase64EncodingEndLineWithLineFeed];
+    [pem appendString:base64Cert];
+    [pem appendString:[NSString stringWithFormat:@"\n-----END %@-----\n", elementName]];
+    
+    NSString *fullName = [NSString stringWithFormat:@"%@/%@.pem", exportPath, fileName];
+    NSError *error;
+    [pem writeToFile:fullName atomically:YES encoding:NSUTF8StringEncoding error:&error];
+    if (error) {
+        fprintf(stderr, "%s\n", [NSString stringWithFormat:@"%@", error].UTF8String);
+    }
+}
+
 static OSStatus
 static OSStatus
-ctk_dump(CFTypeRef secClass, const char *name, const char *tid)
+ctk_dump(id secClass, NSString *name, NSString *tid, NSString *exportPath)
 {
     NSArray *result;
     BOOL returnRef = NO;
 
 {
     NSArray *result;
     BOOL returnRef = NO;
 
-    if ([(__bridge id)secClass isEqual:(id)kSecClassIdentity] || [(__bridge id)secClass isEqual:(id)kSecClassCertificate])
+    if ([secClass isEqual:(id)kSecClassIdentity] || [secClass isEqual:(id)kSecClassCertificate])
         returnRef = YES;
 
     NSDictionary *query = @{
         returnRef = YES;
 
     NSDictionary *query = @{
-        (id)kSecClass : (__bridge id)secClass,
+        (id)kSecClass : secClass,
         (id)kSecMatchLimit : (id)kSecMatchLimitAll,
         (id)kSecAttrAccessGroup : (id)kSecAttrAccessGroupToken,
         (id)kSecReturnAttributes : @YES,
         (id)kSecMatchLimit : (id)kSecMatchLimitAll,
         (id)kSecAttrAccessGroup : (id)kSecAttrAccessGroupToken,
         (id)kSecReturnAttributes : @YES,
@@ -648,7 +665,7 @@ ctk_dump(CFTypeRef secClass, const char *name, const char *tid)
 
     if(tid) {
         NSMutableDictionary *updatedQuery = [NSMutableDictionary dictionaryWithDictionary:query];
 
     if(tid) {
         NSMutableDictionary *updatedQuery = [NSMutableDictionary dictionaryWithDictionary:query];
-        updatedQuery[(id)kSecAttrTokenID] = [NSString stringWithUTF8String:tid];
+        updatedQuery[(id)kSecAttrTokenID] = tid;
         query = updatedQuery;
     }
 
         query = updatedQuery;
     }
 
@@ -669,7 +686,7 @@ ctk_dump(CFTypeRef secClass, const char *name, const char *tid)
             for (NSDictionary *dict in result) {
                 NSMutableDictionary *updatedItem = [NSMutableDictionary dictionaryWithDictionary:dict];
                 id itemRef = updatedItem[(id)kSecValueRef];
             for (NSDictionary *dict in result) {
                 NSMutableDictionary *updatedItem = [NSMutableDictionary dictionaryWithDictionary:dict];
                 id itemRef = updatedItem[(id)kSecValueRef];
-                if ([(__bridge id)secClass isEqual:(id)kSecClassIdentity]) {
+                if ([secClass isEqual:(id)kSecClassIdentity]) {
                     id certificateRef;
                     if (SecIdentityCopyCertificate((__bridge SecIdentityRef)itemRef, (void *)&certificateRef) != errSecSuccess)
                         continue;
                     id certificateRef;
                     if (SecIdentityCopyCertificate((__bridge SecIdentityRef)itemRef, (void *)&certificateRef) != errSecSuccess)
                         continue;
@@ -680,11 +697,21 @@ ctk_dump(CFTypeRef secClass, const char *name, const char *tid)
                 updatedItem[@"sha1"] = certDigest;
                 [updatedItem removeObjectForKey:(id)kSecValueRef];
                 [updatedResult addObject:updatedItem];
                 updatedItem[@"sha1"] = certDigest;
                 [updatedItem removeObjectForKey:(id)kSecValueRef];
                 [updatedResult addObject:updatedItem];
+                
+                if (exportPath) {
+                    NSData *certData = (__bridge_transfer NSData *)SecCertificateCopyData((__bridge SecCertificateRef)itemRef);
+                    exportData(certData, updatedItem[(id)kSecAttrLabel], exportPath, @"CERTIFICATE");
+                    id publicKey = (__bridge_transfer id)SecCertificateCopyKey((__bridge SecCertificateRef)itemRef);
+                    NSData *pubKeyInfo = (__bridge_transfer NSData *)SecKeyCopySubjectPublicKeyInfo((__bridge SecKeyRef)publicKey);
+                    exportData(pubKeyInfo, [NSString stringWithFormat:@"Public Key - %@", updatedItem[(id)kSecAttrLabel]], exportPath, @"PUBLIC KEY");
+                }
             }
             result = updatedResult;
         }
 
             }
             result = updatedResult;
         }
 
-        stat = ctk_dump_items((__bridge CFArrayRef)result, secClass, name);
+        if (!exportPath) {
+            stat = ctk_dump_items((__bridge CFArrayRef)result, secClass, name);
+        }
     } else {
         stat = errSecInternalComponent;
     }
     } else {
         stat = errSecInternalComponent;
     }
@@ -694,13 +721,16 @@ ctk_dump(CFTypeRef secClass, const char *name, const char *tid)
 int
 ctk_export(int argc, char * const *argv)
 {
 int
 ctk_export(int argc, char * const *argv)
 {
-    OSStatus stat = errSecSuccess;
+    __block OSStatus stat = errSecSuccess;
 
     ItemSpec itemSpec = IS_All;
 
     ItemSpec itemSpec = IS_All;
-    const char *tid = NULL;
+    NSString *tid;
+    NSString *exportPath;
     int ch;
     int ch;
+    BOOL optT = NO;
+    BOOL optE = NO;
 
 
-    while ((ch = getopt(argc, argv, "i:t:h")) != -1) {
+    while ((ch = getopt(argc, argv, "i:t:e:h")) != -1) {
         switch  (ch) {
             case 't':
                 if(!strcmp("certs", optarg)) {
         switch  (ch) {
             case 't':
                 if(!strcmp("certs", optarg)) {
@@ -718,9 +748,15 @@ ctk_export(int argc, char * const *argv)
                 else {
                     return SHOW_USAGE_MESSAGE;
                 }
                 else {
                     return SHOW_USAGE_MESSAGE;
                 }
+                optT = YES;
                 break;
             case 'i':
                 break;
             case 'i':
-                tid = optarg;
+                tid = [NSString stringWithUTF8String:optarg];
+                break;
+            case 'e':
+                exportPath = [NSString stringWithUTF8String:optarg];
+                itemSpec = IS_Certs;
+                optE = YES;
                 break;
 
             case '?':
                 break;
 
             case '?':
@@ -728,19 +764,23 @@ ctk_export(int argc, char * const *argv)
                 return SHOW_USAGE_MESSAGE;
         }
     }
                 return SHOW_USAGE_MESSAGE;
         }
     }
+    
+    if (optT && optE) {
+        return SHOW_USAGE_MESSAGE;
+    }
 
 
-    CFTypeRef classes[] = { kSecClassCertificate, kSecClassKey, kSecClassIdentity };
-    const char* names[] = { "certificate", "private key", "identity" };
-    ItemSpec specs[] = { IS_Certs, IS_PrivKeys, IS_Identities };
-
-    for(size_t i = 0; i < sizeof(classes)/sizeof(classes[0]); i++) {
-        if(specs[i] == itemSpec || itemSpec == IS_All) {
-            stat = ctk_dump(classes[i], names[i], tid);
+    NSDictionary<id, NSArray *> *classesAndNames = @{ (id)kSecClassCertificate : @[ @"certificate", @(IS_Certs) ],
+                                                      (id)kSecClassKey : @[ @"private key", @(IS_PrivKeys) ],
+                                                      (id)kSecClassIdentity : @[ @"identity", @(IS_Identities) ] };
+    
+    [classesAndNames enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, NSArray * _Nonnull obj, BOOL * _Nonnull stop) {
+        if (itemSpec == IS_All || itemSpec == ((NSNumber *)obj[1]).unsignedIntegerValue) {
+            stat = ctk_dump(key, obj[0], tid, exportPath);
             if(stat) {
             if(stat) {
-                break;
+                *stop = YES;
             }
         }
             }
         }
-    }
+    }];
 
     return stat;
 }
 
     return stat;
 }
index dcbca48fd169f87bda1cb7d5366da4e4c24d0f75..1adbdfcd489f05400b80b43ab516fa7478eae95c 100644 (file)
@@ -128,10 +128,7 @@ do_keychain_set_password(const char *keychainName, const char* oldPassword, cons
                goto cleanup;
        }
 
                goto cleanup;
        }
 
-       /* lock keychain first to remove existing credentials */
-       (void)SecKeychainLock(keychain);
-
-       /* change the password */
+       /* change the password, if daemon agrees everything looks good */
        result = SecKeychainChangePassword(keychain, oldLen, oldPass, newLen, newPass);
        if (result)
        {
        result = SecKeychainChangePassword(keychain, oldLen, oldPass, newLen, newPass);
        if (result)
        {
index a949890f5a256f8b4283c2ce4a727f183028e3d9..bf391cd99e81ecbc23c2ea2298a57b1ad29a47e0 100644 (file)
@@ -190,7 +190,7 @@ Enable, disable or list disabled smartcard tokens.
 .It Nm list-smartcards
 Display available smartcards.
 .It Nm export-smartcard
 .It Nm list-smartcards
 Display available smartcards.
 .It Nm export-smartcard
-Export items from a smartcard.
+Export/display items from a smartcard.
 .It Nm error
 Display a descriptive message for the given error code(s).
 .El
 .It Nm error
 Display a descriptive message for the given error code(s).
 .El
@@ -1611,23 +1611,28 @@ s of available smartcards.
 .Ar token
 .Op Fl i Ar id
 .Op Fl t Ar certs Ns | Ns Ar privKeys Ns | Ns Ar identities Ns | Ns Ar all
 .Ar token
 .Op Fl i Ar id
 .Op Fl t Ar certs Ns | Ns Ar privKeys Ns | Ns Ar identities Ns | Ns Ar all
+.Op Fl e Ar exportPath
 .Bl -item -offset -indent
 .Bl -item -offset -indent
-Export items from a smartcard. If
+Export/display items from a smartcard. If
 .Ar id
 .Ar id
-isn't provided, items from all smartcards will be exported.
+isn't provided, items from all smartcards will be displayed.
 .It
 Options:
 .Bl -tag -compact -width -indent-indent
 .It Fl i Ar id
 .It
 Options:
 .Bl -tag -compact -width -indent-indent
 .It Fl i Ar id
-Export items from token specified by token
+Export/display items from token specified by token
 .Ar id Ns
 , available
 .Ar id Ns
 s can be listed by list-smartcards command.
 .It Fl t Ar certs Ns | Ns Ar privKeys Ns | Ns Ar identities Ns | Ns Ar all
 .Ar id Ns
 , available
 .Ar id Ns
 s can be listed by list-smartcards command.
 .It Fl t Ar certs Ns | Ns Ar privKeys Ns | Ns Ar identities Ns | Ns Ar all
-Export items of the specified type (Default:
+Display items of the specified type (Default:
 .Ar all Ns
 )
 .Ar all Ns
 )
+.It Fl e Ar exportPath
+Specify path to export certificates and public keys. If
+.Ar exportPath Ns
+ is specified screen output is suppressed. This option cannot be combined with -t option.
 .El
 .El
 .It
 .El
 .El
 .It
index a267dac1cb02b6e3ddccb434e6288021fb83ba92..301f00b5d39f0e05b1fd83662988762be2ea6510 100644 (file)
@@ -505,10 +505,11 @@ const command commands[] =
          "Import items into a keychain." },
 
     { "export-smartcard" , ctk_export,
          "Import items into a keychain." },
 
     { "export-smartcard" , ctk_export,
-        "[-i id] [-t type] \n"
+        "[-i id] [-t type] [-e exportPath] \n"
         "    -i  id of the smartcard to export (available IDs can be listed by list-smartcards\n"
         "    -i  id of the smartcard to export (available IDs can be listed by list-smartcards\n"
-        "        command, default: export all smartcards)\n"
-        "    -t  Type = certs|privKeys|identities|all  (Default: all)\n",
+        "        command, default: export/display all smartcards)\n"
+        "    -t  Type = certs|privKeys|identities|all  (Default: all)\n"
+        "    -e  Specify path to export certificates and public keys. This option cannot be combined with -t option.\n",
         "Export items from a smartcard." },
 
        { "cms", cms_util,
         "Export items from a smartcard." },
 
        { "cms", cms_util,
index 293b43055a3858625f484fd8723d1b98349d3182..456174f96dbcd41d07772fc32bafe456f135642d 100644 (file)
@@ -1190,6 +1190,8 @@ typedef struct {
 #define kSystemKeychainDir             "/Library/Keychains/"
 #define kSystemUnlockFile              "/var/db/SystemKey"
 
 #define kSystemKeychainDir             "/Library/Keychains/"
 #define kSystemUnlockFile              "/var/db/SystemKey"
 
+#define kSystemKeychainPath    kSystemKeychainDir kSystemKeychainName
+
 /*
  * CSSM ACL tags used to store partition/integrity data in ACLs
  */
 /*
  * CSSM ACL tags used to store partition/integrity data in ACLs
  */
index e444b51fec926b0c099e87bd38672534516918b5..ff0b92861ff06c96ffc1a2924e2ea90f30bea44b 100644 (file)
@@ -879,7 +879,7 @@ SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeDate = (SecCDKey
     managedItem.metadata = attributeData;
 
     SecCDKeychainManagedAccessControlEntity* owner = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityTypeAccessControlEntity inManagedObjectContext:managedObjectContext];
     managedItem.metadata = attributeData;
 
     SecCDKeychainManagedAccessControlEntity* owner = [NSEntityDescription insertNewObjectForEntityForName:SecCDKeychainEntityTypeAccessControlEntity inManagedObjectContext:managedObjectContext];
-    owner.type = item.owner.entityType;
+    owner.type = (int32_t)item.owner.entityType;
     owner.stringRepresentation = item.owner.stringRepresentation;
     managedItem.owner = owner;
     [owner addOwnedItemsObject:managedItem];
     owner.stringRepresentation = item.owner.stringRepresentation;
     managedItem.owner = owner;
     [owner addOwnedItemsObject:managedItem];
index ad370e53b0b9bac485d946d58736b42e012dd06c..ba571b1b591b2a8fee2e2bd158cfa05fa0fb523f 100644 (file)
@@ -778,7 +778,7 @@ extern const CFStringRef kSecAttrKeyClassSymmetric
     @constant kSecAttrKeyTypeRC4 (OSX only)
     @constant kSecAttrKeyTypeRC2 (OSX only)
     @constant kSecAttrKeyTypeCAST (OSX only)
     @constant kSecAttrKeyTypeRC4 (OSX only)
     @constant kSecAttrKeyTypeRC2 (OSX only)
     @constant kSecAttrKeyTypeCAST (OSX only)
-    @constant kSecAttrKeyTypeECDSA (deprecated; use kSecAttrKeyTypeEC instead.) (OSX only)
+    @constant kSecAttrKeyTypeECDSA (deprecated; use kSecAttrKeyTypeECSECPrimeRandom instead.) (OSX only)
 */
 extern const CFStringRef kSecAttrKeyTypeRSA
     API_AVAILABLE(macos(10.7), ios(2.0));
 */
 extern const CFStringRef kSecAttrKeyTypeRSA
     API_AVAILABLE(macos(10.7), ios(2.0));
index 0476998d28b8701d7c2c7ceea91298287831bc96..631491fb5db58ee26cd50a7ee84ccc578182829a 100644 (file)
@@ -368,6 +368,7 @@ extern const CFStringRef kSecAttrViewHintAutoUnlock;
 extern const CFStringRef kSecAttrViewHintHealth;
 extern const CFStringRef kSecAttrViewHintApplePay;
 extern const CFStringRef kSecAttrViewHintHome;
 extern const CFStringRef kSecAttrViewHintHealth;
 extern const CFStringRef kSecAttrViewHintApplePay;
 extern const CFStringRef kSecAttrViewHintHome;
+extern const CFStringRef kSecAttrViewHintLimitedPeersAllowed;
 
 
 extern const CFStringRef kSecUseSystemKeychain
 
 
 extern const CFStringRef kSecUseSystemKeychain
index 85467aa661fb463514bb187583f40ced07276302..e5f4c624b3c1398b22a0bc60579094f4eabfe151 100644 (file)
@@ -1076,128 +1076,118 @@ __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AV
     @constant kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1.  AES Key size
     @constant kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG and
-    all-zero 16 byte long IV (initialization vector).
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG and all-zero 16 byte long IV (initialization vector).
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG and
-    all-zero 16 byte long IV (initialization vector).
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG and all-zero 16 byte long IV (initialization vector).
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG and
-    all-zero 16 byte long IV (initialization vector).
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG and all-zero 16 byte long IV (initialization vector).
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG and
-    all-zero 16 byte long IV (initialization vector).
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG and all-zero 16 byte long IV (initialization vector).
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG and
-    all-zero 16 byte long IV (initialization vector).
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG and all-zero 16 byte long IV (initialization vector).
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorX963SHA1AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA1.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG and
-    all-zero 16 byte long IV (initialization vector).
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG and all-zero 16 byte long IV (initialization vector).
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorX963SHA224AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG and
-    all-zero 16 byte long IV (initialization vector).
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG and all-zero 16 byte long IV (initialization vector).
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG and
-    all-zero 16 byte long IV (initialization vector).
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG and all-zero 16 byte long IV (initialization vector).
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorX963SHA384AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG and
-    all-zero 16 byte long IV (initialization vector).
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG and all-zero 16 byte long IV (initialization vector).
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorX963SHA512AESGCM
     Legacy ECIES encryption or decryption, use kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM in new code.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG and
-    all-zero 16 byte long IV (initialization vector).
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG and all-zero 16 byte long IV (initialization vector).
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA224.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG, AES key
-    is first half of KDF output and 16 byte long IV (initialization vector) is second half of KDF output.
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG, AES key is first half of KDF output and 16 byte long IV (initialization vector) is second half
+    of KDF output.
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA256.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG, AES key
-    is first half of KDF output and 16 byte long IV (initialization vector) is second half of KDF output.
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG, AES key is first half of KDF output and 16 byte long IV (initialization vector) is second half
+    of KDF output.
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA384.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG, AES key
-    is first half of KDF output and 16 byte long IV (initialization vector) is second half of KDF output.
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG, AES key is first half of KDF output and 16 byte long IV (initialization vector) is second half
+    of KDF output.
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA512.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG, AES key
-    is first half of KDF output and 16 byte long IV (initialization vector) is second half of KDF output.
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG, AES key is first half of KDF output and 16 byte long IV (initialization vector) is second half
+    of KDF output.
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA224.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG, AES key
-    is first half of KDF output and 16 byte long IV (initialization vector) is second half of KDF output.
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG, AES key is first half of KDF output and 16 byte long IV (initialization vector) is second half
+    of KDF output.
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA256.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG, AES key
-    is first half of KDF output and 16 byte long IV (initialization vector) is second half of KDF output.
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG, AES key is first half of KDF output and 16 byte long IV (initialization vector) is second half
+    of KDF output.
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA384.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG, AES key
-    is first half of KDF output and 16 byte long IV (initialization vector) is second half of KDF output.
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG, AES key is first half of KDF output and 16 byte long IV (initialization vector) is second half
+    of KDF output.
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512.  AES Key size
 
     @constant kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA512AESGCM
     ECIES encryption or decryption.  This algorithm does not limit the size of the message to be encrypted or decrypted.
     Encryption is done using AES-GCM with key negotiated by kSecKeyAlgorithmECDHKeyExchangeCofactorX963SHA512.  AES Key size
-    is 128bit for EC keys <=256bit and 256bit for bigger EC keys.  Ephemeral public key data is used as sharedInfo for KDF,
-    and static public key data is used as authenticationData for AES-GCM processing.  AES-GCM uses 16 bytes long TAG, AES key
-    is first half of KDF output and 16 byte long IV (initialization vector) is second half of KDF output.
+    is 128bit for EC keys <=256bit and 256bit for bigger EC keys. Ephemeral public key data is used as sharedInfo for KDF.
+    AES-GCM uses 16 bytes long TAG, AES key is first half of KDF output and 16 byte long IV (initialization vector) is second half
+    of KDF output.
 
     @constant kSecKeyAlgorithmECDHKeyExchangeCofactor
     Compute shared secret using ECDH cofactor algorithm, suitable only for kSecAttrKeyTypeECSECPrimeRandom keys.
 
     @constant kSecKeyAlgorithmECDHKeyExchangeCofactor
     Compute shared secret using ECDH cofactor algorithm, suitable only for kSecAttrKeyTypeECSECPrimeRandom keys.
index 0c61b2cfba7adc8c115d0d4c0951bbf5eb3413ce..2507bc2edb6d015f58f0fba16ed15eb1de8996a7 100644 (file)
@@ -347,7 +347,7 @@ enum {
  @result An algorithm identifier.
  */
 CFIndex SecKeyGetAlgorithmId(SecKeyRef key)
  @result An algorithm identifier.
  */
 CFIndex SecKeyGetAlgorithmId(SecKeyRef key)
-API_AVAILABLE(macos(10.8), ios(9.0));
+SPI_AVAILABLE(macos(10.8), ios(9.0));
 
 #if TARGET_OS_IPHONE
 /*!
 
 #if TARGET_OS_IPHONE
 /*!
@@ -708,6 +708,88 @@ OSStatus SecKeyRawVerifyOSX(
 
 #endif // SEC_OS_OSX_INCLUDES
 
 
 #endif // SEC_OS_OSX_INCLUDES
 
+/*!
+ @constant kSecKeyApplePayEnabled If set to kCFBooleanTrue during SecKeyCreateRandomKey, then the SEP-based key is ApplePay-enabled,
+ which means that it can be used for ECIES to re-crypt.
+ */
+extern const CFStringRef kSecKeyApplePayEnabled
+SPI_AVAILABLE(macos(10.14.4), ios(12.2), tvos(12.2), watchos(5.2));
+
+/*!
+ @constant kSecKeyEncryptionParameterSymmetricKeySizeInBits CFNumberRef with size in bits for ephemeral
+ symmetric key used for encryption/decryption.
+ */
+extern const CFStringRef kSecKeyEncryptionParameterSymmetricKeySizeInBits
+SPI_AVAILABLE(macos(10.14.4), ios(12.2), tvos(12.2), watchos(5.2));
+
+/*!
+ @constant kSecKeyEncryptionParameterSymmetricAAD CFDataRef with additional authentiction data for AES-GCM encryption.
+ */
+extern const CFStringRef kSecKeyEncryptionParameterSymmetricAAD
+SPI_AVAILABLE(macos(10.14.4), ios(12.2), tvos(12.2), watchos(5.2));
+
+/*!
+ @constant kSecKeyEncryptionParameterRecryptParameters Usable only for SecKeyCreateDecryptedDataWithParameters.
+ Contains dictionary with parameters for re-encryption using the same algorithm and encryption parameters
+ specified inside this dictionary.
+ */
+extern const CFStringRef kSecKeyEncryptionParameterRecryptParameters
+SPI_AVAILABLE(macos(10.14.4), ios(12.2), tvos(12.2), watchos(5.2));
+
+/*!
+ @constant kSecKeyEncryptionParameterRecryptCertificate Usable only inside kSecKeyEncryptionParameterRecryptParameters.
+ Specifies certificate whose public key is used to re-crypt previously decrypted data. This parameter should contain
+ CFDataRef with X509 DER-encoded data of the certificate chain {leaf, intermediate, root}, leaf's public key is
+ to be used for re-encryption.
+ */
+extern const CFStringRef kSecKeyEncryptionParameterRecryptCertificate
+SPI_AVAILABLE(macos(10.14.4), ios(12.2), tvos(12.2), watchos(5.2));
+
+/*!
+ @function SecKeyCreateEncryptedDataWithParameters
+ @abstract Encrypt a block of plaintext.
+ @param key Public key with which to encrypt the data.
+ @param algorithm One of SecKeyAlgorithm constants suitable to perform encryption with this key.
+ @param plaintext The data to encrypt. The length and format of the data must conform to chosen algorithm,
+ typically be less or equal to the value returned by SecKeyGetBlockSize().
+ @param parameters Dictionary with additional parameters for encryption. Supported parameters are:
+  - kSecKeyKeyExchangeParameterSharedInfo: additional SharedInfo value for ECIES encryptions
+  - kSecKeyEncryptionParameterSymmetricKeySizeInBits: 128 or 256, size of ephemeral AES key used for symmetric encryption
+  - kSecKeyEncryptionParameterSymmetricAAD: optional CFDataRef with additiona authentication data for AES-GCM encryption
+ @param error On error, will be populated with an error object describing the failure.
+ See "Security Error Codes" (SecBase.h).
+ @result The ciphertext represented as a CFData, or NULL on failure.
+ @discussion Encrypts plaintext data using specified key.  The exact type of the operation including the format
+ of input and output data is specified by encryption algorithm.
+ */
+CFDataRef SecKeyCreateEncryptedDataWithParameters(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef plaintext,
+                                                  CFDictionaryRef parameters, CFErrorRef *error)
+SPI_AVAILABLE(macos(10.14.4), ios(12.2), tvos(12.2), watchos(5.2));
+
+/*!
+ @function SecKeyCreateDecryptedDataWithParameters
+ @abstract Decrypt a block of ciphertext.
+ @param key Private key with which to decrypt the data.
+ @param algorithm One of SecKeyAlgorithm constants suitable to perform decryption with this key.
+ @param ciphertext The data to decrypt. The length and format of the data must conform to chosen algorithm,
+ typically be less or equal to the value returned by SecKeyGetBlockSize().
+ @param parameters Dictionary with additional parameters for decryption.Supported parameters are:
+  - kSecKeyKeyExchangeParameterSharedInfo: additional SharedInfo value for ECIES encryptions
+  - kSecKeyEncryptionParameterSymmetricKeySizeInBits: 128 or 256, size of ephemeral AES key used for symmetric encryption
+  - kSecKeyEncryptionParameterSymmetricAAD: optional CFDataRef with additiona authentication data for AES-GCM encryption
+  - kSecKeyEncryptionParameterRecryptParameters: optional CFDictionaryRef with parameters for immediate re-encryption
+    of decrypted data. If present, the dictionary *must* contain at least kSecKeyEncryptionParameterRecryptCertificate parameter.
+
+ @param error On error, will be populated with an error object describing the failure.
+ See "Security Error Codes" (SecBase.h).
+ @result The plaintext represented as a CFData, or NULL on failure.
+ @discussion Decrypts ciphertext data using specified key.  The exact type of the operation including the format
+ of input and output data is specified by decryption algorithm.
+ */
+CFDataRef SecKeyCreateDecryptedDataWithParameters(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef ciphertext,
+                                                  CFDictionaryRef parameters, CFErrorRef *error)
+SPI_AVAILABLE(macos(10.14.4), ios(12.2), tvos(12.2), watchos(5.2));
+
 /*!
  @enum SecKeyAttestationKeyType
  @abstract Defines types of builtin attestation keys.
 /*!
  @enum SecKeyAttestationKeyType
  @abstract Defines types of builtin attestation keys.
@@ -716,9 +798,9 @@ typedef CF_ENUM(uint32_t, SecKeyAttestationKeyType)
 {
     kSecKeyAttestationKeyTypeSIK = 0,
     kSecKeyAttestationKeyTypeGID = 1,
 {
     kSecKeyAttestationKeyTypeSIK = 0,
     kSecKeyAttestationKeyTypeGID = 1,
-    kSecKeyAttestationKeyTypeUIKCommitted API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 2,
-    kSecKeyAttestationKeyTypeUIKProposed API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 3,
-} API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
+    kSecKeyAttestationKeyTypeUIKCommitted SPI_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 2,
+    kSecKeyAttestationKeyTypeUIKProposed SPI_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 3,
+} SPI_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
 
 /*!
  @function SecKeyCopyAttestationKey
 
 /*!
  @function SecKeyCopyAttestationKey
@@ -730,7 +812,7 @@ typedef CF_ENUM(uint32_t, SecKeyAttestationKeyType)
  @result On success a SecKeyRef containing the requested key is returned, on failure it returns NULL.
 */
 SecKeyRef SecKeyCopyAttestationKey(SecKeyAttestationKeyType keyType, CFErrorRef *error)
  @result On success a SecKeyRef containing the requested key is returned, on failure it returns NULL.
 */
 SecKeyRef SecKeyCopyAttestationKey(SecKeyAttestationKeyType keyType, CFErrorRef *error)
-API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
+SPI_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
 
 /*!
  @function SecKeyCreateAttestation
 
 /*!
  @function SecKeyCreateAttestation
@@ -745,7 +827,7 @@ API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
  @discussion Key attestation only works for CTK SEP keys, i.e. keys created with kSecAttrTokenID=kSecAttrTokenIDSecureEnclave.
 */
 CFDataRef SecKeyCreateAttestation(SecKeyRef key, SecKeyRef keyToAttest, CFErrorRef *error)
  @discussion Key attestation only works for CTK SEP keys, i.e. keys created with kSecAttrTokenID=kSecAttrTokenIDSecureEnclave.
 */
 CFDataRef SecKeyCreateAttestation(SecKeyRef key, SecKeyRef keyToAttest, CFErrorRef *error)
-API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
+SPI_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
 
 /*!
  @function SecKeySetParameter
 
 /*!
  @function SecKeySetParameter
@@ -761,10 +843,10 @@ API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
  SecKey user (application) and backend and in this case are not interpreted by SecKey layer in any way.
  */
 Boolean SecKeySetParameter(SecKeyRef key, CFStringRef name, CFPropertyListRef value, CFErrorRef *error)
  SecKey user (application) and backend and in this case are not interpreted by SecKey layer in any way.
  */
 Boolean SecKeySetParameter(SecKeyRef key, CFStringRef name, CFPropertyListRef value, CFErrorRef *error)
-API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
+SPI_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
 
 extern const CFStringRef kSecKeyParameterSETokenAttestationNonce
 
 extern const CFStringRef kSecKeyParameterSETokenAttestationNonce
-API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
+SPI_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
 
 /*!
  Available lifetime operations for SEP system keys.
 
 /*!
  Available lifetime operations for SEP system keys.
@@ -772,7 +854,7 @@ API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0));
 typedef CF_ENUM(int, SecKeyControlLifetimeType) {
     kSecKeyControlLifetimeTypeBump = 0,
     kSecKeyControlLifetimeTypeCommit = 1,
 typedef CF_ENUM(int, SecKeyControlLifetimeType) {
     kSecKeyControlLifetimeTypeBump = 0,
     kSecKeyControlLifetimeTypeCommit = 1,
-} API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0));
+} SPI_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0));
 
 /*!
  @function SecKeyControlLifetime
 
 /*!
  @function SecKeyControlLifetime
@@ -783,7 +865,7 @@ typedef CF_ENUM(int, SecKeyControlLifetimeType) {
  @param error Error which gathers more information when something went wrong.
  */
 Boolean SecKeyControlLifetime(SecKeyRef key, SecKeyControlLifetimeType type, CFErrorRef *error)
  @param error Error which gathers more information when something went wrong.
  */
 Boolean SecKeyControlLifetime(SecKeyRef key, SecKeyControlLifetimeType type, CFErrorRef *error)
-API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0));
+SPI_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0));
 
 /*!
  @function SecKeyCreateDuplicate
 
 /*!
  @function SecKeyCreateDuplicate
@@ -796,7 +878,7 @@ API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0));
  If the key is immutable (i.e. does not support SecKeySetParameter), calling this method is identical to calling CFRetain().
  */
 SecKeyRef SecKeyCreateDuplicate(SecKeyRef key)
  If the key is immutable (i.e. does not support SecKeySetParameter), calling this method is identical to calling CFRetain().
  */
 SecKeyRef SecKeyCreateDuplicate(SecKeyRef key)
-API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
+SPI_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0));
 
 /*!
  Algorithms for converting between bigendian and core-crypto ccunit data representation.
 
 /*!
  Algorithms for converting between bigendian and core-crypto ccunit data representation.
index d6eeb2256e3512472001a0283875d54343a863ac..6e35c084c11facffb5853d5beaba203197afc3ad 100644 (file)
@@ -61,6 +61,7 @@ extern CKKSItemState* const SecCKKSStateUnauthenticated;
 extern CKKSItemState* const SecCKKSStateInFlight;
 extern CKKSItemState* const SecCKKSStateReencrypt;
 extern CKKSItemState* const SecCKKSStateError;
 extern CKKSItemState* const SecCKKSStateInFlight;
 extern CKKSItemState* const SecCKKSStateReencrypt;
 extern CKKSItemState* const SecCKKSStateError;
+extern CKKSItemState* const SecCKKSStateZoneMismatch; // an item has appeared that's in the wrong zone
 extern CKKSItemState* const SecCKKSStateDeleted;  // meta-state: please delete this item!
 
 /* Processed States */
 extern CKKSItemState* const SecCKKSStateDeleted;  // meta-state: please delete this item!
 
 /* Processed States */
index c760202100fd0c390f84669edf1dd2a33c2f27ff..3d80c47d6bba92c3ce51dfcdba4cae60f63b7886 100644 (file)
@@ -50,6 +50,7 @@ CKKSItemState* const SecCKKSStateUnauthenticated = (CKKSItemState*) @"unauthenti
 CKKSItemState* const SecCKKSStateInFlight = (CKKSItemState*) @"inflight";
 CKKSItemState* const SecCKKSStateReencrypt = (CKKSItemState*) @"reencrypt";
 CKKSItemState* const SecCKKSStateError = (CKKSItemState*) @"error";
 CKKSItemState* const SecCKKSStateInFlight = (CKKSItemState*) @"inflight";
 CKKSItemState* const SecCKKSStateReencrypt = (CKKSItemState*) @"reencrypt";
 CKKSItemState* const SecCKKSStateError = (CKKSItemState*) @"error";
+CKKSItemState* const SecCKKSStateZoneMismatch = (CKKSItemState*) @"zone_mismatch";
 CKKSItemState* const SecCKKSStateDeleted = (CKKSItemState*) @"deleted";
 
 CKKSProcessedState* const SecCKKSProcessedStateLocal = (CKKSProcessedState*) @"local";
 CKKSItemState* const SecCKKSStateDeleted = (CKKSItemState*) @"deleted";
 
 CKKSProcessedState* const SecCKKSProcessedStateLocal = (CKKSProcessedState*) @"local";
index 3132c6d0fc7f675ec1af0d8f38c2badaf25b0849..f3f53f19b28c84b46ab05cbc8412a585b9768eef 100644 (file)
                 continue;
             }
 
                 continue;
             }
 
+
+            // Now, filter: if this item was added locally, would it go to this view?
+            // In this release, this is based solely on viewhint
+            NSString* viewHint = attributes[(id)kSecAttrSyncViewHint];
+            bool itemIsForView = [viewHint isEqualToString: ckks.zoneName];
+            if(!itemIsForView) {
+
+                ckkserror("ckksincoming", ckks, "ViewHint in decrypted item (%@) does not match (%@), skipping item", viewHint, ckks.zoneName);
+                iqe.state = SecCKKSStateZoneMismatch;
+                [iqe saveToDatabase:&error];
+                if(error) {
+                    ckkserror("ckksincoming", ckks, "Couldn't save zone mismatch IQE to database: %@", error);
+                    self.error = error;
+                }
+                continue;
+            }
+
             if([iqe.action isEqualToString: SecCKKSActionAdd] || [iqe.action isEqualToString: SecCKKSActionModify]) {
                 BOOL requireManifestValidation = [CKKSManifest shouldEnforceManifests];
                 BOOL manifestValidatesItem = [manifest validateItem:iqe.item withError:&error];
             if([iqe.action isEqualToString: SecCKKSActionAdd] || [iqe.action isEqualToString: SecCKKSActionModify]) {
                 BOOL requireManifestValidation = [CKKSManifest shouldEnforceManifests];
                 BOOL manifestValidatesItem = [manifest validateItem:iqe.item withError:&error];
index 965c28f212bccd6b7e5a9c1468872a4b3b1685f3..07e5b98780a9509758ce5543bc461d4dc510d0cb 100644 (file)
 
                                                                        // Ugly, but: the Manatee and Engram views need to send a fake 'PCS' view change.
                                                                        // TODO: make this data-driven somehow
 
                                                                        // Ugly, but: the Manatee and Engram views need to send a fake 'PCS' view change.
                                                                        // TODO: make this data-driven somehow
-                                                                       if([strongSelf.zoneName isEqualToString:@"Manatee"] || [strongSelf.zoneName isEqualToString:@"Engram"]) {
+                                                                       if([strongSelf.zoneName isEqualToString:@"Manatee"] ||
+                                                                          [strongSelf.zoneName isEqualToString:@"Engram"] ||
+                                                                          [strongSelf.zoneName isEqualToString:@"ApplePay"] ||
+                                                                          [strongSelf.zoneName isEqualToString:@"LimitedPeersAllowed"]) {
                                                                            [strongSelf.notifierClass post:@"com.apple.security.view-change.PCS"];
                                                                        }
                                                                    }];
                                                                            [strongSelf.notifierClass post:@"com.apple.security.view-change.PCS"];
                                                                        }
                                                                    }];
index ace523439096cedb859427357ef34281da22a779..664d69deba227b76a360d100734dc80e97eaa039 100644 (file)
 @property FakeCKZone*          homeZone;
 @property (readonly) ZoneKeys* homeZoneKeys;
 
 @property FakeCKZone*          homeZone;
 @property (readonly) ZoneKeys* homeZoneKeys;
 
+@property CKRecordZoneID*      limitedZoneID;
+@property CKKSKeychainView*    limitedView;
+@property FakeCKZone*          limitedZone;
+@property (readonly) ZoneKeys* limitedZoneKeys;
+
 @end
 
 @implementation CloudKitKeychainSyncingSOSIntegrationTests
 @end
 
 @implementation CloudKitKeychainSyncingSOSIntegrationTests
     [self.ckksZones addObject:self.applepayZoneID];
 
     self.homeZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Home" ownerName:CKCurrentUserDefaultName];
     [self.ckksZones addObject:self.applepayZoneID];
 
     self.homeZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Home" ownerName:CKCurrentUserDefaultName];
-    self.homeZone = [[FakeCKZone alloc] initZone: self.healthZoneID];
+    self.homeZone = [[FakeCKZone alloc] initZone: self.homeZoneID];
     self.zones[self.homeZoneID] = self.homeZone;
     self.homeView = [[CKKSViewManager manager] findView:@"Home"];
     XCTAssertNotNil(self.homeView, "CKKSViewManager created the Home view");
     [self.ckksZones addObject:self.homeZoneID];
     self.zones[self.homeZoneID] = self.homeZone;
     self.homeView = [[CKKSViewManager manager] findView:@"Home"];
     XCTAssertNotNil(self.homeView, "CKKSViewManager created the Home view");
     [self.ckksZones addObject:self.homeZoneID];
+
+    self.limitedZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"LimitedPeersAllowed" ownerName:CKCurrentUserDefaultName];
+    self.limitedZone = [[FakeCKZone alloc] initZone: self.limitedZoneID];
+    self.zones[self.limitedZoneID] = self.limitedZone;
+    self.limitedView = [[CKKSViewManager manager] findView:@"LimitedPeersAllowed"];
+    XCTAssertNotNil(self.limitedView, "CKKSViewManager created the LimitedPeersAllowed view");
+    [self.ckksZones addObject:self.limitedZoneID];
 }
 
 + (void)tearDown {
 }
 
 + (void)tearDown {
     [self startCKKSSubsystem];
 
     XCTestExpectation* applepayChanged = [self expectChangeForView:self.applepayZoneID.zoneName];
     [self startCKKSSubsystem];
 
     XCTestExpectation* applepayChanged = [self expectChangeForView:self.applepayZoneID.zoneName];
-    // ApplePay is NOT is PCS view, so it should not send the fake 'PCS' view notification
     XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"];
     XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"];
-    pcsChanged.inverted = YES;
+
 
     // We expect a single record to be uploaded to the ApplePay view.
     [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.applepayZoneID];
 
     // We expect a single record to be uploaded to the ApplePay view.
     [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.applepayZoneID];
     [self waitForExpectations:@[pcsChanged] timeout:0.2];
 }
 
     [self waitForExpectations:@[pcsChanged] timeout:0.2];
 }
 
+-(void)testAddLimitedPeersAllowedItems {
+    [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test.
+
+    [self startCKKSSubsystem];
+
+    XCTestExpectation* limitedChanged = [self expectChangeForView:self.limitedZoneID.zoneName];
+    // LimitedPeersAllowed is a PCS view, so it should send the fake 'PCS' view notification
+    XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"];
+
+    // We expect a single record to be uploaded to the LimitedPeersOkay view.
+    [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.limitedZoneID];
+    [self addGenericPassword: @"data" account: @"account-delete-me-limited-peers" viewHint:(NSString*) kSecAttrViewHintLimitedPeersAllowed];
+
+    OCMVerifyAllWithDelay(self.mockDatabase, 20);
+    [self waitForExpectations:@[limitedChanged] timeout:1];
+    [self waitForExpectations:@[pcsChanged] timeout:0.2];
+
+    [self waitForKeyHierarchyReadinesses];
+
+    // Let's also test that an item added by a future peer (lacking the right viewhint) doesn't sync
+    NSMutableDictionary* item = [[self fakeRecordDictionary:@"asdf" zoneID:self.limitedZoneID] mutableCopy];
+    item[(id)kSecAttrSyncViewHint] = @"new-view";
+
+    CKRecordID* ckrid = [[CKRecordID alloc] initWithRecordName:@"37E6CA21-A586-44E1-9A1C-3EE464C78EB5" zoneID:self.limitedZoneID];
+    CKRecord* ckr = [self newRecord:ckrid withNewItemData:item];
+    [self.limitedZone addToZone:ckr];
+    ckr = [self createFakeRecord:self.limitedZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2AAA" withAccount:@"asdf-exist"];
+    [self.limitedZone addToZone:ckr];
+
+    [self.limitedView notifyZoneChange:nil];
+    [self.limitedView waitForFetchAndIncomingQueueProcessing];
+
+    [self findGenericPassword:@"asdf-exist" expecting:errSecSuccess];
+    [self findGenericPassword:@"asdf" expecting:errSecItemNotFound];
+
+    NSError *error = NULL;
+    XCTAssertEqual([CKKSIncomingQueueEntry countByState:SecCKKSStateZoneMismatch zone:self.limitedZoneID error:&error],
+                   1,
+                   "Expected a ZoneMismatch entry in incoming queue: %@", error);
+    XCTAssertNil(error, "Should be no error fetching incoming queue entries");
+}
+
 -(void)testAddOtherViewHintItem {
     [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test.
 
 -(void)testAddOtherViewHintItem {
     [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test.
 
     [self putFakeDeviceStatusInCloudKit: self.healthZoneID];
     [self putFakeDeviceStatusInCloudKit: self.applepayZoneID];
     [self putFakeDeviceStatusInCloudKit: self.homeZoneID];
     [self putFakeDeviceStatusInCloudKit: self.healthZoneID];
     [self putFakeDeviceStatusInCloudKit: self.applepayZoneID];
     [self putFakeDeviceStatusInCloudKit: self.homeZoneID];
+    [self putFakeDeviceStatusInCloudKit: self.limitedZoneID];
 }
 
 -(void)putFakeKeyHierachiesInCloudKit{
 }
 
 -(void)putFakeKeyHierachiesInCloudKit{
     [self putFakeKeyHierarchyInCloudKit: self.healthZoneID];
     [self putFakeKeyHierarchyInCloudKit: self.applepayZoneID];
     [self putFakeKeyHierarchyInCloudKit: self.homeZoneID];
     [self putFakeKeyHierarchyInCloudKit: self.healthZoneID];
     [self putFakeKeyHierarchyInCloudKit: self.applepayZoneID];
     [self putFakeKeyHierarchyInCloudKit: self.homeZoneID];
+    [self putFakeKeyHierarchyInCloudKit: self.limitedZoneID];
 }
 -(void)saveTLKsToKeychain{
     [self saveTLKMaterialToKeychain:self.engramZoneID];
 }
 -(void)saveTLKsToKeychain{
     [self saveTLKMaterialToKeychain:self.engramZoneID];
     [self saveTLKMaterialToKeychain:self.healthZoneID];
     [self saveTLKMaterialToKeychain:self.applepayZoneID];
     [self saveTLKMaterialToKeychain:self.homeZoneID];
     [self saveTLKMaterialToKeychain:self.healthZoneID];
     [self saveTLKMaterialToKeychain:self.applepayZoneID];
     [self saveTLKMaterialToKeychain:self.homeZoneID];
+    [self saveTLKMaterialToKeychain:self.limitedZoneID];
 }
 -(void)deleteTLKMaterialsFromKeychain{
     [self deleteTLKMaterialFromKeychain: self.engramZoneID];
 }
 -(void)deleteTLKMaterialsFromKeychain{
     [self deleteTLKMaterialFromKeychain: self.engramZoneID];
     [self deleteTLKMaterialFromKeychain: self.healthZoneID];
     [self deleteTLKMaterialFromKeychain: self.applepayZoneID];
     [self deleteTLKMaterialFromKeychain: self.homeZoneID];
     [self deleteTLKMaterialFromKeychain: self.healthZoneID];
     [self deleteTLKMaterialFromKeychain: self.applepayZoneID];
     [self deleteTLKMaterialFromKeychain: self.homeZoneID];
+    [self deleteTLKMaterialFromKeychain:self.limitedZoneID];
 }
 
 -(void)waitForKeyHierarchyReadinesses {
 }
 
 -(void)waitForKeyHierarchyReadinesses {
     [self.healthView waitForKeyHierarchyReadiness];
     [self.applepayView waitForKeyHierarchyReadiness];
     [self.homeView waitForKeyHierarchyReadiness];
     [self.healthView waitForKeyHierarchyReadiness];
     [self.applepayView waitForKeyHierarchyReadiness];
     [self.homeView waitForKeyHierarchyReadiness];
+    [self.limitedView waitForKeyHierarchyReadiness];
 }
 
 -(void)testAcceptExistingAndUsePiggyKeyHierarchy {
 }
 
 -(void)testAcceptExistingAndUsePiggyKeyHierarchy {
index 9fc7a7c90961a9774b5b01232fb398add843d1e3..951dd0f6d767fb637a66a5265d9f246ef98c2fa3 100644 (file)
@@ -62,6 +62,7 @@
               (id)kSecClass : (id)kSecClassGenericPassword,
               (id)kSecReturnPersistentRef: @YES,
               (id)kSecReturnAttributes: @YES,
               (id)kSecClass : (id)kSecClassGenericPassword,
               (id)kSecReturnPersistentRef: @YES,
               (id)kSecReturnAttributes: @YES,
+              (id)kSecAttrSyncViewHint: @"keychain",
               (id)kSecAttrAccessGroup : @"com.apple.security.ckks",
               (id)kSecAttrAccessible: (id)kSecAttrAccessibleAfterFirstUnlock,
               (id)kSecAttrAccount : account,
               (id)kSecAttrAccessGroup : @"com.apple.security.ckks",
               (id)kSecAttrAccessible: (id)kSecAttrAccessibleAfterFirstUnlock,
               (id)kSecAttrAccount : account,
index d89f20a18e390d1db642e1d652c2a9a8eceb0c85..c7fedf83861da6b135a6614b5f7095c50998594f 100644 (file)
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
-    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID];
+    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID];
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
                                                   PCSPublicKey:publicKey
                                              PCSPublicIdentity:publicIdentity]];
 
                                                   PCSPublicKey:publicKey
                                              PCSPublicIdentity:publicIdentity]];
 
-    result = [self pcsAddItem:@"tOTHER-ITEM"
+    result = [self pcsAddItem:@"OTHER-ITEM"
                          data:[@"asdfasdf" dataUsingEncoding:NSUTF8StringEncoding]
             serviceIdentifier:(NSNumber*)servIdentifier
                     publicKey:(NSData*)publicKey
                          data:[@"asdfasdf" dataUsingEncoding:NSUTF8StringEncoding]
             serviceIdentifier:(NSNumber*)servIdentifier
                     publicKey:(NSData*)publicKey
 
     // Check that the record is where we expect it
     [self waitForCKModifications];
 
     // Check that the record is where we expect it
     [self waitForCKModifications];
-    CKRecordID* pcsOtherItemRecordID = [[CKRecordID alloc] initWithRecordName: @"878BEAA6-1EE9-1079-1025-E6832AC8F2F3" zoneID:self.keychainZoneID];
+    CKRecordID* pcsOtherItemRecordID = [[CKRecordID alloc] initWithRecordName: @"11D16E4E-F9F7-6940-938C-78BAC4D56953" zoneID:self.keychainZoneID];
     CKRecord* recordOther = self.keychainZone.currentDatabase[pcsOtherItemRecordID];
     XCTAssertNotNil(recordOther, "Found other record in CloudKit at expected UUID");
 
     CKRecord* recordOther = self.keychainZone.currentDatabase[pcsOtherItemRecordID];
     XCTAssertNotNil(recordOther, "Found other record in CloudKit at expected UUID");
 
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
-    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID];
+    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID];
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
 
     // Check that the records are where we expect them in CloudKit
     [self waitForCKModifications];
 
     // Check that the records are where we expect them in CloudKit
     [self waitForCKModifications];
-    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID];
+    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID];
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
-    CKRecordID* pcsItemRecordID2 = [[CKRecordID alloc] initWithRecordName: @"3AB8E78D-75AF-CFEF-F833-FA3E3E90978A" zoneID:self.keychainZoneID];
+    CKRecordID* pcsItemRecordID2 = [[CKRecordID alloc] initWithRecordName: @"10E76B80-CE1C-A52A-B0CB-462A2EBA05AF" zoneID:self.keychainZoneID];
     CKRecord* record2 = self.keychainZone.currentDatabase[pcsItemRecordID2];
     XCTAssertNotNil(record2, "Found 2nd record in CloudKit at expected UUID");
 
     CKRecord* record2 = self.keychainZone.currentDatabase[pcsItemRecordID2];
     XCTAssertNotNil(record2, "Found 2nd record in CloudKit at expected UUID");
 
 
     // Another machine comes along and updates the pointer!
     CKKSCurrentItemPointer* cip = [[CKKSCurrentItemPointer alloc] initForIdentifier:@"com.apple.security.ckks-pcsservice"
 
     // Another machine comes along and updates the pointer!
     CKKSCurrentItemPointer* cip = [[CKKSCurrentItemPointer alloc] initForIdentifier:@"com.apple.security.ckks-pcsservice"
-                                                                    currentItemUUID:@"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3"
+                                                                    currentItemUUID:@"50184A35-4480-E8BA-769B-567CF72F1EC0"
                                                                               state:SecCKKSProcessedStateRemote
                                                                              zoneID:self.keychainZoneID
                                                                     encodedCKRecord:nil];
                                                                               state:SecCKKSProcessedStateRemote
                                                                              zoneID:self.keychainZoneID
                                                                     encodedCKRecord:nil];
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
-    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID];
+    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID];
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
 
     // Another machine comes along and updates the pointer!
     CKKSCurrentItemPointer* cip = [[CKKSCurrentItemPointer alloc] initForIdentifier:@"com.apple.security.ckks-pcsservice"
 
     // Another machine comes along and updates the pointer!
     CKKSCurrentItemPointer* cip = [[CKKSCurrentItemPointer alloc] initForIdentifier:@"com.apple.security.ckks-pcsservice"
-                                                                    currentItemUUID:@"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3"
+                                                                    currentItemUUID:@"50184A35-4480-E8BA-769B-567CF72F1EC0"
                                                                               state:SecCKKSProcessedStateRemote
                                                                              zoneID:self.keychainZoneID
                                                                     encodedCKRecord:nil];
                                                                               state:SecCKKSProcessedStateRemote
                                                                              zoneID:self.keychainZoneID
                                                                     encodedCKRecord:nil];
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
-    NSString* recordUUID = @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3";
+    NSString* recordUUID = @"50184A35-4480-E8BA-769B-567CF72F1EC0";
     CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName:recordUUID zoneID:self.keychainZoneID];
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
     CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName:recordUUID zoneID:self.keychainZoneID];
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
-    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID];
+    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID];
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
     // Check that the number is on the CKKSMirrorEntry
     [self.keychainView dispatchSync: ^bool {
         NSError* error = nil;
     // Check that the number is on the CKKSMirrorEntry
     [self.keychainView dispatchSync: ^bool {
         NSError* error = nil;
-        CKKSMirrorEntry* ckme = [CKKSMirrorEntry fromDatabase:@"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID error:&error];
+        CKKSMirrorEntry* ckme = [CKKSMirrorEntry fromDatabase:@"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID error:&error];
 
         XCTAssertNil(error, "no error fetching ckme");
         XCTAssertNotNil(ckme, "Received a ckme");
 
         XCTAssertNil(error, "no error fetching ckme");
         XCTAssertNotNil(ckme, "Received a ckme");
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
-    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID];
+    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID];
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
 
     // Check that the record is where we expect it in CloudKit
     [self waitForCKModifications];
-    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID];
+    CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID];
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
     CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID];
     XCTAssertNotNil(record, "Found record in CloudKit at expected UUID");
 
     XCTAssertNil(error, "Error should be nil parsing base64 item");
 
     item[@"v_Data"] = [@"conflictingdata" dataUsingEncoding:NSUTF8StringEncoding];
     XCTAssertNil(error, "Error should be nil parsing base64 item");
 
     item[@"v_Data"] = [@"conflictingdata" dataUsingEncoding:NSUTF8StringEncoding];
-    CKRecordID* ckrid = [[CKRecordID alloc] initWithRecordName:@"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID];
+    item[@"vwht"] = self.keychainZoneID.zoneName;
+    CKRecordID* ckrid = [[CKRecordID alloc] initWithRecordName:@"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID];
     CKRecord* mismatchedRecord = [self newRecord:ckrid withNewItemData:item];
     [self.keychainZone addToZone: mismatchedRecord];
 
     CKRecord* mismatchedRecord = [self newRecord:ckrid withNewItemData:item];
     [self.keychainZone addToZone: mismatchedRecord];
 
index c5a7706ed3540e72b9bc93386fab792097d0a9e2..57df961b975bbb9a0ba3ac001aaa186ca6a07462 100644 (file)
@@ -532,8 +532,11 @@ SecCmsSignedDataVerifySignerInfo(SecCmsSignedDataRef sigd, int i,
     SecAsn1Item *contentType, *digest;
     OSStatus status;
 
     SecAsn1Item *contentType, *digest;
     OSStatus status;
 
-    cinfo = &(sigd->contentInfo);
+    if (sigd == NULL || sigd->signerInfos == NULL || i >= SecCmsSignedDataSignerInfoCount(sigd)) {
+        return errSecParam;
+    }
 
 
+    cinfo = &(sigd->contentInfo);
     signerinfo = sigd->signerInfos[i];
 
     /* Signature or digest level verificationStatus errors should supercede
     signerinfo = sigd->signerInfos[i];
 
     /* Signature or digest level verificationStatus errors should supercede
@@ -541,15 +544,21 @@ SecCmsSignedDataVerifySignerInfo(SecCmsSignedDataRef sigd, int i,
 
     /* Find digest and contentType for signerinfo */
     algiddata = SecCmsSignerInfoGetDigestAlg(signerinfo);
 
     /* Find digest and contentType for signerinfo */
     algiddata = SecCmsSignerInfoGetDigestAlg(signerinfo);
+    if (algiddata == NULL) {
+        return errSecInvalidDigestAlgorithm;
+    }
 
     if (!sigd->digests) {
 
     if (!sigd->digests) {
-       SECAlgorithmID **digestalgs = SecCmsSignedDataGetDigestAlgs(sigd);
-       SecCmsDigestContextRef digcx = SecCmsDigestContextStartMultiple(digestalgs);
-       SecCmsSignedDataSetDigestContext(sigd, digcx);
-       SecCmsDigestContextDestroy(digcx);
+        SECAlgorithmID **digestalgs = SecCmsSignedDataGetDigestAlgs(sigd);
+        SecCmsDigestContextRef digcx = SecCmsDigestContextStartMultiple(digestalgs);
+        SecCmsSignedDataSetDigestContext(sigd, digcx);
+        SecCmsDigestContextDestroy(digcx);
     }
 
     digest = SecCmsSignedDataGetDigestByAlgTag(sigd, algiddata->offset);
     }
 
     digest = SecCmsSignedDataGetDigestByAlgTag(sigd, algiddata->offset);
+    if (digest == NULL) {
+        return errSecDataNotAvailable;
+    }
 
     contentType = SecCmsContentInfoGetContentTypeOID(cinfo);
 
 
     contentType = SecCmsContentInfoGetContentTypeOID(cinfo);
 
index 03a4ac46592557b2bfe7cd7d89a14203a479192f..9ce04a93c3d40f5847b16e21da91d476204ea6f1 100644 (file)
Binary files a/resources/English.lproj/OID.strings and b/resources/English.lproj/OID.strings differ
index fb6330cfc9dad036f6b46942d162855293f409b1..70b8bdaf89dc7eaedde4f23616e9ad9bf420736d 100644 (file)
Binary files a/resources/English.lproj/Trust.strings and b/resources/English.lproj/Trust.strings differ
index 11b2b4b68eab439fb1854fee03cca17f65752b85..57b635c03c6191fac87f09af8d9d6be7d8863b6c 100644 (file)
@@ -150,8 +150,8 @@ csops_task(SecTaskRef task, int ops, void *blob, size_t size)
        return rc;
 }
 
        return rc;
 }
 
-CFStringRef
-SecTaskCopySigningIdentifier(SecTaskRef task, CFErrorRef *error)
+static CFStringRef
+SecTaskCopyIdentifier(SecTaskRef task, int op, CFErrorRef *error)
 {
         CFStringRef signingId = NULL;
         char *data = NULL;
 {
         CFStringRef signingId = NULL;
         char *data = NULL;
@@ -159,7 +159,7 @@ SecTaskCopySigningIdentifier(SecTaskRef task, CFErrorRef *error)
         uint32_t bufferlen;
         int ret;
 
         uint32_t bufferlen;
         int ret;
 
-        ret = csops_task(task, CS_OPS_IDENTITY, &header, sizeof(header));
+        ret = csops_task(task, op, &header, sizeof(header));
         if (ret != -1 || errno != ERANGE)
                 return NULL;
 
         if (ret != -1 || errno != ERANGE)
                 return NULL;
 
@@ -174,7 +174,7 @@ SecTaskCopySigningIdentifier(SecTaskRef task, CFErrorRef *error)
                 ret = ENOMEM;
                 goto out;
         }
                 ret = ENOMEM;
                 goto out;
         }
-        ret = csops_task(task, CS_OPS_IDENTITY, data, bufferlen);
+        ret = csops_task(task, op, data, bufferlen);
         if (ret) {
                 ret = errno;
                 goto out;
         if (ret) {
                 ret = errno;
                 goto out;
@@ -192,6 +192,18 @@ SecTaskCopySigningIdentifier(SecTaskRef task, CFErrorRef *error)
         return signingId;
 }
 
         return signingId;
 }
 
+CFStringRef
+SecTaskCopySigningIdentifier(SecTaskRef task, CFErrorRef *error)
+{
+    return SecTaskCopyIdentifier(task, CS_OPS_IDENTITY, error);
+}
+
+CFStringRef
+SecTaskCopyTeamIdentifier(SecTaskRef task, CFErrorRef *error)
+{
+    return SecTaskCopyIdentifier(task, CS_OPS_TEAMID, error);
+}
+
 uint32_t
 SecTaskGetCodeSignStatus(SecTaskRef task)
 {
 uint32_t
 SecTaskGetCodeSignStatus(SecTaskRef task)
 {
index b72266ecb8f088a70b9191ec476267308958a939..e29aa8832d36bd4d8372131edb2a628ff5a4034d 100644 (file)
@@ -39,7 +39,7 @@ __BEGIN_DECLS
     task satisfies the requirement.
 */
 
     task satisfies the requirement.
 */
 
-OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement);
+OSStatus SecTaskValidateForRequirement(SecTaskRef _Nonnull task, CFStringRef _Nonnull requirement);
 
 /*!
   @function SecTaskGetCodeSignStatus
 
 /*!
   @function SecTaskGetCodeSignStatus
@@ -48,7 +48,7 @@ OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement)
 */
 
 uint32_t
 */
 
 uint32_t
-SecTaskGetCodeSignStatus(SecTaskRef task);
+SecTaskGetCodeSignStatus(SecTaskRef _Nonnull task);
 #endif /* SEC_OS_OSX */
 
 /*!
 #endif /* SEC_OS_OSX */
 
 /*!
@@ -57,9 +57,18 @@ SecTaskGetCodeSignStatus(SecTaskRef task);
  false the tasks entitlements must not be used for anything security sensetive.
  @param task A previously created SecTask object
  */
  false the tasks entitlements must not be used for anything security sensetive.
  @param task A previously created SecTask object
  */
-Boolean SecTaskEntitlementsValidated(SecTaskRef task);
-
+Boolean SecTaskEntitlementsValidated(SecTaskRef _Nonnull task);
 
 
+/*!
+ @function SecTaskCopyTeamIdentifier
+ @abstract Return the value of the team identifier.
+ @param task A previously created SecTask object
+ @param error On a NULL return, this will contain a CFError describing
+ the problem.  This argument may be NULL if the caller is not interested in
+ detailed errors. The caller must CFRelease the returned value
+ */
+__nullable
+CFStringRef SecTaskCopyTeamIdentifier(SecTaskRef _Nonnull task, CFErrorRef _Nullable * _Nullable error);
 
 __END_DECLS
 
 
 __END_DECLS
 
index 52bf234862afc013e429bb5a3f35680b7233b292..2286c2d43b4e06c79e806d7a030e58fdbae0a3ee 100644 (file)
@@ -123,7 +123,7 @@ static service_user_record_t * get_user_record(uid_t uid)
     if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1) {
         bufsize = 4096;
     }
     if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1) {
         bufsize = 4096;
     }
-    char buf[bufsize];
+    char *buf = calloc(1, (size_t)bufsize);
     struct passwd pwbuf, *pw = NULL;
     int rc;
     if (((rc = getpwuid_r(uid, &pwbuf, buf, bufsize, &pw)) == 0) && pw != NULL) {
     struct passwd pwbuf, *pw = NULL;
     int rc;
     if (((rc = getpwuid_r(uid, &pwbuf, buf, bufsize, &pw)) == 0) && pw != NULL) {
@@ -138,6 +138,7 @@ static service_user_record_t * get_user_record(uid_t uid)
     }
 
 done:
     }
 
 done:
+    free(buf);
     return ur;
 }
 
     return ur;
 }
 
index df1647eee0b16d55c40cc8acb6b35f1f5c3e8204..60176b1b7e2d182b36314268adab519dae24b8ef 100644 (file)
@@ -32,6 +32,7 @@
 #include <security_utilities/crc.h>
 #include <security_utilities/casts.h>
 #include <unistd.h>
 #include <security_utilities/crc.h>
 #include <security_utilities/casts.h>
 #include <unistd.h>
+#include <vector>
 
 /*
     Logically, these should go in /var/run/mds, but we know that /var/db/mds
 
 /*
     Logically, these should go in /var/run/mds, but we know that /var/db/mds
@@ -153,13 +154,13 @@ void SharedMemoryServer::WriteMessage (SegmentOffsetType domain, SegmentOffsetTy
 
        // assemble the final message
        ssize_t messageSize = kHeaderLength + messageLength;
 
        // assemble the final message
        ssize_t messageSize = kHeaderLength + messageLength;
-       u_int8_t finalMessage[messageSize];
-       SegmentOffsetType *fm  = (SegmentOffsetType*) finalMessage;
+       std::vector<u_int8_t> finalMessage(messageSize);
+       SegmentOffsetType *fm  = (SegmentOffsetType*) finalMessage.data();
        fm[0] = OSSwapHostToBigInt32(domain);
        fm[1] = OSSwapHostToBigInt32(event);
        memcpy(&fm[2], message, messageLength);
        
        fm[0] = OSSwapHostToBigInt32(domain);
        fm[1] = OSSwapHostToBigInt32(event);
        memcpy(&fm[2], message, messageLength);
        
-       SegmentOffsetType crc = CalculateCRC(finalMessage, messageSize);
+       SegmentOffsetType crc = CalculateCRC(finalMessage.data(), messageSize);
        
        // write the length
        WriteOffset(int_cast<size_t, SegmentOffsetType>(messageSize));
        
        // write the length
        WriteOffset(int_cast<size_t, SegmentOffsetType>(messageSize));
@@ -168,7 +169,7 @@ void SharedMemoryServer::WriteMessage (SegmentOffsetType domain, SegmentOffsetTy
        WriteOffset(crc);
        
        // write the data
        WriteOffset(crc);
        
        // write the data
-       WriteData (finalMessage, int_cast<size_t, SegmentOffsetType>(messageSize));
+       WriteData (finalMessage.data(), int_cast<size_t, SegmentOffsetType>(messageSize));
        
        // write the data count
        SetProducerOffset(int_cast<size_t, SegmentOffsetType>(mDataPtr - mDataArea));
        
        // write the data count
        SetProducerOffset(int_cast<size_t, SegmentOffsetType>(mDataPtr - mDataArea));
index 88107375579e8cf16466f5b9c405337f6b48cbc9..e5004bd6df2ab9d7955fce31d2b285fa86bf050e 100644 (file)
@@ -321,6 +321,10 @@ static void xpcArrayToAuthItemSet(AuthItemSet *setToBuild, xpc_object_t input) {
         bool sensitive = xpc_dictionary_get_value(item, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH);
         if (sensitive) {
             size_t sensitiveLength = (size_t)xpc_dictionary_get_uint64(item, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH);
         bool sensitive = xpc_dictionary_get_value(item, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH);
         if (sensitive) {
             size_t sensitiveLength = (size_t)xpc_dictionary_get_uint64(item, AUTH_XPC_ITEM_SENSITIVE_VALUE_LENGTH);
+            if (sensitiveLength > length) {
+                secnotice("SecurityAgentXPCQuery", "Sensitive data len %zu is not valid", sensitiveLength);
+                return true;
+            }
             dataCopy = malloc(sensitiveLength);
             memcpy(dataCopy, data, sensitiveLength);
             memset_s((void *)data, length, 0, sensitiveLength); // clear the sensitive data, memset_s is never optimized away
             dataCopy = malloc(sensitiveLength);
             memcpy(dataCopy, data, sensitiveLength);
             memset_s((void *)data, length, 0, sensitiveLength); // clear the sensitive data, memset_s is never optimized away
index 352e07d8b1e083cf0901b7cf0bd1feee63a874b9..811ccb1f194c392d3990c68fa0e0e0ce047f75af 100644 (file)
@@ -57,7 +57,7 @@ ServerChild::ServerChild()
 //
 ServerChild::~ServerChild()
 {
 //
 ServerChild::~ServerChild()
 {
-       mServicePort.destroy();
+       mServicePort.deallocate();
        
        if (state() == alive) {
                this->kill(SIGTERM);            // shoot it once
        
        if (state() == alive) {
                this->kill(SIGTERM);            // shoot it once
@@ -119,7 +119,8 @@ void ServerChild::checkIn(Port servicePort, pid_t pid)
                {
                        StLock<Mutex> _(mCheckinLock);
                        child->mServicePort = servicePort;
                {
                        StLock<Mutex> _(mCheckinLock);
                        child->mServicePort = servicePort;
-                       servicePort.modRefs(MACH_PORT_RIGHT_SEND, +1);  // retain send right
+            // The macro END_IPCS deallocates this
+            servicePort.modRefs(MACH_PORT_RIGHT_SEND, +1);    // retain send right
                        secinfo("serverchild", "%p (pid %d) checking in; resuming parent thread",
                                child, pid);
                }
                        secinfo("serverchild", "%p (pid %d) checking in; resuming parent thread",
                                child, pid);
                }
index 0b80042f02bf0ab0222d0a46ace5af702d5d1b04..8c9ac64f9ca973e58a2551fad83cd46c9e9a9208 100644 (file)
@@ -45,15 +45,19 @@ ClientIdentification::ClientIdentification()
 // Initialize the ClientIdentification.
 // This creates a process-level code object for the client.
 //
 // Initialize the ClientIdentification.
 // This creates a process-level code object for the client.
 //
-void ClientIdentification::setup(pid_t pid)
+void ClientIdentification::setup(Security::CommonCriteria::AuditToken const &audit)
 {
 {
-       StLock<Mutex> _(mLock);
-       StLock<Mutex> __(mValidityCheckLock);
-    OSStatus rc = SecCodeCreateWithPID(pid, kSecCSDefaultFlags, &mClientProcess.aref());
-       if (rc)
-               secinfo("clientid", "could not get code for process %d: OSStatus=%d",
-                       pid, int32_t(rc));
-       mGuests.erase(mGuests.begin(), mGuests.end());
+    StLock<Mutex> _(mLock);
+    StLock<Mutex> __(mValidityCheckLock);
+    
+    audit_token_t const token = audit.auditToken();
+    OSStatus rc = SecCodeCreateWithAuditToken(&token, kSecCSDefaultFlags, &mClientProcess.aref());
+    
+    if (rc) {
+        secerror("could not get code for process %d: OSStatus=%d",
+                audit.pid(), int32_t(rc));
+    }
+    mGuests.erase(mGuests.begin(), mGuests.end());
 }
 
 
 }
 
 
index 70c9ea22b901f43bfe8a314ece4c7e7c2fbf0aae..a64fa3eb46f50479c95b3c92299a11e4e2a67425 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "codesigdb.h"
 #include <Security/SecCode.h>
 
 #include "codesigdb.h"
 #include <Security/SecCode.h>
+#include <security_utilities/ccaudit.h>
 #include <security_utilities/cfutilities.h>
 #include <string>
 
 #include <security_utilities/cfutilities.h>
 #include <string>
 
@@ -60,7 +61,7 @@ protected:
        SecCodeRef processCode() const;
        SecCodeRef currentGuest() const;
 
        SecCodeRef processCode() const;
        SecCodeRef currentGuest() const;
 
-       void setup(pid_t pid);
+       void setup(Security::CommonCriteria::AuditToken const &audit);
 
 public:
        IFDUMP(void dump());
 
 public:
        IFDUMP(void dump());
index fb0540310c6007be32167c3074777467675245e5..5ca68c608bc9ffe40758ce519dddb3a0f4baaf38 100644 (file)
@@ -64,13 +64,12 @@ void CodeSigningHost::reset()
        case noHosting:
                break;  // nothing to do
        case dynamicHosting:
        case noHosting:
                break;  // nothing to do
        case dynamicHosting:
-               mHostingPort.destroy();
-               mHostingPort = MACH_PORT_NULL;
+               mHostingPort.deallocate();
         secnotice("SecServer", "%d host unregister", mHostingPort.port());
                break;
        case proxyHosting:
                Server::active().remove(*this); // unhook service handler
         secnotice("SecServer", "%d host unregister", mHostingPort.port());
                break;
        case proxyHosting:
                Server::active().remove(*this); // unhook service handler
-               mHostingPort.destroy(); // destroy receive right
+               mHostingPort.modRefs(MACH_PORT_RIGHT_RECEIVE, -1);
                mHostingState = noHosting;
                mHostingPort = MACH_PORT_NULL;
                mGuests.erase(mGuests.begin(), mGuests.end());
                mHostingState = noHosting;
                mHostingPort = MACH_PORT_NULL;
                mGuests.erase(mGuests.begin(), mGuests.end());
index 99d014ee98738fb75ee4e3f49adbf8dbb7312518..fcf017da108ab3065afff3a55ebf35fe731fcaae 100644 (file)
@@ -693,7 +693,12 @@ void KeychainDatabase::changePassphrase(const AccessCredentials *cred)
 {
        // get and hold the common lock (don't let other threads break in here)
        StLock<Mutex> _(common());
 {
        // get and hold the common lock (don't let other threads break in here)
        StLock<Mutex> _(common());
-       
+
+    if (!checkCredentials(cred)) {
+        secinfo("KCdb", "Cannot change passphrase for (%s): existing passphrase does not match", common().dbName());
+        MacOSError::throwMe(errSecAuthFailed);
+    }
+
        // establish OLD secret - i.e. unlock the database
        //@@@ do we want to leave the final lock state alone?
     if (common().isLoginKeychain()) mSaveSecret = true;
        // establish OLD secret - i.e. unlock the database
        //@@@ do we want to leave the final lock state alone?
     if (common().isLoginKeychain()) mSaveSecret = true;
index 1206b157ecd0a1be07d82641ce5784eeaf2f4d43..b31937988f282dc11257cdfc598ae1e282acd221 100644 (file)
 // Construct a Process object.
 //
 Process::Process(TaskPort taskPort,    const ClientSetupInfo *info, const CommonCriteria::AuditToken &audit)
 // Construct a Process object.
 //
 Process::Process(TaskPort taskPort,    const ClientSetupInfo *info, const CommonCriteria::AuditToken &audit)
- :  mTaskPort(taskPort), mByteFlipped(false), mPid(audit.pid()), mUid(audit.euid()), mGid(audit.egid())
+ :  mTaskPort(taskPort), mByteFlipped(false), mPid(audit.pid()), mUid(audit.euid()), mGid(audit.egid()), mAudit(audit)
 {
        StLock<Mutex> _(*this);
        
        // set parent session
        parent(Session::find(audit.sessionId(), true));
 {
        StLock<Mutex> _(*this);
        
        // set parent session
        parent(Session::find(audit.sessionId(), true));
-
-    // let's take a look at our wannabe client...
+       
+       // let's take a look at our wannabe client...
+       
+       // Not enough to make sure we will get the right process, as
+       // pids get recycled. But we will later create the actual SecCode using
+       // the audit token, which is unique to the one instance of the process,
+       // so this just catches a pid mismatch early.
        if (mTaskPort.pid() != mPid) {
                secnotice("SecServer", "Task/pid setup mismatch pid=%d task=%d(%d)",
        if (mTaskPort.pid() != mPid) {
                secnotice("SecServer", "Task/pid setup mismatch pid=%d task=%d(%d)",
-                       mPid, mTaskPort.port(), mTaskPort.pid());
+                                 mPid, mTaskPort.port(), mTaskPort.pid());
                CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED);     // you lied!
        }
                CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED);     // you lied!
        }
-
+       
        setup(info);
        setup(info);
-       ClientIdentification::setup(this->pid());
-
+       ClientIdentification::setup(this->audit_token());
+       
+       if(!processCode()) {
+               // This can happen if the process died in the meantime.
+               secnotice("SecServer", "no process created in setup, old pid=%d old task=%d(%d)",
+                                 mPid, mTaskPort.port(), mTaskPort.pid());
+               CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED);
+       }
+       
     // NB: ServerChild::find() should only be used to determine
     // *existence*.  Don't use the returned Child object for anything else, 
     // as it is not protected against its underlying process's destruction.  
     // NB: ServerChild::find() should only be used to determine
     // *existence*.  Don't use the returned Child object for anything else, 
     // as it is not protected against its underlying process's destruction.  
@@ -86,7 +98,7 @@ void Process::reset(TaskPort taskPort, const ClientSetupInfo *info, const Common
        setup(info);
        CFCopyRef<SecCodeRef> oldCode = processCode();
 
        setup(info);
        CFCopyRef<SecCodeRef> oldCode = processCode();
 
-       ClientIdentification::setup(this->pid());       // re-constructs processCode()
+       ClientIdentification::setup(this->audit_token());       // re-constructs processCode()
        if (CFEqual(oldCode, processCode())) {
         secnotice("SecServer", "%p Client reset amnesia", this);
        } else {
        if (CFEqual(oldCode, processCode())) {
         secnotice("SecServer", "%p Client reset amnesia", this);
        } else {
@@ -127,8 +139,9 @@ Process::~Process()
     secinfo("SecServer", "%p client release: %d", this, this->pid());
 
     // release our name for the process's task port
     secinfo("SecServer", "%p client release: %d", this, this->pid());
 
     // release our name for the process's task port
-       if (mTaskPort)
-        mTaskPort.destroy();
+    if (mTaskPort) {
+        mTaskPort.deallocate();
+    }
 }
 
 void Process::kill()
 }
 
 void Process::kill()
index ce24dc9f6ffbef4943b0cd8c51276374a2d1e061..00be3cbde8ce3162b800125bf59b5ff159e9a8c8 100644 (file)
@@ -79,6 +79,7 @@ public:
     uid_t uid() const                  { return mUid; }
     gid_t gid() const                  { return mGid; }
     pid_t pid() const                  { return mPid; }
     uid_t uid() const                  { return mUid; }
     gid_t gid() const                  { return mGid; }
     pid_t pid() const                  { return mPid; }
+    Security::CommonCriteria::AuditToken const &audit_token() const { return mAudit; }
     TaskPort taskPort() const  { return mTaskPort; }
        bool byteFlipped() const        { return mByteFlipped; }
        
     TaskPort taskPort() const  { return mTaskPort; }
        bool byteFlipped() const        { return mByteFlipped; }
        
@@ -110,6 +111,7 @@ private:
     pid_t mPid;                                                        // process id
     uid_t mUid;                                                        // UNIX uid credential
     gid_t mGid;                                                        // primary UNIX gid credential
     pid_t mPid;                                                        // process id
     uid_t mUid;                                                        // UNIX uid credential
     gid_t mGid;                                                        // primary UNIX gid credential
+    Security::CommonCriteria::AuditToken const mAudit; // audit token
 
        // canonical local (transient) key store
        RefPointer<LocalDatabase> mLocalStore;
 
        // canonical local (transient) key store
        RefPointer<LocalDatabase> mLocalStore;
index 7a47c485af654b8102eff2a4abc3e98ce9c6e632..25e5af1eddce7be0fe8d645802e02dd9150ff815 100644 (file)
@@ -320,6 +320,9 @@ const CFTypeRef kAKSKeyOpUnwrap = (CFTypeRef)CFSTR("kAKSKeyOpUnwrap");
 const CFTypeRef kAKSKeyOpComputeKey = (CFTypeRef)CFSTR("kAKSKeyOpComputeKey");
 const CFTypeRef kAKSKeyOpAttest = (CFTypeRef)CFSTR("kAKSKeyOpAttest");
 const CFTypeRef kAKSKeyOpTranscrypt = (CFTypeRef)CFSTR("kAKSKeyOpTranscrypt");
 const CFTypeRef kAKSKeyOpComputeKey = (CFTypeRef)CFSTR("kAKSKeyOpComputeKey");
 const CFTypeRef kAKSKeyOpAttest = (CFTypeRef)CFSTR("kAKSKeyOpAttest");
 const CFTypeRef kAKSKeyOpTranscrypt = (CFTypeRef)CFSTR("kAKSKeyOpTranscrypt");
+const CFTypeRef kAKSKeyOpECIESEncrypt = (CFTypeRef)CFSTR("kAKSKeyOpECIESEncrypt");
+const CFTypeRef kAKSKeyOpECIESDecrypt = (CFTypeRef)CFSTR("kAKSKeyOpECIESDecrypt");
+const CFTypeRef kAKSKeyOpECIESTranscode = (CFTypeRef)CFSTR("kAKSKeyOpECIESTranscode");
 
 
 TKTokenRef TKTokenCreate(CFDictionaryRef attributes, CFErrorRef *error)
 
 
 TKTokenRef TKTokenCreate(CFDictionaryRef attributes, CFErrorRef *error)
@@ -332,11 +335,6 @@ CFTypeRef TKTokenCopyObjectData(TKTokenRef token, CFDataRef objectID, CFErrorRef
     return NULL;
 }
 
     return NULL;
 }
 
-CFDataRef TKTokenCopyObjectCreationAccessControl(TKTokenRef token, CFDictionaryRef objectAttributes, CFErrorRef *error)
-{
-    return NULL;
-}
-
 CFDataRef TKTokenCreateOrUpdateObject(TKTokenRef token, CFDataRef objectID, CFMutableDictionaryRef attributes, CFErrorRef *error)
 {
     return NULL;
 CFDataRef TKTokenCreateOrUpdateObject(TKTokenRef token, CFDataRef objectID, CFMutableDictionaryRef attributes, CFErrorRef *error)
 {
     return NULL;