<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>
<true/>
<key>com.apple.keystore.console</key>
<true/>
+ <key>com.apple.security.cs.disable-library-validation</key>
+ <true/>
</dict>
</plist>
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);
#include <AssertMacros.h>
#include <assert.h>
+AUTHD_DEFINE_LOG
+
xpc_object_t
SerializeItemSet(const AuthorizationItemSet * itemSet)
{
// <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);
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
CFRelease(gSessionMap);
CFRelease(gAuthTokenMap);
- IOPMConnectionSetDispatchQueue(gIOPMconn, NULL);
- IOPMConnectionRelease(gIOPMconn);
-
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()
{
- return gInDarkWake;
+ return IOPMIsADarkWake(IOPMConnectionGetSystemCapabilities());
}
authdb_t server_get_database()
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();
--- /dev/null
+#!/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
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
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;
- 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) {
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);
//
bool SecCodeSigner::valid() const
{
- if (mOpFlags & kSecCSRemoveSignature)
+ if (mOpFlags & (kSecCSRemoveSignature | kSecCSEditSignature)) {
return true;
+ }
return mSigner;
}
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);
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)
MacOSError::throwMe(errSecCSInvalidObjectRef);
}
- state.mDryRun = getBool(kSecCodeSignerDryRun);
-
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
}
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);
}
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
+
};
text.erase(_saveIndex);
{ // ( ... )*
for (;;) {
- switch ( LA(1)) {
- case 0x5c /* '\\' */ :
- {
+ if ((LA(1) == 0x5c /* '\\' */ )) {
{
_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);
}
}
- break;
}
- default:
- {
+ else {
goto _loop66;
}
- }
+
}
_loop66:;
} // ( ... )*
}
-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
-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 :
-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 :
-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 :
-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 :
-const antlr::BitSet RequirementLexer::_tokenSet_5(_tokenSet_5_data_,8);
+const antlr::BitSet RequirementLexer::_tokenSet_5(_tokenSet_5_data_,16);
ANTLR_END_NAMESPACE
//
-// 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)
{
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
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 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");
| kSecCSRequirementInformation
| kSecCSDynamicInformation
| kSecCSContentInformation
- | kSecCSSkipResourceDirectory);
+ | kSecCSSkipResourceDirectory
+ | kSecCSCalculateCMSDigest);
SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
CFRef<CFDictionaryRef> info = code->signingInformation(flags);
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 */
/*
* 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 kSecCodeInfoCMSDigestHashType; /* Internal */
+extern const CFStringRef kSecCodeInfoCMSDigest; /* Internal */
extern const CFStringRef kSecCodeInfoDiskRepVersionPlatform; /* Number */
extern const CFStringRef kSecCodeInfoDiskRepVersionMin; /* Number */
#if TARGET_OS_OSX
/*!
- @function SecCodeCreateWithPID
+ @function SecCodeCreateWithAuditToken
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.
*/
+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
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");
BEGIN_CSAPI
checkFlags(flags,
- kSecCSRemoveSignature
+ kSecCSEditSignature
+ | kSecCSRemoveSignature
| kSecCSSignPreserveSignature
| kSecCSSignNestedCode
| kSecCSSignOpaque
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
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
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
};
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.
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());
}
}
+ 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
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
CodeDirectory::HashAlgorithms hashAlgorithms() const { return mHashAlgorithms; }
CFDataRef cdHash();
CFArrayRef cdHashes();
+ CFDictionaryRef cdHashesFull();
CFDataRef signature();
CFAbsoluteTime signingTime();
CFAbsoluteTime signingTimestamp();
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);
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)
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
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;
}
}
+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).
// 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);
+ RawComponentMap createRawComponents();
CFDataRef identification();
+ DiskRep *mainExecRep() const { return mExecRep.get(); };
std::string mainExecutablePath();
CFURLRef copyCanonicalPath();
std::string resourcesRootPath();
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;
}
+bool CodeDirectory::Builder::opened()
+{
+ return bool(mExec);
+}
+
//
// Set the source for one special slot
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; }
MacOSError::throwMe(errSecCSInvalidAttributeValues);
try {
- diskRep = new PidDiskRep(pid, infoPlist);
+ diskRep = new PidDiskRep(pid, audit, infoPlist);
} catch (...) { }
}
//
// 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.
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.
}
}
+//
+// 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,
// 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());
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)",
- mainExecutablePath().c_str(), macho->architecture().name());
+ mainExecutablePath().c_str(), macho->architecture().name());
MacOSError::throwMe(errSecCSSignatureInvalid);
}
}
}
- if (mSigningData)
- return mSigningData->component(slot);
-
- // not found
- return NULL;
+ return mSigningData;
}
// 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);
+ RawComponentMap createRawComponents();
CFDataRef identification();
Universal *mainExecutableImage();
void prepareForSigning(SigningContext &context);
private:
static bool needsExecSeg(const MachO& macho);
+ EmbeddedSignatureBlob *signingData();
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
};
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_object_t reply = xpc_connection_send_message_with_reply_sync(conn, request);
if (reply && xpc_get_type(reply) == XPC_TYPE_DICTIONARY) {
const void *data;
}
-PidDiskRep::PidDiskRep(pid_t pid, CFDataRef infoPlist)
+PidDiskRep::PidDiskRep(pid_t pid, audit_token_t *audit, CFDataRef infoPlist)
: mDataFetched(false)
{
BlobCore header;
- CODESIGN_DISKREP_CREATE_KERNEL(this);
-
+
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)
- MacOSError::throwMe(errSecCSNoSuchCode);
+ MacOSError::throwMe(errSecCSNoSuchCode);
if (errno != ERANGE)
UnixError::throwMe(errno);
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))
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);
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);
}
-
+
return (flags & CS_PLATFORM_BINARY) == CS_PLATFORM_BINARY;
}
#ifndef _H_PIDDISKREP
#define _H_PIDDISKREP
+#include <memory>
+
#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:
- PidDiskRep(pid_t pid, CFDataRef infoPlist);
+ PidDiskRep(pid_t pid, audit_token_t *audit, CFDataRef infoPlist);
~PidDiskRep();
CFDataRef component(CodeDirectory::SpecialSlot slot);
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;
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;
}
+
+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)
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 {
//
// signer - Signing operation supervisor and controller
//
+#include "bundlediskrep.h"
#include "der_plist.h"
#include "signer.h"
#include "resources.h"
}
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
}
}
+//// 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
void sign(SecCSFlags flags);
void remove(SecCSFlags flags);
+ void edit(SecCSFlags flags);
SecCodeSigner &state;
SecStaticCode * const code;
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> >
// 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,
SecCSFlags signingFlags() const;
private:
+ static EditableDiskRep *editMainExecutableRep(DiskRep *rep);
+
void addPreEncryptHashes(PreEncryptHashMap &map, SecStaticCode const *code);
void addRuntimeVersions(RuntimeVersionMap &map, SecStaticCode const *code);
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;
};
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());
+ }
});
}
}
//
// 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.
//
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
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)
return false; // No MAC, no integrity.
}
- throw cssme;
+ throw;
}
secnotice("integrity", "***** INVALID ITEM");
}
} catch(CssmError cssme) {
secnotice("integrity", "error while checking integrity, denying access: %s", cssme.what());
- throw cssme;
+ throw;
}
SSDbUniqueRecordImpl* impl = dynamic_cast<SSDbUniqueRecordImpl *>(&(*dbUniqueRecord()));
} catch(CssmError cssme) {
mKey.release();
secnotice("integrity", "error while checking integrity, denying access: %s", cssme.what());
- throw cssme;
+ throw;
}
}
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);
+
if (oldPassword)
{
const CssmData &oldPass = *new(allocator) CssmData(const_cast<void *>(oldPassword), oldPasswordLength);
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++)
{
{ CSSM_LIST_TYPE_UNKNOWN, &subject1, &subject2 },
false, // Delegate
// rights for this entry
- { (uint32)numAcls, rights },
+ { (uint32)numAcls, rights.data() },
// rest is defaulted
}
}
// 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;
// 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)
{
- CFTypeRef key = keysPtr[i];
+ CFTypeRef key = keys[i];
int j;
for (j = 0; j < infoNumItems; ++j)
if (j >= infoNumItems)
{
// if we got here, we aren't interested in this item.
- valuesPtr[i] = NULL;
+ values[i] = NULL;
}
}
// 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;
}
}
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;
--- /dev/null
+#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;
+}
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)
}
// 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);
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
/* 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);
- 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 */
/* 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,
/***** 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");
/*
* 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,
/*
* 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,
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()
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); }
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);
};
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;
}
extern const CFStringRef kCKKSViewHealth;
extern const CFStringRef kCKKSViewApplePay;
extern const CFStringRef kCKKSViewHome;
+extern const CFStringRef kCKKSViewLimitedPeersAllowed;
/*!
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);
+ }
}
void SOSDigestVectorAppend(struct SOSDigestVector *dv, const uint8_t *digest)
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;
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)) {
CFRelease(keyattributes);
CFRelease(exportedkey);
- bzero(export_keybytes, 0);
+ cc_clear(export_size, export_keybytes);
return retval;
}
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, , )
/* 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,
/***** 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");
/*
* 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,
/*
* 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,
+++ /dev/null
-/*
- * 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;
-}
--- /dev/null
+/*
+ * 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;
+}
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);
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;
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));
});
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;
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);
+}
OSStatus SecCTKKeyGeneratePair(CFDictionaryRef parameters,
SecKeyRef *rsaPublicKey, SecKeyRef *rsaPrivateKey);
SecKeyRef SecKeyCreateCTKKey(CFAllocatorRef allocator, CFDictionaryRef refAttributes, CFErrorRef *error);
+void SecCTKKeySetTestMode(CFStringRef tokenID, CFTypeRef enable);
__END_DECLS
_SecKeyCreate
_SecKeyCreateAttestation
_SecKeyCreateDecryptedData
+_SecKeyCreateDecryptedDataWithParameters
_SecKeyCreateDuplicate
_SecKeyCreateECPrivateKey
_SecKeyCreateECPublicKey
_SecKeyCreateEncryptedData
+_SecKeyCreateEncryptedDataWithParameters
_SecKeyCreateFromAttributeDictionary
#if TARGET_OS_OSX
#if TARGET_OS_OSX
_kSecKeyAttributeName
#endif /* TARGET_OS_OSX */
+_kSecKeyEncryptionParameterRecryptParameters
+_kSecKeyEncryptionParameterRecryptCertificate
+_kSecKeyEncryptionParameterSymmetricAAD
+_kSecKeyEncryptionParameterSymmetricKeySizeInBits
_kSecKeyKeyExchangeParameterRequestedSize
_kSecKeyKeyExchangeParameterSharedInfo
_kSecKeyParameterSETokenAttestationNonce
+_kSecKeyApplePayEnabled
_kSecPrivateKeyAttrs
_kSecPublicKeyAttrs
#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")
if (ctx == nil) {
ctx = LACreateNewContextWithACMContext(NULL, error);
if (!ctx) {
+ os_unfair_lock_unlock(&lock);
secerror("Failed to create authentication context %@", *error);
return token;
}
// 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);
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");
#include <Security/SecItemPriv.h>
#include <Security/SecItemShim.h>
#include <Security/SecFramework.h>
+#include <Security/SecCertificate.h>
#include <utilities/SecIOFormat.h>
}
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);
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) };
- CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, plainText, NULL, &localError);
+ CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, plaintext, parameters, &localError);
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) };
- CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, cipherText, NULL, error);
+ CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, ciphertext, parameters, error);
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;
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;
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,
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);
- require_quiet(encryptCopyResult(keyExchangeResult, in1, ciphertext, error), out);
+ require_quiet(encryptCopyResult(keyExchangeResult, in1, in2, ciphertext, error), out);
result = CFRetain(ciphertext);
} else {
result = CFRetain(keyExchangeResult);
// 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);
- require_quiet(result = decryptCopyResult(keyExchangeResult, ciphertext, error), out);
+ require_quiet(result = decryptCopyResult(keyExchangeResult, ciphertext, in2, error), out);
} else {
result = CFRetain(keyExchangeResult);
}
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) {
- // 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.
- 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.
- 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);
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,
- 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")));
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);
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,
- 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")));
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);
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),
@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. */
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;
}
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:
@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;
}
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++;
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;
}
}
}
* 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);
- 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);
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;
config.TLSMinimumSupportedProtocol = kTLSProtocol12;
config.TLSMaximumSupportedProtocol = kTLSProtocol13;
- config._requiresPowerPluggedIn = YES;
-
- config.allowsCellularAccess = (!updateOnWiFiOnly) ? YES : NO;
-
return config;
}
<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>
- <string>fmip</string>
+ <string>generic_apple_server</string>
<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>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>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>
#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
#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,
} else {
keyTypes = @[(id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeyTypeSecureEnclaveAttestation];
}
+ BOOL noACL = YES;
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);
}
}
-static void attestationTest(CFStringRef protection) {
+static void attestationTest(CFStringRef protection, BOOL noACL) {
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);
}
}
+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;
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);
- attestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly);
- attestationTest(kSecAttrAccessibleUntilReboot);
+ attestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, NO);
+ attestationTest(kSecAttrAccessibleUntilReboot, YES);
return 0;
}
}
#import <Foundation/Foundation.h>
#import <Security/SecItemPriv.h>
+#import <Security/SecKeyPriv.h>
#import <corecrypto/ccrng.h>
#import <corecrypto/ccsha1.h>
"%@ 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));
+ 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);
+ 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];
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;
// 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));
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");
+ 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,
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;
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;
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");
int si_82_sectrust_ct(int argc, char *const *argv)
{
- plan_tests(432);
+ plan_tests(433);
tests();
test_sct_serialization();
} 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;
/*
}
sqlite3_reset(stmt);
}
+ sqlite3_finalize(stmt);
if (vacuumMode != SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL) {
(void)sqlite3_exec(handle, "PRAGMA auto_vacuum = incremental", NULL, NULL, NULL);
{
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);
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;
}
- 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;
}
}
// 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;
}
- 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);
+ free(real_key);
return true;
}
_SecRandomCopyBytes
_SecSHA1DigestCreate
_SecTaskCopySigningIdentifier
+_SecTaskCopyTeamIdentifier
_SecTaskCopyValueForEntitlement
_SecTaskCopyValuesForEntitlements
_SecTaskCreateFromSelf
_SecCodeCopyStaticCode
_SecCodeCopyHost
_SecCodeCopyGuestWithAttributes
+_SecCodeCreateWithAuditToken
_SecCodeCreateWithPID
_SecCodeCheckValidity
_SecCodeCheckValidityWithErrors
_kSecCodeSignerDetached
_kSecCodeSignerDigestAlgorithm
_kSecCodeSignerDryRun
+_kSecCodeSignerEditCMS
+_kSecCodeSignerEditCpuSubtype
+_kSecCodeSignerEditCpuType
_kSecCodeSignerEntitlements
_kSecCodeSignerFlags
_kSecCodeSignerIdentifier
_kSecCodeSignerPlatformIdentifier
_kSecCodeSignerRuntimeVersion
_kSecCodeSignerPreserveAFSC
+_kSecCodeSignerOmitAdhocFlag
_kSecCodeSignerTimestampServer
_kSecCodeSignerTimestampAuthentication
_kSecCodeSignerTimestampOmitCertificates
+_kSecCodeInfoCdHashes
+_kSecCodeInfoCdHashesFull
_kSecCodeInfoCertificates
_kSecCodeInfoChangedFiles
_kSecCodeInfoCMS
+_kSecCodeInfoCMSDigest
+_kSecCodeInfoCMSDigestHashType
_kSecCodeInfoTime
_kSecCodeInfoTimestamp
_kSecCodeInfoDesignatedRequirement
_kSecCodeInfoTeamIdentifier
_kSecCodeInfoTrust
_kSecCodeInfoUnique
-_kSecCodeInfoCdHashes
_kSecCodeInfoRuntimeVersion
_kSecCodeInfoCodeDirectory
_kSecCodeInfoCodeOffset
_kSecCodeAttributeBundleVersion
_kSecCodeAttributeSubarchitecture
_kSecCodeInfoCMS
+_kSecCodeInfoCMSDigest
+_kSecCodeInfoCMSDigestHashType
_kSecCodeInfoCdHashes
+_kSecCodeInfoCdHashesFull
_kSecCodeInfoChangedFiles
_kSecCodeInfoCodeDirectory
_kSecCodeInfoCodeOffset
/* 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, ); }; };
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 */; };
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, ); }; };
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 */; };
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 */; };
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 */; };
+ 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 */; };
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 */; };
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 */; };
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 */; };
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 */; };
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 */; };
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 */; };
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; };
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>"; };
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>"; };
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>"; };
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>"; };
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>"; };
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>"; };
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 */
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 */,
);
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 */,
4432AF8D1A01472C000958DC /* libaks_acl.a in Frameworks */,
438166ED1B4ECF9400C54D58 /* CoreFoundation.framework in Frameworks */,
4CAF67AC0F3A70220064A534 /* IOKit.framework in Frameworks */,
+ 0940F6F82151316500C06F18 /* libACM.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
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 */,
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 */,
);
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 */,
);
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 */,
DC1789231D7799A600B50D50 /* libz.dylib in Frameworks */,
DC1789251D7799CD00B50D50 /* CoreFoundation.framework in Frameworks */,
DC1789271D7799D400B50D50 /* IOKit.framework in Frameworks */,
+ 0940F6F92151316600C06F18 /* libACM.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
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 */,
);
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 */,
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 */,
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 */,
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 */,
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 */,
);
children = (
DCC78E281D8085FC00865A7C /* AppleBaselineEscrowCertificates.h */,
D41149A01E7C935D00C078C7 /* AppleiPhoneDeviceCACertificates.h */,
- DCC78E301D8085FC00865A7C /* SecAccessControl.c */,
+ DCC78E301D8085FC00865A7C /* SecAccessControl.m */,
443381D918A3D81400215606 /* SecAccessControl.h */,
443381DA18A3D81400215606 /* SecAccessControlPriv.h */,
DCC78E351D8085FC00865A7C /* SecBase64.c */,
isa = PBXGroup;
children = (
DC610A671D78FA76002223DE /* teamid.sh */,
+ F9B458272183E01100F6BCEB /* SignatureEditing.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 */,
+ 6CA837612210C5E7002770F1 /* kc-45-change-password.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 */,
- 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 */,
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 */,
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 */,
<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>
#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>
typedef struct {
int i;
- const char *name;
+ NSString *name;
} ctk_print_context;
OSStatus
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 OSStatus
-ctk_dump_items(CFArrayRef items, CFTypeRef secClass, const char *name)
+ctk_dump_items(CFArrayRef items, id secClass, NSString *name)
{
OSStatus stat = errSecSuccess;
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
-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;
- 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 = @{
- (id)kSecClass : (__bridge id)secClass,
+ (id)kSecClass : secClass,
(id)kSecMatchLimit : (id)kSecMatchLimitAll,
(id)kSecAttrAccessGroup : (id)kSecAttrAccessGroupToken,
(id)kSecReturnAttributes : @YES,
if(tid) {
NSMutableDictionary *updatedQuery = [NSMutableDictionary dictionaryWithDictionary:query];
- updatedQuery[(id)kSecAttrTokenID] = [NSString stringWithUTF8String:tid];
+ updatedQuery[(id)kSecAttrTokenID] = tid;
query = updatedQuery;
}
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;
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;
}
- stat = ctk_dump_items((__bridge CFArrayRef)result, secClass, name);
+ if (!exportPath) {
+ stat = ctk_dump_items((__bridge CFArrayRef)result, secClass, name);
+ }
} else {
stat = errSecInternalComponent;
}
int
ctk_export(int argc, char * const *argv)
{
- OSStatus stat = errSecSuccess;
+ __block OSStatus stat = errSecSuccess;
ItemSpec itemSpec = IS_All;
- const char *tid = NULL;
+ NSString *tid;
+ NSString *exportPath;
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)) {
else {
return SHOW_USAGE_MESSAGE;
}
+ optT = YES;
break;
case 'i':
- tid = optarg;
+ tid = [NSString stringWithUTF8String:optarg];
+ break;
+ case 'e':
+ exportPath = [NSString stringWithUTF8String:optarg];
+ itemSpec = IS_Certs;
+ optE = YES;
break;
case '?':
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) {
- break;
+ *stop = YES;
}
}
- }
+ }];
return stat;
}
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)
{
.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
.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
-Export items from a smartcard. If
+Export/display items from a smartcard. If
.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
-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
-Export items of the specified type (Default:
+Display items of the specified type (Default:
.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
"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"
- " 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,
#define kSystemKeychainDir "/Library/Keychains/"
#define kSystemUnlockFile "/var/db/SystemKey"
+#define kSystemKeychainPath kSystemKeychainDir kSystemKeychainName
+
/*
* CSSM ACL tags used to store partition/integrity data in ACLs
*/
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];
@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 kSecAttrViewHintHealth;
extern const CFStringRef kSecAttrViewHintApplePay;
extern const CFStringRef kSecAttrViewHintHome;
+extern const CFStringRef kSecAttrViewHintLimitedPeersAllowed;
extern const CFStringRef kSecUseSystemKeychain
@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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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.
@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
/*!
#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.
{
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
@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
@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
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
-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.
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
@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
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.
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 */
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";
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];
// 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"];
}
}];
@property FakeCKZone* homeZone;
@property (readonly) ZoneKeys* homeZoneKeys;
+@property CKRecordZoneID* limitedZoneID;
+@property CKKSKeychainView* limitedView;
+@property FakeCKZone* limitedZone;
+@property (readonly) ZoneKeys* limitedZoneKeys;
+
@end
@implementation CloudKitKeychainSyncingSOSIntegrationTests
[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.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 {
[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"];
- pcsChanged.inverted = YES;
+
// 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];
}
+-(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.
[self putFakeDeviceStatusInCloudKit: self.healthZoneID];
[self putFakeDeviceStatusInCloudKit: self.applepayZoneID];
[self putFakeDeviceStatusInCloudKit: self.homeZoneID];
+ [self putFakeDeviceStatusInCloudKit: self.limitedZoneID];
}
-(void)putFakeKeyHierachiesInCloudKit{
[self putFakeKeyHierarchyInCloudKit: self.healthZoneID];
[self putFakeKeyHierarchyInCloudKit: self.applepayZoneID];
[self putFakeKeyHierarchyInCloudKit: self.homeZoneID];
+ [self putFakeKeyHierarchyInCloudKit: self.limitedZoneID];
}
-(void)saveTLKsToKeychain{
[self saveTLKMaterialToKeychain:self.engramZoneID];
[self saveTLKMaterialToKeychain:self.healthZoneID];
[self saveTLKMaterialToKeychain:self.applepayZoneID];
[self saveTLKMaterialToKeychain:self.homeZoneID];
+ [self saveTLKMaterialToKeychain:self.limitedZoneID];
}
-(void)deleteTLKMaterialsFromKeychain{
[self deleteTLKMaterialFromKeychain: self.engramZoneID];
[self deleteTLKMaterialFromKeychain: self.healthZoneID];
[self deleteTLKMaterialFromKeychain: self.applepayZoneID];
[self deleteTLKMaterialFromKeychain: self.homeZoneID];
+ [self deleteTLKMaterialFromKeychain:self.limitedZoneID];
}
-(void)waitForKeyHierarchyReadinesses {
[self.healthView waitForKeyHierarchyReadiness];
[self.applepayView waitForKeyHierarchyReadiness];
[self.homeView waitForKeyHierarchyReadiness];
+ [self.limitedView waitForKeyHierarchyReadiness];
}
-(void)testAcceptExistingAndUsePiggyKeyHierarchy {
(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,
// 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");
PCSPublicKey:publicKey
PCSPublicIdentity:publicIdentity]];
- result = [self pcsAddItem:@"tOTHER-ITEM"
+ result = [self pcsAddItem:@"OTHER-ITEM"
data:[@"asdfasdf" dataUsingEncoding:NSUTF8StringEncoding]
serviceIdentifier:(NSNumber*)servIdentifier
publicKey:(NSData*)publicKey
// 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");
// 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");
// 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");
- 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");
// 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];
// 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");
// 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];
// 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");
// 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");
// 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");
// 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");
// 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");
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];
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
/* Find digest and contentType for signerinfo */
algiddata = SecCmsSignerInfoGetDigestAlg(signerinfo);
+ if (algiddata == NULL) {
+ return errSecInvalidDigestAlgorithm;
+ }
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);
+ if (digest == NULL) {
+ return errSecDataNotAvailable;
+ }
contentType = SecCmsContentInfoGetContentTypeOID(cinfo);
return rc;
}
-CFStringRef
-SecTaskCopySigningIdentifier(SecTaskRef task, CFErrorRef *error)
+static CFStringRef
+SecTaskCopyIdentifier(SecTaskRef task, int op, CFErrorRef *error)
{
CFStringRef signingId = NULL;
char *data = NULL;
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;
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;
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)
{
task satisfies the requirement.
*/
-OSStatus SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement);
+OSStatus SecTaskValidateForRequirement(SecTaskRef _Nonnull task, CFStringRef _Nonnull requirement);
/*!
@function SecTaskGetCodeSignStatus
*/
uint32_t
-SecTaskGetCodeSignStatus(SecTaskRef task);
+SecTaskGetCodeSignStatus(SecTaskRef _Nonnull task);
#endif /* SEC_OS_OSX */
/*!
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
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) {
}
done:
+ free(buf);
return ur;
}
#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
// 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);
- SegmentOffsetType crc = CalculateCRC(finalMessage, messageSize);
+ SegmentOffsetType crc = CalculateCRC(finalMessage.data(), messageSize);
// write the length
WriteOffset(int_cast<size_t, SegmentOffsetType>(messageSize));
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));
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
//
ServerChild::~ServerChild()
{
- mServicePort.destroy();
+ mServicePort.deallocate();
if (state() == alive) {
this->kill(SIGTERM); // shoot it once
{
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);
}
// 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());
}
#include "codesigdb.h"
#include <Security/SecCode.h>
+#include <security_utilities/ccaudit.h>
#include <security_utilities/cfutilities.h>
#include <string>
SecCodeRef processCode() const;
SecCodeRef currentGuest() const;
- void setup(pid_t pid);
+ void setup(Security::CommonCriteria::AuditToken const &audit);
public:
IFDUMP(void dump());
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
- mHostingPort.destroy(); // destroy receive right
+ mHostingPort.modRefs(MACH_PORT_RIGHT_RECEIVE, -1);
mHostingState = noHosting;
mHostingPort = MACH_PORT_NULL;
mGuests.erase(mGuests.begin(), mGuests.end());
{
// 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;
// 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));
-
- // 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)",
- mPid, mTaskPort.port(), mTaskPort.pid());
+ mPid, mTaskPort.port(), mTaskPort.pid());
CssmError::throwMe(CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED); // you lied!
}
-
+
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.
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 {
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()
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; }
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;
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)
return NULL;
}
-CFDataRef TKTokenCopyObjectCreationAccessControl(TKTokenRef token, CFDictionaryRef objectAttributes, CFErrorRef *error)
-{
- return NULL;
-}
-
CFDataRef TKTokenCreateOrUpdateObject(TKTokenRef token, CFDataRef objectID, CFMutableDictionaryRef attributes, CFErrorRef *error)
{
return NULL;